@gentleduck/upload 0.2.2 → 0.2.5

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.
@@ -0,0 +1 @@
1
+ function e(e){return new Promise(t=>setTimeout(t,e))}export{e as t};
@@ -0,0 +1,3 @@
1
+ import { a as AnyCursor, c as WithSignal, d as IntentBase, f as IntentMap, i as UploadTransport, l as UploadResultBase, n as StrategyRegistry, o as CursorMap, p as StrategyKey, r as UploadStrategy, s as UploadApi, t as StrategyCtx, u as AnyIntent } from "../strategy.types-gg9ZStRe.js";
2
+ import { $ as RejectReason, A as serializeSnapshot, B as UploadItem, C as StoreOptions, D as createTypedEmitter, E as UploadEventMap, F as PersistedUploadItem, G as UploadCommand, H as UploadProgress, I as PersistenceAdapter, J as resolveUploadConfig, K as UploadConfig, L as UploadState, M as LocalStorageAdapter, N as IndexedDBAdapter, O as TypedEmitter, P as PersistedSnapshot, Q as BuiltInUploadError, R as createReducer, S as PersistenceOptions, T as UploadStore, U as UploadCompletionKind, V as UploadPhase, W as UploadOutcome, X as createXHRTransport, Y as RetryDecision, Z as FileFingerprint, _ as UploadHooks, a as DEFAULT_MAX_ATTEMPTS, b as DeserializeContext, c as DEFAULT_PROGRESS_THROTTLE_MS, d as sleep, et as UploadError, f as validateFileList, g as createUploadClient, h as UploadClient, i as fingerprintMatches, j as MemoryAdapter, k as deserializeSnapshot, l as DEFAULT_RETRY_DELAY_BASE_MS, m as validateFile, n as isRecord, nt as UploadValidationRules, o as DEFAULT_MAX_CONCURRENT_UPLOADS, p as validateIntent, q as UploadConfigInput, r as computeFingerprint, s as DEFAULT_MAX_ITEMS, t as generateId, tt as UploadErrorBase, u as DEFAULT_RETRY_DELAY_MAX_MS, v as UploadPlugin, w as StoreRuntime, x as InflightUpload, y as createUploadStore, z as InternalEvent } from "../index-BXg9WIce.js";
3
+ export { AnyCursor, AnyIntent, BuiltInUploadError, CursorMap, DEFAULT_MAX_ATTEMPTS, DEFAULT_MAX_CONCURRENT_UPLOADS, DEFAULT_MAX_ITEMS, DEFAULT_PROGRESS_THROTTLE_MS, DEFAULT_RETRY_DELAY_BASE_MS, DEFAULT_RETRY_DELAY_MAX_MS, DeserializeContext, FileFingerprint, IndexedDBAdapter, InflightUpload, IntentBase, IntentMap, InternalEvent, LocalStorageAdapter, MemoryAdapter, PersistedSnapshot, PersistedUploadItem, PersistenceAdapter, PersistenceOptions, RejectReason, RetryDecision, StoreOptions, StoreRuntime, StrategyCtx, StrategyKey, StrategyRegistry, TypedEmitter, UploadApi, UploadClient, UploadCommand, UploadCompletionKind, UploadConfig, UploadConfigInput, UploadError, UploadErrorBase, UploadEventMap, UploadHooks, UploadItem, UploadOutcome, UploadPhase, UploadPlugin, UploadProgress, UploadResultBase, UploadState, UploadStore, UploadStrategy, UploadTransport, UploadValidationRules, WithSignal, computeFingerprint, createReducer, createTypedEmitter, createUploadClient, createUploadStore, createXHRTransport, deserializeSnapshot, fingerprintMatches, generateId, isRecord, resolveUploadConfig, serializeSnapshot, sleep, validateFile, validateFileList, validateIntent };
@@ -0,0 +1 @@
1
+ import{C as e,S as t,_ as n,a as r,b as i,c as a,d as o,f as s,g as c,h as l,i as u,l as d,m as f,n as p,o as m,p as h,r as g,s as _,t as v,u as y,v as b,w as x,x as S,y as C}from"../core-BNxznRif.js";import{t as w}from"../async-DxRWu4le.js";export{C as DEFAULT_MAX_ATTEMPTS,i as DEFAULT_MAX_CONCURRENT_UPLOADS,S as DEFAULT_MAX_ITEMS,t as DEFAULT_PROGRESS_THROTTLE_MS,e as DEFAULT_RETRY_DELAY_BASE_MS,x as DEFAULT_RETRY_DELAY_MAX_MS,d as IndexedDBAdapter,a as LocalStorageAdapter,_ as MemoryAdapter,o as computeFingerprint,g as createReducer,u as createTypedEmitter,v as createUploadClient,p as createUploadStore,y as createXHRTransport,r as deserializeSnapshot,s as fingerprintMatches,n as generateId,l as isRecord,b as resolveUploadConfig,m as serializeSnapshot,w as sleep,c as validateFile,h as validateFileList,f as validateIntent};
@@ -0,0 +1,2 @@
1
+ import{t as e}from"./async-DxRWu4le.js";const t=500,n=1e4,r=100,i=3,a=3,o=100;function s(e){return{maxConcurrentUploads:Math.max(1,e?.maxConcurrentUploads??3),autoStart:e?.autoStart,progressThrottleMs:Math.max(0,e?.progressThrottleMs??100),validation:e?.validation??{},maxAttempts:Math.max(1,e?.maxAttempts??3),retryPolicy:e?.retryPolicy,maxItems:Math.max(1,e?.maxItems??100),completedItemTTL:e?.completedItemTTL}}function c(){return`upload_${Date.now()}_${Math.random().toString(36).slice(2)}`}function l(e,t,n){let r=n.validation?.[t];if(!r)return null;if(e.size===0)return{code:`empty_file`};if(r.maxSizeBytes!==void 0&&e.size>r.maxSizeBytes)return{code:`file_too_large`,maxBytes:r.maxSizeBytes,size:e.size};if(r.minSizeBytes!==void 0&&e.size<r.minSizeBytes)return{code:`empty_file`};if(r.allowedTypes||r.allowedExtensions){let t=r.allowedTypes||[],n=r.allowedExtensions||[],i=e.name.split(`.`).pop()?.toLowerCase(),a=(e.type||``).toLowerCase(),o=t.length===0?!1:t.some(e=>{if(e.endsWith(`/*`)){let t=e.slice(0,-2).toLowerCase();return a.startsWith(`${t}/`)}return a===e.toLowerCase()}),s=i&&n.length>0?n.some(e=>e.toLowerCase()===i):!1,c=t.length>0,l=n.length>0;if(!(c&&l?o||s:(!c||o)&&(!l||s)))return{code:`type_not_allowed`,allowed:[...t,...n],got:e.type||e.name}}return null}function u(e){return!!e&&typeof e==`object`}function d(e,t){if(!u(e))return Error(`Invalid intent: must be an object`);if(typeof e.strategy!=`string`)return Error(`Invalid intent: missing or invalid strategy field`);if(e.strategy!==t)return Error(`Invalid intent: strategy mismatch (expected ${t}, got ${e.strategy})`);if(typeof e.fileId!=`string`||!e.fileId)return Error(`Invalid intent: missing or invalid fileId`);if(t===`post`){if(typeof e.url!=`string`||!e.url)return Error(`Invalid post intent: missing or invalid url`);try{let t=new URL(e.url);if(![`http:`,`https:`].includes(t.protocol))return Error(`Invalid post intent: url must use http or https protocol`)}catch{return Error(`Invalid post intent: url is not a valid URL`)}if(!e.fields||typeof e.fields!=`object`)return Error(`Invalid post intent: missing or invalid fields`)}else if(t===`multipart`){if(typeof e.uploadId!=`string`||!e.uploadId)return Error(`Invalid multipart intent: missing or invalid uploadId`);if(typeof e.partSize!=`number`||e.partSize<=0)return Error(`Invalid multipart intent: missing or invalid partSize`);if(`parts`in e&&e.parts!==void 0&&!Array.isArray(e.parts))return Error(`Invalid multipart intent: parts must be an array if provided`)}return null}function f(e,t,n,r=0){let i=n.validation?.[t],a=[],o=[],s=i?.maxFiles,c=s===void 0?1/0:Math.max(0,s-r);for(let r of e){if(c<=0){let e=s??0;o.push({file:r,reason:{code:`too_many_files`,max:e}});continue}let e=l(r,t,n);if(e){o.push({file:r,reason:e});continue}a.push(r),--c}return{valid:a,rejected:o}}function p(e){return{name:e.name,size:e.size,type:e.type,lastModified:e.lastModified}}function m(e,t){return e.name===t.name&&e.size===t.size&&e.lastModified===t.lastModified}async function h(e){let t=await e.arrayBuffer(),n=await crypto.subtle.digest(`SHA-256`,t);return Array.from(new Uint8Array(n)).map(e=>e.toString(16).padStart(2,`0`)).join(``)}function g(e,t){let n=e.config?.autoStart;return n===void 0?!1:Array.isArray(n)?n.includes(t):typeof n==`function`?n(t):!1}function _(e,t){if(t)return t(e);if(x(e))return{code:`aborted`,message:`Upload aborted`,reason:String(e.reason??`unknown`),retryable:!1};let n=u(e)&&typeof e.message==`string`?e.message:`Unknown error`;if(String(n).toLowerCase().includes(`network`)||String(n).toLowerCase().includes(`fetch`))return{code:`network`,message:String(n),cause:e,retryable:!0};if(u(e)&&(typeof e.status==`number`||typeof e.statusCode==`number`)){let t=typeof e.status==`number`?e.status:e.statusCode,r=t>=500||t===429;return{code:`http`,status:t,message:String(n),cause:e,retryable:r}}return{code:`unknown`,message:String(n),cause:e,retryable:!1}}function v(e){return`intent`in e&&!!e.intent}function y(e){return`file`in e&&!!e.file}function b(e){return`cursor`in e}function ee(e){return u(e)&&e.strategy===`multipart`&&typeof e.fileId==`string`&&typeof e.uploadId==`string`}function x(e){return u(e)&&e.code===`aborted`}function S(e,t){if(e.retryPolicy)return e.retryPolicy(t);if(t.error.code===`auth`||t.error.code===`validation_failed`||t.error.code===`strategy_missing`||t.error.code===`aborted`)return{retryable:!1};let r=e.maxAttempts;return t.attempt<r?{retryable:!0,delayMs:Math.min(n,500*2**(t.attempt-1))}:{retryable:!1}}function C(e,t,n){let r=Array.from(e.state.items.values()).filter(e=>e.purpose===n&&e.phase!==`canceled`).length,{valid:i,rejected:a}=f(t,n,e.opts.config,r);for(let{file:t,reason:n}of a)e.emitter.emit(`file.rejected`,{reason:n,file:t});let o=Date.now(),s=[];for(let t of i){let r=c(),i=(e.opts.fingerprint??p)(t);s.push({localId:r,purpose:n,file:t,fingerprint:i,createdAt:o}),e.enqueueEffect(async()=>{let a;try{a=await h(t);let n={...i,checksum:a};e.applyInternal({type:`fingerprint.updated`,localId:r,fingerprint:n})}catch(e){typeof window<`u`&&process.env.NODE_ENV===`development`&&console.warn(`[UploadEngine] Failed to calculate checksum:`,e)}if(a&&e.opts.api.findByChecksum)try{let t=await e.opts.api.findByChecksum({checksum:a,purpose:n});if(t){let n=e.state.items.get(r);if(n&&n.phase===`validating`){e.applyInternal({type:`dedupe.ok`,localId:r,result:t});return}}}catch(e){typeof window<`u`&&process.env.NODE_ENV===`development`&&console.warn(`[UploadEngine] Failed to check for existing file:`,e)}let o=e.opts.validateFile?.(t,n);if(o){e.applyInternal({type:`validation.failed`,localId:r,reason:o});return}let s=l(t,n,e.opts.config);if(s){e.applyInternal({type:`validation.failed`,localId:r,reason:s});return}e.applyInternal({type:`validation.ok`,localId:r})})}s.length>0&&e.applyInternal({type:`files.added`,items:s})}function w(e,t){let n=e.state.items.get(t),r=e.inflightIntents.get(t);r&&(r.abort({reason:`cancel`}),e.inflightIntents.delete(t));let i=e.inflightCompletes.get(t);i&&(i.abort({reason:`cancel`}),e.inflightCompletes.delete(t));let a=e.inflightUploads.get(t);if(a&&(a.mode=`cancel`,a.controller.abort({reason:`cancel`})),n&&v(n)&&n.intent.strategy===`multipart`&&e.opts.api.multipart?.abort){let t=n.intent;ee(t)&&e.enqueueEffect(async()=>{try{let n=e.opts.api.multipart?.abort;n&&await n({fileId:t.fileId,uploadId:t.uploadId})}catch{}})}}function T(e,t){let n=e.inflightUploads.get(t);if(n){n.mode=`pause`,n.controller.abort({reason:`pause`});return}}function E(e,t){if(t.type===`startAll`){let n=t.purpose;Array.from(e.state.items.values()).filter(e=>e.phase===`ready`&&(!n||e.purpose===n)).forEach(t=>{e.dispatch({type:`start`,localId:t.localId})});return}if(t.type===`pauseAll`){let n=t.purpose;Array.from(e.state.items.values()).filter(e=>e.phase===`uploading`&&(!n||e.purpose===n)).forEach(t=>{e.dispatch({type:`pause`,localId:t.localId})});return}if(t.type===`cancelAll`){let n=t.purpose;Array.from(e.state.items.values()).filter(e=>e.phase!==`completed`&&e.phase!==`canceled`&&(!n||e.purpose===n)).forEach(t=>{e.dispatch({type:`cancel`,localId:t.localId})});return}if(t.type===`addFiles`){C(e,t.files,t.purpose);return}if(t.type===`pause`){T(e,t.localId),e.applyCommand(t);return}if(t.type===`cancel`){w(e,t.localId),e.applyCommand(t);return}if(t.type===`start`){e.applyCommand(t);return}if(t.type===`resume`){e.applyCommand(t);return}e.applyCommand(t)}function D(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function O(e){return e?.reason}function te(e){if(!e)return`unknown`;if(typeof e==`string`)return e===`pause`||e===`cancel`?e:`unknown`;if(u(e)&&`reason`in e){let t=e.reason;if(t===`pause`||t===`cancel`)return t}if(u(e)&&`kind`in e){let t=e.kind;if(t===`pause`||t===`cancel`)return t}return`unknown`}var k=class extends Error{constructor(e){super(`Upload aborted`),D(this,`code`,`aborted`),D(this,`reason`,void 0),this.reason=te(e)}};function A(e){return new k(e)}function ne(e,t){return e.status===0?Error(`CORS error: The upload server does not allow requests from this origin. Please check CORS configuration.`):Error(`${t} (status: ${e.status})`)}function re(e){let t={};return e.getAllResponseHeaders().split(`\r
2
+ `).map(e=>e.trim()).filter(Boolean).forEach(e=>{let n=e.indexOf(`:`);if(n<=0)return;let r=e.slice(0,n).trim().toLowerCase(),i=e.slice(n+1).trim();r&&(t[r]=i)}),t}function ie(e){return/^https?:\/\//i.test(e)}function ae(e){let t=e.getResponseHeader(`ETag`)??e.getResponseHeader(`etag`);if(t)return t.replace(/"/g,``)}function j(e){return new Promise((t,n)=>{if(!e.url||typeof e.url!=`string`){n(Error(`UploadTransport: missing url`));return}if(!ie(e.url)){n(Error(`UploadTransport: expected absolute URL, got: ${String(e.url)}`));return}let r=new XMLHttpRequest,i=!1,a=e=>{i||(i=!0,s(),e())},o=()=>{try{r.abort()}finally{a(()=>n(A(O(e.signal))))}},s=()=>{e.signal&&e.signal.removeEventListener(`abort`,o),r.upload.onprogress=null,r.onload=null,r.onerror=null,r.onabort=null};if(e.signal?.aborted){a(()=>n(A(O(e.signal))));return}if(e.signal&&e.signal.addEventListener(`abort`,o,{once:!0}),e.onProgress&&(r.upload.onprogress=t=>{t.lengthComputable&&e.onProgress?.(t.loaded,t.total)}),r.onload=()=>{let e=r.status;a(e>=200&&e<300?()=>t({headers:re(r),etag:ae(r)}):()=>n(Error(`Upload failed with status ${e}`)))},r.onerror=()=>a(()=>n(ne(r,`Network error during upload`))),r.onabort=()=>a(()=>n(A(e.signal?.aborted?O(e.signal):`unknown`))),r.open(e.method,e.url),e.headers)for(let[t,n]of Object.entries(e.headers))r.setRequestHeader(t,n);r.send(e.body)})}function M(){return{async postForm(e){let t=new FormData;for(let[n,r]of Object.entries(e.fields))t.append(n,r);return t.append(`file`,e.file,e.filename??`file`),{headers:(await j({method:`POST`,url:e.url,body:t,signal:e.signal,onProgress:e.onProgress})).headers}},async put(e){let t=await j({method:`PUT`,url:e.url,body:e.body,signal:e.signal,headers:e.headers,onProgress:e.onProgress});return{headers:t.headers,etag:t.etag}},async patch(e){return{headers:(await j({method:`PATCH`,url:e.url,body:e.body,signal:e.signal,headers:e.headers,onProgress:e.onProgress})).headers}}}}const N=`snapshots`;function P(){return new Promise((e,t)=>{let n=indexedDB.open(`upload-engine`,1);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(N)||e.createObjectStore(N)},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}function F(e){return new Promise((t,n)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>n(e.error)})}function I(e){return new Promise((t,n)=>{e.oncomplete=()=>t(),e.onabort=()=>n(e.error??Error(`IndexedDB transaction aborted`)),e.onerror=()=>n(e.error??Error(`IndexedDB transaction error`))})}const L={async load(e){if(typeof indexedDB>`u`)return null;let t=(await P()).transaction(N,`readonly`),n=t.objectStore(N);try{let r=await F(n.get(e));return await I(t),r??null}catch{try{await I(t)}catch{}return null}},async save(e,t){if(typeof indexedDB>`u`)return;let n=(await P()).transaction(N,`readwrite`),r=n.objectStore(N);try{r.put(t,e),await I(n)}catch{try{n.abort()}catch{}}},async clear(e){if(typeof indexedDB>`u`)return;let t=(await P()).transaction(N,`readwrite`),n=t.objectStore(N);try{n.delete(e),await I(t)}catch{try{t.abort()}catch{}}}},R={load(e){if(typeof localStorage>`u`)return null;let t=localStorage.getItem(e);if(!t)return null;try{return JSON.parse(t)}catch{return null}},save(e,t){typeof localStorage>`u`||localStorage.setItem(e,JSON.stringify(t))},clear(e){typeof localStorage>`u`||localStorage.removeItem(e)}},z=new Map,B={load(e){return z.get(e)??null},save(e,t){z.set(e,t)},clear(e){z.delete(e)}};function V(e,t){let n={};for(let t of e.items.values()){if(!v(t)||t.phase===`completed`||t.phase===`canceled`||t.phase===`error`)continue;let e=b(t)?t.cursor:void 0,r=`progress`in t&&t.progress?{uploadedBytes:t.progress.uploadedBytes,totalBytes:t.progress.totalBytes,pct:t.progress.pct}:void 0,i={id:t.localId,purpose:t.purpose,status:t.phase,file:{name:t.fingerprint.name,size:t.fingerprint.size,type:t.fingerprint.type,lastModified:t.fingerprint.lastModified,checksum:t.fingerprint.checksum},intent:t.intent,cursor:e,progress:r};n[i.id]=i}return{version:t,createdAt:Date.now(),items:n}}function H(e,t){if(!t.isPurpose||!t.isIntent||!U(e))return null;let n=new Map;for(let r of Object.values(e.items)){let i=W(r);if(!i||!t.isPurpose(i.purpose)||!t.isIntent(i.intent))continue;let a=i.intent.strategy;if(typeof a!=`string`||!t.hasStrategy(a)||!i.cursor||!K(i.cursor,t.hasStrategy)||i.cursor.strategy!==a)continue;let o=i.progress?.totalBytes??i.file.size,s=i.progress?.uploadedBytes??0,c=typeof i.progress?.pct==`number`?i.progress.pct:o>0?Math.min(100,Math.max(0,s/o*100)):0;n.set(i.id,{phase:`paused`,localId:i.id,purpose:i.purpose,fingerprint:{name:i.file.name,size:i.file.size,type:i.file.type,lastModified:i.file.lastModified,checksum:i.file.checksum},intent:i.intent,cursor:i.cursor,progress:{uploadedBytes:s,totalBytes:o,pct:c},pausedAt:Date.now(),createdAt:e.createdAt??Date.now(),file:void 0})}return{items:n}}function U(e){return!u(e)||typeof e.version!=`number`||typeof e.createdAt!=`number`?!1:u(e.items)}function W(e){if(!u(e))return null;let t=typeof e.id==`string`?e.id:null,n=typeof e.purpose==`string`?e.purpose:null,r=typeof e.status==`string`?e.status:null,i=e.intent;if(!t||!n||!r||!u(e.file))return null;let a=typeof e.file.name==`string`?e.file.name:null,o=typeof e.file.size==`number`?e.file.size:null,s=typeof e.file.type==`string`?e.file.type:null,c=typeof e.file.lastModified==`number`?e.file.lastModified:null,l=typeof e.file.checksum==`string`?e.file.checksum:void 0;if(!a||o===null||!s||c===null)return null;let d=G(e.progress);return{id:t,purpose:n,status:r,file:{name:a,size:o,type:s,lastModified:c,checksum:l},intent:i,cursor:e.cursor,progress:d}}function G(e){if(!u(e)||typeof e.uploadedBytes!=`number`||typeof e.totalBytes!=`number`)return;let t=typeof e.pct==`number`?e.pct:void 0;return{uploadedBytes:e.uploadedBytes,totalBytes:e.totalBytes,pct:t}}function K(e,t){return!(!u(e)||typeof e.strategy!=`string`||!t(e.strategy))}function q(){let e={};return{on(t,n){let r=e[t];return r||(r=new Set,e[t]=r),r.add(n),()=>{let r=e[t];r&&(r.delete(n),r.size===0&&delete e[t])}},off(t,n){let r=e[t];return r?(r.delete(n),r.size===0&&delete e[t],()=>{}):()=>{}},emit(t,n){let r=e[t];r&&r.forEach(e=>{try{e(n)}catch(e){typeof window<`u`&&process.env.NODE_ENV===`development`&&console.error(`[UploadEngine] Error in event listener for "${t}":`,e)}})}}}function J(){return function(e,t){let n=new Map(e.items),r=(e,t)=>n.set(e,t),i=Date.now();if((e=>`type`in e&&typeof e.type==`string`&&!e.type.includes(`.`))(t)){switch(t.type){case`addFiles`:break;case`start`:{let e=n.get(t.localId);if(!e||e.phase!==`ready`)break;r(t.localId,{...e,phase:`queued`,requestedAt:i});break}case`resume`:{let e=n.get(t.localId);if(!e||e.phase!==`paused`||!e.file)break;r(t.localId,{...e,file:e.file,phase:`queued`,requestedAt:i});break}case`pause`:{let e=n.get(t.localId);if(!e)break;e.phase===`queued`&&r(t.localId,{...e,phase:`ready`});break}case`cancel`:{let e=n.get(t.localId);if(!e||e.phase===`completed`||e.phase===`canceled`)break;r(t.localId,Y(e,i));break}case`retry`:{let e=n.get(t.localId);if(!e||e.phase!==`error`||!e.retryable||!e.file)break;e.intent?e.progress&&e.progress.pct===100?r(t.localId,{...e,progress:e.progress,intent:e.intent,file:e.file,phase:`completing`,completingAt:i}):r(t.localId,{...e,file:e.file,intent:e.intent,phase:`ready`}):r(t.localId,{...e,phase:`creating_intent`,file:e.file,attempt:(e.attempt??1)+1});break}case`rebind`:{let e=n.get(t.localId);if(!e)break;e.phase===`paused`&&!e.file&&m(p(t.file),e.fingerprint)&&r(t.localId,{...e,file:t.file});break}case`remove`:n.delete(t.localId);break;case`startAll`:case`pauseAll`:case`cancelAll`:break}return{items:n}}switch(t.type){case`files.added`:{let e=t;for(let t of e.items)n.has(t.localId)||r(t.localId,{phase:`validating`,localId:t.localId,purpose:t.purpose,file:t.file,fingerprint:t.fingerprint,createdAt:t.createdAt});break}case`fingerprint.updated`:{let e=t,i=n.get(e.localId);if(!i)break;r(e.localId,{...i,fingerprint:e.fingerprint});break}case`validation.ok`:{let e=n.get(t.localId);if(!e||e.phase!==`validating`)break;r(t.localId,{...e,phase:`creating_intent`,attempt:1});break}case`validation.failed`:{let e=t,a=n.get(e.localId);if(!a||a.phase!==`validating`)break;r(e.localId,{...a,phase:`error`,error:{code:`validation_failed`,reason:e.reason,message:String(e.reason)},retryable:!1,attempt:1,failedAt:i});break}case`intent.ok`:{let e=t,i=n.get(e.localId);if(!i||i.phase!==`creating_intent`)break;r(e.localId,{...i,phase:`ready`,intent:e.intent});break}case`intent.failed`:{let e=t,a=n.get(e.localId);if(!a||a.phase!==`creating_intent`)break;r(e.localId,{...a,phase:`error`,error:e.error,retryable:e.retryable,failedAt:i});break}case`upload.begin`:{let e=t,i=n.get(e.localId);if(!i||i.phase!==`queued`)break;let a=i.file.size,o=i.progress,s=o?{...o,totalBytes:a,pct:X(o.uploadedBytes,a)}:{uploadedBytes:0,totalBytes:a,pct:0};r(e.localId,{...i,phase:`uploading`,progress:s,startedAt:e.startedAt});break}case`upload.progress`:{let e=t,i=n.get(e.localId);if(!i||i.phase!==`uploading`)break;let a={uploadedBytes:e.uploadedBytes,totalBytes:e.totalBytes,pct:X(e.uploadedBytes,e.totalBytes)};r(e.localId,{...i,progress:a});break}case`cursor.updated`:{let e=t,i=n.get(e.localId);if(!i)break;(i.phase===`uploading`||i.phase===`queued`||i.phase===`paused`)&&r(e.localId,{...i,cursor:e.cursor});break}case`upload.ok`:{let e=t,a=n.get(e.localId);if(!a||a.phase!==`uploading`)break;r(e.localId,{...a,phase:`completing`,progress:{uploadedBytes:a.file.size,totalBytes:a.file.size,pct:100},completingAt:i});break}case`upload.failed`:{let e=t,a=n.get(e.localId);if(!a||a.phase!==`uploading`)break;r(e.localId,{...a,phase:`error`,error:e.error,retryable:e.retryable,attempt:1,failedAt:i});break}case`paused`:{let e=t,i=n.get(e.localId);if(!i||i.phase!==`uploading`)break;r(e.localId,{...i,phase:`paused`,cursor:e.cursor,pausedAt:e.pausedAt});break}case`canceled`:{let e=t,i=n.get(e.localId);if(!i)break;r(e.localId,Y(i,e.canceledAt));break}case`complete.ok`:{let e=t,a=n.get(e.localId);if(!a||a.phase!==`completing`)break;r(e.localId,{...a,phase:`completed`,completedBy:`upload`,result:e.result,completedAt:i});break}case`dedupe.ok`:{let e=t,a=n.get(e.localId);if(!a||a.phase!==`validating`)break;r(e.localId,{phase:`completed`,localId:a.localId,file:a.file,purpose:a.purpose,fingerprint:a.fingerprint,result:e.result,completedBy:`dedupe`,completedAt:i,createdAt:a.createdAt});break}case`complete.failed`:{let e=t,a=n.get(e.localId);if(!a||a.phase!==`completing`)break;let o=(a.attempt??1)+1;r(e.localId,{...a,phase:`error`,error:e.error,retryable:e.retryable,attempt:o,failedAt:i});break}}return{items:n}}}function Y(e,t){return{phase:`canceled`,localId:e.localId,purpose:e.purpose,fingerprint:e.fingerprint,canceledAt:t,createdAt:e.createdAt,file:`file`in e?e.file:void 0,intent:`intent`in e?e.intent:void 0,cursor:`cursor`in e?e.cursor:void 0,progress:`progress`in e?e.progress:void 0,attempt:`attempt`in e?e.attempt:void 0}}function X(e,t){return t<=0?0:Math.min(100,e/t*100)}function Z(e,t){let n=e.config?.maxItems,r=e.config?.completedItemTTL,i=Date.now(),a=[],o=Array.from(t.items.entries());if(r!==void 0)for(let[e,t]of o)((t.phase===`completed`||t.phase===`canceled`)&&`completedAt`in t&&typeof t.completedAt==`number`&&i-t.completedAt>r||t.phase===`canceled`&&`canceledAt`in t&&typeof t.canceledAt==`number`&&i-t.canceledAt>r)&&a.push(e);let s=o.filter(([e])=>!a.includes(e));if(n!==void 0&&s.length>n){let e=s.filter(([,e])=>e.phase===`completed`||e.phase===`canceled`).sort(([,e],[,t])=>(`completedAt`in e?e.completedAt:`canceledAt`in e?e.canceledAt:0)-(`completedAt`in t?t.completedAt:`canceledAt`in t?t.canceledAt:0)),t=s.length-n;for(let n=0;n<t&&n<e.length;n++)a.push(e[n][0])}if(a.length===0)return null;let c=new Map(t.items);for(let e of a)c.delete(e);return{...t,items:c}}async function oe(t,n){let r=t.state.items.get(n);if(!r||r.phase!==`creating_intent`||t.inflightIntents.has(n))return;let i=new AbortController;t.inflightIntents.set(n,i);try{let e=await t.opts.api.createIntent({purpose:r.purpose,contentType:r.file.type||`application/octet-stream`,size:r.file.size,filename:r.file.name,checksum:r.fingerprint.checksum},{signal:i.signal});t.inflightIntents.delete(n);let a=t.state.items.get(n);if(!a||a.phase!==`creating_intent`)return;let o=d(e,e.strategy);if(o){let e={code:`validation_failed`,message:`Invalid intent from backend: ${o.message}`,cause:o,retryable:!1};t.applyInternal({type:`intent.failed`,localId:n,error:e,retryable:!1});return}t.applyInternal({type:`intent.ok`,localId:n,intent:e})}catch(a){if(t.inflightIntents.delete(n),i.signal.aborted)return;let o=_(a,t.opts.errorNormalizer),s={...o,message:`${o.message} (file: ${r.fingerprint.name}, size: ${r.file.size} bytes, purpose: ${r.purpose})`},c=S(t.opts.config,{phase:`intent`,attempt:r.attempt,error:s});t.applyInternal({type:`intent.failed`,localId:n,error:s,retryable:c.retryable}),c.retryable&&c.delayMs!==void 0&&t.enqueueEffect(async()=>{await e(c.delayMs),t.dispatch({type:`retry`,localId:n})})}}async function se(t,n){let r=t.state.items.get(n);if(!r||r.phase!==`completing`||t.inflightCompletes.has(n))return;let i=new AbortController;t.inflightCompletes.set(n,i);try{let e=await t.opts.api.complete({fileId:r.intent.fileId},{signal:i.signal});t.inflightCompletes.delete(n);let a=t.state.items.get(n);if(!a||a.phase!==`completing`)return;t.applyInternal({type:`complete.ok`,localId:n,result:e})}catch(r){if(t.inflightCompletes.delete(n),i.signal.aborted)return;let a=_(r,t.opts.errorNormalizer),o=t.state.items.get(n),s=o?{...a,message:`${a.message} (file: ${o.fingerprint.name}, fileId: ${(v(o)&&o.intent?.fileId)??`unknown`})`}:a,c=o&&`attempt`in o?o.attempt??1:1,l=S(t.opts.config,{phase:`complete`,attempt:c,error:s});t.applyInternal({type:`complete.failed`,localId:n,error:s,retryable:l.retryable}),l.retryable&&l.delayMs!==void 0&&t.enqueueEffect(async()=>{await e(l.delayMs),t.dispatch({type:`retry`,localId:n})})}}async function ce(t,n){let r=t.state.items.get(n);if(!r||r.phase!==`uploading`||!v(r)){t.inflightUploads.delete(n);return}let i=t.inflightUploads.get(n);if(i||(i={controller:new AbortController,mode:`normal`,started:!1},t.inflightUploads.set(n,i)),i.started)return;i.started=!0;let a=i.controller,o=()=>{let e=t.state.items.get(n);!e||e.phase===`canceled`||t.applyInternal({type:`canceled`,localId:n,canceledAt:Date.now()})},s=e=>{let r=t.state.items.get(n);!r||r.phase===`paused`||t.applyInternal({type:`paused`,localId:n,cursor:e,pausedAt:Date.now()})};if(a.signal.aborted){if(t.inflightUploads.delete(n),i.mode===`pause`){let e=t.state.items.get(n),i;r&&v(r)&&(i=r.intent.strategy);let a=(e&&b(e)?e.cursor:void 0)||(i?{strategy:i,value:void 0}:void 0);a&&s(a);return}if(i.mode===`cancel`){o();return}return}let c=r.intent.strategy;if(!t.opts.strategies.has(c)){t.inflightUploads.delete(n);let e={code:`strategy_missing`,message:`Strategy not found: ${c}`,strategy:String(c),retryable:!1};t.applyInternal({type:`upload.failed`,localId:n,error:e,retryable:!1});return}let l=t.opts.strategies.get(c);if(!l){t.inflightUploads.delete(n);let e={code:`strategy_missing`,message:`Strategy not found: ${r.intent.strategy}`,strategy:String(r.intent.strategy),retryable:!1};t.applyInternal({type:`upload.failed`,localId:n,error:e,retryable:!1});return}let u=0,d=t.opts.config.progressThrottleMs;try{if(await l.start({file:r.file,intent:r.intent,signal:a.signal,transport:t.opts.transport,api:t.opts.api,readCursor:()=>{let e=t.state.items.get(n);if(!(!e||!b(e)||!e.cursor)&&e.cursor.strategy===c)return e.cursor.value},persistCursor:e=>{let r={strategy:c,value:e};t.applyInternal({type:`cursor.updated`,localId:n,cursor:r})},reportProgress:e=>{let r=Date.now();r-u<d||(t.applyInternal({type:`upload.progress`,localId:n,uploadedBytes:e.uploadedBytes,totalBytes:e.totalBytes}),u=r)}}),t.inflightUploads.delete(n),i?.mode===`cancel`){o();return}if(a.signal.aborted&&i?.mode===`pause`){let e=t.state.items.get(n);s((e&&b(e)?e.cursor:void 0)||{strategy:c,value:void 0});return}t.applyInternal({type:`upload.ok`,localId:n})}catch(r){if(t.inflightUploads.delete(n),a.signal.aborted){if(i?.mode===`pause`){let e=t.state.items.get(n);s((e&&b(e)?e.cursor:void 0)||{strategy:c,value:void 0});return}if(i?.mode===`cancel`){o();return}o();return}let l=_(r,t.opts.errorNormalizer),u=t.state.items.get(n),d=u?{...l,message:`${l.message} (file: ${u.fingerprint.name}, size: ${(y(u)&&u.file?.size)??0} bytes, phase: ${u.phase})`}:l,f=S(t.opts.config,{phase:`upload`,attempt:1,error:d});t.applyInternal({type:`upload.failed`,localId:n,error:d,retryable:f.retryable}),f.retryable&&f.delayMs!==void 0&&t.enqueueEffect(async()=>{await e(f.delayMs),t.dispatch({type:`retry`,localId:n})})}}function le(e){if(!e.scheduling){e.scheduling=!0;try{ue(e),fe(e),de(e)}finally{e.scheduling=!1}}}function ue(e){for(let t of e.state.items.values())t.phase===`creating_intent`&&(e.inflightIntents.has(t.localId)||e.enqueueEffect(()=>oe(e,t.localId)))}function de(e){for(let t of e.state.items.values())t.phase===`completing`&&(e.inflightCompletes.has(t.localId)||e.enqueueEffect(()=>se(e,t.localId)))}function fe(e){let t=Math.max(1,e.opts.config.maxConcurrentUploads),n=e.inflightUploads.size;for(let t of e.state.items.values())t.phase===`ready`&&g(e.opts,t.purpose)&&e.applyCommand({type:`start`,localId:t.localId});if(n>=t)return;let r=Array.from(e.state.items.values()).filter(pe);if(r.length===0)return;let i=Math.max(0,t-n),a=r.slice(0,i);for(let t of a){if(e.inflightUploads.has(t.localId))continue;let n=new AbortController;e.inflightUploads.set(t.localId,{controller:n,mode:`normal`,started:!1}),e.applyInternal({type:`upload.begin`,localId:t.localId,startedAt:Date.now()}),ce(e,t.localId)}}function pe(e){return e.phase===`queued`}function me(e){let t=Q(e),n=t.persistence,r=null,i=Math.max(0,n?.debounceMs??200),a=async()=>{if(n)try{let e=(n.serialize??V)(s.state,n.version);if(!e.items||Object.keys(e.items).length===0){await n.adapter.clear(n.key);return}await n.adapter.save(n.key,e)}catch(e){typeof window<`u`&&process.env.NODE_ENV===`development`&&console.warn(`[UploadEngine] persistence flush failed:`,e)}},o=()=>{if(n){if(i===0){a();return}r&&clearTimeout(r),r=setTimeout(()=>void a(),i)}},s={opts:t,state:t.initialState??{items:new Map},listeners:new Set,emitter:q(),reduce:J(),inflightUploads:new Map,inflightIntents:new Map,inflightCompletes:new Map,effectQueue:[],processingEffects:!1,scheduling:!1,notify(){s.listeners.forEach(e=>{e()})},scheduleWork(){le(s)},applyInternal(e){let t=s.state;s.state=s.reduce(t,e),s.opts.hooks?.onInternalEvent?.(e,s.state),he(s,e);let n=Z(s.opts,s.state);n&&(s.state=n),o(),s.notify(),s.scheduleWork()},applyCommand(e){let t=s.state,n=s.reduce(t,e);s.state=n,ge(s,e,t,n);let r=Z(s.opts,s.state);r&&(s.state=r),o(),s.notify(),s.scheduleWork()},enqueueEffect(e){s.effectQueue.push(e),s.processingEffects||s.processEffects()},async processEffects(){for(s.processingEffects=!0;s.effectQueue.length>0;){let e=s.effectQueue.shift();if(e)try{await e()}catch(e){if(typeof window<`u`&&process.env.NODE_ENV===`development`){let t=e instanceof Error?e:Error(String(e)),n={queueLength:s.effectQueue.length,processing:s.processingEffects,timestamp:new Date().toISOString()};console.error(`[UploadEngine] Effect error:`,t,n)}}}s.processingEffects=!1},dispatch:()=>{throw Error(`[UploadEngine] dispatch not initialized`)}};if(n&&!t.initialState&&typeof window<`u`)try{let e=n.adapter.load(n.key);Promise.resolve(e).then(e=>{if(!e)return;let r=(n.deserialize??H)(e,{isPurpose:n.isPurpose,isIntent:n.isIntent,hasStrategy:t.strategies.has});if(r){if(s.state.items.size===0)s.state=r;else{let e=new Map(s.state.items);for(let[t,n]of r.items.entries())e.has(t)||e.set(t,n);s.state={...s.state,items:e}}s.notify(),s.scheduleWork()}}).catch(()=>void 0)}catch{}return s}function Q(e){return{...e,config:s(e.config),transport:e.transport??M()}}function he(e,t){switch(t.type){case`files.added`:for(let n of t.items)e.emitter.emit(`file.added`,{localId:n.localId,purpose:n.purpose,file:n.file,fingerprint:n.fingerprint});break;case`validation.ok`:e.emitter.emit(`validation.ok`,{localId:t.localId}),e.emitter.emit(`intent.creating`,{localId:t.localId});break;case`validation.failed`:e.emitter.emit(`validation.failed`,{localId:t.localId,reason:t.reason});break;case`intent.ok`:e.emitter.emit(`intent.created`,{localId:t.localId,intent:t.intent});break;case`intent.failed`:e.emitter.emit(`intent.failed`,{localId:t.localId,error:t.error,retryable:t.retryable});break;case`upload.begin`:e.emitter.emit(`upload.started`,{localId:t.localId});break;case`upload.progress`:{let n=t.totalBytes>0?Math.min(100,t.uploadedBytes/t.totalBytes*100):0;e.emitter.emit(`upload.progress`,{localId:t.localId,pct:n,uploadedBytes:t.uploadedBytes,totalBytes:t.totalBytes});break}case`cursor.updated`:e.emitter.emit(`upload.cursor`,{localId:t.localId,cursor:t.cursor});break;case`upload.ok`:e.emitter.emit(`upload.completing`,{localId:t.localId});break;case`upload.failed`:e.emitter.emit(`upload.error`,{localId:t.localId,error:t.error,retryable:t.retryable});break;case`dedupe.ok`:e.emitter.emit(`upload.completed`,{localId:t.localId,result:t.result,completedBy:`dedupe`});break;case`complete.ok`:e.emitter.emit(`upload.completed`,{localId:t.localId,result:t.result,completedBy:`upload`});break;case`complete.failed`:e.emitter.emit(`upload.error`,{localId:t.localId,error:t.error,retryable:t.retryable});break;case`paused`:e.emitter.emit(`upload.paused`,{localId:t.localId,cursor:t.cursor});break;case`canceled`:e.emitter.emit(`upload.canceled`,{localId:t.localId});break;case`fingerprint.updated`:break}}function ge(e,t,n,r){if(t.type===`start`||t.type===`resume`){let i=n.items.get(t.localId),a=r.items.get(t.localId);if(!i||!a||a.phase!==`queued`)return;i.phase===`paused`?e.emitter.emit(`upload.resumed`,{localId:t.localId}):e.emitter.emit(`upload.queued`,{localId:t.localId})}if(t.type===`cancel`){let i=n.items.get(t.localId),a=r.items.get(t.localId);if(!i||!a)return;a.phase===`canceled`&&i.phase!==`canceled`&&e.emitter.emit(`upload.canceled`,{localId:t.localId})}}function $(e){let t=me(e);t.dispatch=e=>E(t,e);let n={on:t.emitter.on.bind(t.emitter),off:t.emitter.off.bind(t.emitter),dispatch:t.dispatch,getSnapshot:()=>t.state};for(let t of e.plugins||[])try{t.setup(n)}catch(e){typeof window<`u`&&process.env.NODE_ENV===`development`&&console.error(`[UploadEngine] Plugin "${t.name}" failed to setup:`,e)}return{...n,subscribe:e=>(t.listeners.add(e),()=>t.listeners.delete(e)),waitFor(e){return _e(t,e)}}}function _e(e,t){if(t.length===0)return Promise.resolve([]);let n=new Set(t),r=new Map,i=()=>{for(let t of n){let i=e.state.items.get(t);if(!i){r.set(t,{localId:t,status:`missing`}),n.delete(t);continue}if(i.phase===`completed`){r.set(t,{localId:t,status:`completed`,completedBy:i.completedBy,result:i.result}),n.delete(t);continue}if(i.phase===`error`){r.set(t,{localId:t,status:`error`,error:i.error}),n.delete(t);continue}i.phase===`canceled`&&(r.set(t,{localId:t,status:`canceled`}),n.delete(t))}};return i(),n.size===0?Promise.resolve(t.map(e=>r.get(e)??{localId:e,status:`missing`})):new Promise(a=>{let o=()=>{i(),n.size===0&&(e.listeners.delete(o),a(t.map(e=>r.get(e)??{localId:e,status:`missing`})))};e.listeners.add(o)})}function ve(e){return $(e)}export{t as C,r as S,c as _,H as a,a as b,R as c,p as d,m as f,l as g,u as h,q as i,L as l,d as m,$ as n,V as o,f as p,J as r,B as s,ve as t,M as u,s as v,n as w,o as x,i as y};