@mux/upchunk
Version:
Dead simple chunked file uploads using Fetch
1,495 lines (1,487 loc) • 48.8 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
// node_modules/global/window.js
var require_window = __commonJS({
"node_modules/global/window.js"(exports, module) {
var win;
if (typeof window !== "undefined") {
win = window;
} else if (typeof global !== "undefined") {
win = global;
} else if (typeof self !== "undefined") {
win = self;
} else {
win = {};
}
module.exports = win;
}
});
// node_modules/is-function/index.js
var require_is_function = __commonJS({
"node_modules/is-function/index.js"(exports, module) {
module.exports = isFunction;
var toString = Object.prototype.toString;
function isFunction(fn) {
if (!fn) {
return false;
}
var string = toString.call(fn);
return string === "[object Function]" || typeof fn === "function" && string !== "[object RegExp]" || typeof window !== "undefined" && (fn === window.setTimeout || fn === window.alert || fn === window.confirm || fn === window.prompt);
}
}
});
// node_modules/parse-headers/parse-headers.js
var require_parse_headers = __commonJS({
"node_modules/parse-headers/parse-headers.js"(exports, module) {
var trim = function(string) {
return string.replace(/^\s+|\s+$/g, "");
};
var isArray = function(arg) {
return Object.prototype.toString.call(arg) === "[object Array]";
};
module.exports = function(headers) {
if (!headers)
return {};
var result = {};
var headersArr = trim(headers).split("\n");
for (var i = 0; i < headersArr.length; i++) {
var row = headersArr[i];
var index = row.indexOf(":"), key = trim(row.slice(0, index)).toLowerCase(), value = trim(row.slice(index + 1));
if (typeof result[key] === "undefined") {
result[key] = value;
} else if (isArray(result[key])) {
result[key].push(value);
} else {
result[key] = [result[key], value];
}
}
return result;
};
}
});
// node_modules/xtend/immutable.js
var require_immutable = __commonJS({
"node_modules/xtend/immutable.js"(exports, module) {
module.exports = extend;
var hasOwnProperty = Object.prototype.hasOwnProperty;
function extend() {
var target = {};
for (var i = 0; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
}
}
});
// node_modules/xhr/index.js
var require_xhr = __commonJS({
"node_modules/xhr/index.js"(exports, module) {
"use strict";
var window2 = require_window();
var isFunction = require_is_function();
var parseHeaders = require_parse_headers();
var xtend = require_immutable();
module.exports = createXHR;
module.exports.default = createXHR;
createXHR.XMLHttpRequest = window2.XMLHttpRequest || noop;
createXHR.XDomainRequest = "withCredentials" in new createXHR.XMLHttpRequest() ? createXHR.XMLHttpRequest : window2.XDomainRequest;
forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
options = initParams(uri, options, callback);
options.method = method.toUpperCase();
return _createXHR(options);
};
});
function forEachArray(array, iterator) {
for (var i = 0; i < array.length; i++) {
iterator(array[i]);
}
}
function isEmpty(obj) {
for (var i in obj) {
if (obj.hasOwnProperty(i))
return false;
}
return true;
}
function initParams(uri, options, callback) {
var params = uri;
if (isFunction(options)) {
callback = options;
if (typeof uri === "string") {
params = { uri };
}
} else {
params = xtend(options, { uri });
}
params.callback = callback;
return params;
}
function createXHR(uri, options, callback) {
options = initParams(uri, options, callback);
return _createXHR(options);
}
function _createXHR(options) {
if (typeof options.callback === "undefined") {
throw new Error("callback argument missing");
}
var called = false;
var callback = function cbOnce(err, response, body2) {
if (!called) {
called = true;
options.callback(err, response, body2);
}
};
function readystatechange() {
if (xhr2.readyState === 4) {
setTimeout(loadFunc, 0);
}
}
function getBody() {
var body2 = void 0;
if (xhr2.response) {
body2 = xhr2.response;
} else {
body2 = xhr2.responseText || getXml(xhr2);
}
if (isJson) {
try {
body2 = JSON.parse(body2);
} catch (e) {
}
}
return body2;
}
function errorFunc(evt) {
clearTimeout(timeoutTimer);
if (!(evt instanceof Error)) {
evt = new Error("" + (evt || "Unknown XMLHttpRequest Error"));
}
evt.statusCode = 0;
return callback(evt, failureResponse);
}
function loadFunc() {
if (aborted)
return;
var status;
clearTimeout(timeoutTimer);
if (options.useXDR && xhr2.status === void 0) {
status = 200;
} else {
status = xhr2.status === 1223 ? 204 : xhr2.status;
}
var response = failureResponse;
var err = null;
if (status !== 0) {
response = {
body: getBody(),
statusCode: status,
method,
headers: {},
url: uri,
rawRequest: xhr2
};
if (xhr2.getAllResponseHeaders) {
response.headers = parseHeaders(xhr2.getAllResponseHeaders());
}
} else {
err = new Error("Internal XMLHttpRequest Error");
}
return callback(err, response, response.body);
}
var xhr2 = options.xhr || null;
if (!xhr2) {
if (options.cors || options.useXDR) {
xhr2 = new createXHR.XDomainRequest();
} else {
xhr2 = new createXHR.XMLHttpRequest();
}
}
var key;
var aborted;
var uri = xhr2.url = options.uri || options.url;
var method = xhr2.method = options.method || "GET";
var body = options.body || options.data;
var headers = xhr2.headers = options.headers || {};
var sync = !!options.sync;
var isJson = false;
var timeoutTimer;
var failureResponse = {
body: void 0,
headers: {},
statusCode: 0,
method,
url: uri,
rawRequest: xhr2
};
if ("json" in options && options.json !== false) {
isJson = true;
headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json");
if (method !== "GET" && method !== "HEAD") {
headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json");
body = JSON.stringify(options.json === true ? body : options.json);
}
}
xhr2.onreadystatechange = readystatechange;
xhr2.onload = loadFunc;
xhr2.onerror = errorFunc;
xhr2.onprogress = function() {
};
xhr2.onabort = function() {
aborted = true;
};
xhr2.ontimeout = errorFunc;
xhr2.open(method, uri, !sync, options.username, options.password);
if (!sync) {
xhr2.withCredentials = !!options.withCredentials;
}
if (!sync && options.timeout > 0) {
timeoutTimer = setTimeout(function() {
if (aborted)
return;
aborted = true;
xhr2.abort("timeout");
var e = new Error("XMLHttpRequest timeout");
e.code = "ETIMEDOUT";
errorFunc(e);
}, options.timeout);
}
if (xhr2.setRequestHeader) {
for (key in headers) {
if (headers.hasOwnProperty(key)) {
xhr2.setRequestHeader(key, headers[key]);
}
}
} else if (options.headers && !isEmpty(options.headers)) {
throw new Error("Headers cannot be set on an XDomainRequest object");
}
if ("responseType" in options) {
xhr2.responseType = options.responseType;
}
if ("beforeSend" in options && typeof options.beforeSend === "function") {
options.beforeSend(xhr2);
}
xhr2.send(body || null);
return xhr2;
}
function getXml(xhr2) {
try {
if (xhr2.responseType === "document") {
return xhr2.responseXML;
}
var firefoxBugTakenEffect = xhr2.responseXML && xhr2.responseXML.documentElement.nodeName === "parsererror";
if (xhr2.responseType === "" && !firefoxBugTakenEffect) {
return xhr2.responseXML;
}
} catch (e) {
}
return null;
}
function noop() {
}
}
});
// node_modules/event-target-shim/index.mjs
function assertType(condition, message, ...args) {
if (!condition) {
throw new TypeError(format(message, args));
}
}
function format(message, args) {
let i = 0;
return message.replace(/%[os]/gu, () => anyToString(args[i++]));
}
function anyToString(x) {
if (typeof x !== "object" || x === null) {
return String(x);
}
return Object.prototype.toString.call(x);
}
var currentErrorHandler;
function reportError(maybeError) {
try {
const error = maybeError instanceof Error ? maybeError : new Error(anyToString(maybeError));
if (currentErrorHandler) {
currentErrorHandler(error);
return;
}
if (typeof dispatchEvent === "function" && typeof ErrorEvent === "function") {
dispatchEvent(new ErrorEvent("error", { error, message: error.message }));
} else if (typeof process !== "undefined" && typeof process.emit === "function") {
process.emit("uncaughtException", error);
return;
}
console.error(error);
} catch (_a) {
}
}
var Global = typeof window !== "undefined" ? window : typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : typeof globalThis !== "undefined" ? globalThis : void 0;
var currentWarnHandler;
var Warning = class {
constructor(code, message) {
this.code = code;
this.message = message;
}
warn(...args) {
var _a;
try {
if (currentWarnHandler) {
currentWarnHandler({ ...this, args });
return;
}
const stack = ((_a = new Error().stack) !== null && _a !== void 0 ? _a : "").replace(/^(?:.+?\n){2}/gu, "\n");
console.warn(this.message, ...args, stack);
} catch (_b) {
}
}
};
var InitEventWasCalledWhileDispatching = new Warning("W01", "Unable to initialize event under dispatching.");
var FalsyWasAssignedToCancelBubble = new Warning("W02", "Assigning any falsy value to 'cancelBubble' property has no effect.");
var TruthyWasAssignedToReturnValue = new Warning("W03", "Assigning any truthy value to 'returnValue' property has no effect.");
var NonCancelableEventWasCanceled = new Warning("W04", "Unable to preventDefault on non-cancelable events.");
var CanceledInPassiveListener = new Warning("W05", "Unable to preventDefault inside passive event listener invocation.");
var EventListenerWasDuplicated = new Warning("W06", "An event listener wasn't added because it has been added already: %o, %o");
var OptionWasIgnored = new Warning("W07", "The %o option value was abandoned because the event listener wasn't added as duplicated.");
var InvalidEventListener = new Warning("W08", "The 'callback' argument must be a function or an object that has 'handleEvent' method: %o");
var InvalidAttributeHandler = new Warning("W09", "Event attribute handler must be a function: %o");
var Event = class {
static get NONE() {
return NONE;
}
static get CAPTURING_PHASE() {
return CAPTURING_PHASE;
}
static get AT_TARGET() {
return AT_TARGET;
}
static get BUBBLING_PHASE() {
return BUBBLING_PHASE;
}
constructor(type, eventInitDict) {
Object.defineProperty(this, "isTrusted", {
value: false,
enumerable: true
});
const opts = eventInitDict !== null && eventInitDict !== void 0 ? eventInitDict : {};
internalDataMap.set(this, {
type: String(type),
bubbles: Boolean(opts.bubbles),
cancelable: Boolean(opts.cancelable),
composed: Boolean(opts.composed),
target: null,
currentTarget: null,
stopPropagationFlag: false,
stopImmediatePropagationFlag: false,
canceledFlag: false,
inPassiveListenerFlag: false,
dispatchFlag: false,
timeStamp: Date.now()
});
}
get type() {
return $(this).type;
}
get target() {
return $(this).target;
}
get srcElement() {
return $(this).target;
}
get currentTarget() {
return $(this).currentTarget;
}
composedPath() {
const currentTarget = $(this).currentTarget;
if (currentTarget) {
return [currentTarget];
}
return [];
}
get NONE() {
return NONE;
}
get CAPTURING_PHASE() {
return CAPTURING_PHASE;
}
get AT_TARGET() {
return AT_TARGET;
}
get BUBBLING_PHASE() {
return BUBBLING_PHASE;
}
get eventPhase() {
return $(this).dispatchFlag ? 2 : 0;
}
stopPropagation() {
$(this).stopPropagationFlag = true;
}
get cancelBubble() {
return $(this).stopPropagationFlag;
}
set cancelBubble(value) {
if (value) {
$(this).stopPropagationFlag = true;
} else {
FalsyWasAssignedToCancelBubble.warn();
}
}
stopImmediatePropagation() {
const data = $(this);
data.stopPropagationFlag = data.stopImmediatePropagationFlag = true;
}
get bubbles() {
return $(this).bubbles;
}
get cancelable() {
return $(this).cancelable;
}
get returnValue() {
return !$(this).canceledFlag;
}
set returnValue(value) {
if (!value) {
setCancelFlag($(this));
} else {
TruthyWasAssignedToReturnValue.warn();
}
}
preventDefault() {
setCancelFlag($(this));
}
get defaultPrevented() {
return $(this).canceledFlag;
}
get composed() {
return $(this).composed;
}
get isTrusted() {
return false;
}
get timeStamp() {
return $(this).timeStamp;
}
initEvent(type, bubbles = false, cancelable = false) {
const data = $(this);
if (data.dispatchFlag) {
InitEventWasCalledWhileDispatching.warn();
return;
}
internalDataMap.set(this, {
...data,
type: String(type),
bubbles: Boolean(bubbles),
cancelable: Boolean(cancelable),
target: null,
currentTarget: null,
stopPropagationFlag: false,
stopImmediatePropagationFlag: false,
canceledFlag: false
});
}
};
var NONE = 0;
var CAPTURING_PHASE = 1;
var AT_TARGET = 2;
var BUBBLING_PHASE = 3;
var internalDataMap = /* @__PURE__ */ new WeakMap();
function $(event, name = "this") {
const retv = internalDataMap.get(event);
assertType(retv != null, "'%s' must be an object that Event constructor created, but got another one: %o", name, event);
return retv;
}
function setCancelFlag(data) {
if (data.inPassiveListenerFlag) {
CanceledInPassiveListener.warn();
return;
}
if (!data.cancelable) {
NonCancelableEventWasCanceled.warn();
return;
}
data.canceledFlag = true;
}
Object.defineProperty(Event, "NONE", { enumerable: true });
Object.defineProperty(Event, "CAPTURING_PHASE", { enumerable: true });
Object.defineProperty(Event, "AT_TARGET", { enumerable: true });
Object.defineProperty(Event, "BUBBLING_PHASE", { enumerable: true });
var keys = Object.getOwnPropertyNames(Event.prototype);
for (let i = 0; i < keys.length; ++i) {
if (keys[i] === "constructor") {
continue;
}
Object.defineProperty(Event.prototype, keys[i], { enumerable: true });
}
if (typeof Global !== "undefined" && typeof Global.Event !== "undefined") {
Object.setPrototypeOf(Event.prototype, Global.Event.prototype);
}
function createInvalidStateError(message) {
if (Global.DOMException) {
return new Global.DOMException(message, "InvalidStateError");
}
if (DOMException == null) {
DOMException = class DOMException2 extends Error {
constructor(msg) {
super(msg);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, DOMException2);
}
}
get code() {
return 11;
}
get name() {
return "InvalidStateError";
}
};
Object.defineProperties(DOMException.prototype, {
code: { enumerable: true },
name: { enumerable: true }
});
defineErrorCodeProperties(DOMException);
defineErrorCodeProperties(DOMException.prototype);
}
return new DOMException(message);
}
var DOMException;
var ErrorCodeMap = {
INDEX_SIZE_ERR: 1,
DOMSTRING_SIZE_ERR: 2,
HIERARCHY_REQUEST_ERR: 3,
WRONG_DOCUMENT_ERR: 4,
INVALID_CHARACTER_ERR: 5,
NO_DATA_ALLOWED_ERR: 6,
NO_MODIFICATION_ALLOWED_ERR: 7,
NOT_FOUND_ERR: 8,
NOT_SUPPORTED_ERR: 9,
INUSE_ATTRIBUTE_ERR: 10,
INVALID_STATE_ERR: 11,
SYNTAX_ERR: 12,
INVALID_MODIFICATION_ERR: 13,
NAMESPACE_ERR: 14,
INVALID_ACCESS_ERR: 15,
VALIDATION_ERR: 16,
TYPE_MISMATCH_ERR: 17,
SECURITY_ERR: 18,
NETWORK_ERR: 19,
ABORT_ERR: 20,
URL_MISMATCH_ERR: 21,
QUOTA_EXCEEDED_ERR: 22,
TIMEOUT_ERR: 23,
INVALID_NODE_TYPE_ERR: 24,
DATA_CLONE_ERR: 25
};
function defineErrorCodeProperties(obj) {
const keys2 = Object.keys(ErrorCodeMap);
for (let i = 0; i < keys2.length; ++i) {
const key = keys2[i];
const value = ErrorCodeMap[key];
Object.defineProperty(obj, key, {
get() {
return value;
},
configurable: true,
enumerable: true
});
}
}
var EventWrapper = class extends Event {
static wrap(event) {
return new (getWrapperClassOf(event))(event);
}
constructor(event) {
super(event.type, {
bubbles: event.bubbles,
cancelable: event.cancelable,
composed: event.composed
});
if (event.cancelBubble) {
super.stopPropagation();
}
if (event.defaultPrevented) {
super.preventDefault();
}
internalDataMap$1.set(this, { original: event });
const keys2 = Object.keys(event);
for (let i = 0; i < keys2.length; ++i) {
const key = keys2[i];
if (!(key in this)) {
Object.defineProperty(this, key, defineRedirectDescriptor(event, key));
}
}
}
stopPropagation() {
super.stopPropagation();
const { original } = $$1(this);
if ("stopPropagation" in original) {
original.stopPropagation();
}
}
get cancelBubble() {
return super.cancelBubble;
}
set cancelBubble(value) {
super.cancelBubble = value;
const { original } = $$1(this);
if ("cancelBubble" in original) {
original.cancelBubble = value;
}
}
stopImmediatePropagation() {
super.stopImmediatePropagation();
const { original } = $$1(this);
if ("stopImmediatePropagation" in original) {
original.stopImmediatePropagation();
}
}
get returnValue() {
return super.returnValue;
}
set returnValue(value) {
super.returnValue = value;
const { original } = $$1(this);
if ("returnValue" in original) {
original.returnValue = value;
}
}
preventDefault() {
super.preventDefault();
const { original } = $$1(this);
if ("preventDefault" in original) {
original.preventDefault();
}
}
get timeStamp() {
const { original } = $$1(this);
if ("timeStamp" in original) {
return original.timeStamp;
}
return super.timeStamp;
}
};
var internalDataMap$1 = /* @__PURE__ */ new WeakMap();
function $$1(event) {
const retv = internalDataMap$1.get(event);
assertType(retv != null, "'this' is expected an Event object, but got", event);
return retv;
}
var wrapperClassCache = /* @__PURE__ */ new WeakMap();
wrapperClassCache.set(Object.prototype, EventWrapper);
if (typeof Global !== "undefined" && typeof Global.Event !== "undefined") {
wrapperClassCache.set(Global.Event.prototype, EventWrapper);
}
function getWrapperClassOf(originalEvent) {
const prototype = Object.getPrototypeOf(originalEvent);
if (prototype == null) {
return EventWrapper;
}
let wrapper = wrapperClassCache.get(prototype);
if (wrapper == null) {
wrapper = defineWrapper(getWrapperClassOf(prototype), prototype);
wrapperClassCache.set(prototype, wrapper);
}
return wrapper;
}
function defineWrapper(BaseEventWrapper, originalPrototype) {
class CustomEventWrapper extends BaseEventWrapper {
}
const keys2 = Object.keys(originalPrototype);
for (let i = 0; i < keys2.length; ++i) {
Object.defineProperty(CustomEventWrapper.prototype, keys2[i], defineRedirectDescriptor(originalPrototype, keys2[i]));
}
return CustomEventWrapper;
}
function defineRedirectDescriptor(obj, key) {
const d = Object.getOwnPropertyDescriptor(obj, key);
return {
get() {
const original = $$1(this).original;
const value = original[key];
if (typeof value === "function") {
return value.bind(original);
}
return value;
},
set(value) {
const original = $$1(this).original;
original[key] = value;
},
configurable: d.configurable,
enumerable: d.enumerable
};
}
function createListener(callback, capture, passive, once, signal, signalListener) {
return {
callback,
flags: (capture ? 1 : 0) | (passive ? 2 : 0) | (once ? 4 : 0),
signal,
signalListener
};
}
function setRemoved(listener) {
listener.flags |= 8;
}
function isCapture(listener) {
return (listener.flags & 1) === 1;
}
function isPassive(listener) {
return (listener.flags & 2) === 2;
}
function isOnce(listener) {
return (listener.flags & 4) === 4;
}
function isRemoved(listener) {
return (listener.flags & 8) === 8;
}
function invokeCallback({ callback }, target, event) {
try {
if (typeof callback === "function") {
callback.call(target, event);
} else if (typeof callback.handleEvent === "function") {
callback.handleEvent(event);
}
} catch (thrownError) {
reportError(thrownError);
}
}
function findIndexOfListener({ listeners }, callback, capture) {
for (let i = 0; i < listeners.length; ++i) {
if (listeners[i].callback === callback && isCapture(listeners[i]) === capture) {
return i;
}
}
return -1;
}
function addListener(list, callback, capture, passive, once, signal) {
let signalListener;
if (signal) {
signalListener = removeListener.bind(null, list, callback, capture);
signal.addEventListener("abort", signalListener);
}
const listener = createListener(callback, capture, passive, once, signal, signalListener);
if (list.cow) {
list.cow = false;
list.listeners = [...list.listeners, listener];
} else {
list.listeners.push(listener);
}
return listener;
}
function removeListener(list, callback, capture) {
const index = findIndexOfListener(list, callback, capture);
if (index !== -1) {
return removeListenerAt(list, index);
}
return false;
}
function removeListenerAt(list, index, disableCow = false) {
const listener = list.listeners[index];
setRemoved(listener);
if (listener.signal) {
listener.signal.removeEventListener("abort", listener.signalListener);
}
if (list.cow && !disableCow) {
list.cow = false;
list.listeners = list.listeners.filter((_, i) => i !== index);
return false;
}
list.listeners.splice(index, 1);
return true;
}
function createListenerListMap() {
return /* @__PURE__ */ Object.create(null);
}
function ensureListenerList(listenerMap, type) {
var _a;
return (_a = listenerMap[type]) !== null && _a !== void 0 ? _a : listenerMap[type] = {
attrCallback: void 0,
attrListener: void 0,
cow: false,
listeners: []
};
}
var EventTarget = class {
constructor() {
internalDataMap$2.set(this, createListenerListMap());
}
addEventListener(type0, callback0, options0) {
const listenerMap = $$2(this);
const { callback, capture, once, passive, signal, type } = normalizeAddOptions(type0, callback0, options0);
if (callback == null || (signal === null || signal === void 0 ? void 0 : signal.aborted)) {
return;
}
const list = ensureListenerList(listenerMap, type);
const i = findIndexOfListener(list, callback, capture);
if (i !== -1) {
warnDuplicate(list.listeners[i], passive, once, signal);
return;
}
addListener(list, callback, capture, passive, once, signal);
}
removeEventListener(type0, callback0, options0) {
const listenerMap = $$2(this);
const { callback, capture, type } = normalizeOptions(type0, callback0, options0);
const list = listenerMap[type];
if (callback != null && list) {
removeListener(list, callback, capture);
}
}
dispatchEvent(e) {
const list = $$2(this)[String(e.type)];
if (list == null) {
return true;
}
const event = e instanceof Event ? e : EventWrapper.wrap(e);
const eventData = $(event, "event");
if (eventData.dispatchFlag) {
throw createInvalidStateError("This event has been in dispatching.");
}
eventData.dispatchFlag = true;
eventData.target = eventData.currentTarget = this;
if (!eventData.stopPropagationFlag) {
const { cow, listeners } = list;
list.cow = true;
for (let i = 0; i < listeners.length; ++i) {
const listener = listeners[i];
if (isRemoved(listener)) {
continue;
}
if (isOnce(listener) && removeListenerAt(list, i, !cow)) {
i -= 1;
}
eventData.inPassiveListenerFlag = isPassive(listener);
invokeCallback(listener, this, event);
eventData.inPassiveListenerFlag = false;
if (eventData.stopImmediatePropagationFlag) {
break;
}
}
if (!cow) {
list.cow = false;
}
}
eventData.target = null;
eventData.currentTarget = null;
eventData.stopImmediatePropagationFlag = false;
eventData.stopPropagationFlag = false;
eventData.dispatchFlag = false;
return !eventData.canceledFlag;
}
};
var internalDataMap$2 = /* @__PURE__ */ new WeakMap();
function $$2(target, name = "this") {
const retv = internalDataMap$2.get(target);
assertType(retv != null, "'%s' must be an object that EventTarget constructor created, but got another one: %o", name, target);
return retv;
}
function normalizeAddOptions(type, callback, options) {
var _a;
assertCallback(callback);
if (typeof options === "object" && options !== null) {
return {
type: String(type),
callback: callback !== null && callback !== void 0 ? callback : void 0,
capture: Boolean(options.capture),
passive: Boolean(options.passive),
once: Boolean(options.once),
signal: (_a = options.signal) !== null && _a !== void 0 ? _a : void 0
};
}
return {
type: String(type),
callback: callback !== null && callback !== void 0 ? callback : void 0,
capture: Boolean(options),
passive: false,
once: false,
signal: void 0
};
}
function normalizeOptions(type, callback, options) {
assertCallback(callback);
if (typeof options === "object" && options !== null) {
return {
type: String(type),
callback: callback !== null && callback !== void 0 ? callback : void 0,
capture: Boolean(options.capture)
};
}
return {
type: String(type),
callback: callback !== null && callback !== void 0 ? callback : void 0,
capture: Boolean(options)
};
}
function assertCallback(callback) {
if (typeof callback === "function" || typeof callback === "object" && callback !== null && typeof callback.handleEvent === "function") {
return;
}
if (callback == null || typeof callback === "object") {
InvalidEventListener.warn(callback);
return;
}
throw new TypeError(format(InvalidEventListener.message, [callback]));
}
function warnDuplicate(listener, passive, once, signal) {
EventListenerWasDuplicated.warn(isCapture(listener) ? "capture" : "bubble", listener.callback);
if (isPassive(listener) !== passive) {
OptionWasIgnored.warn("passive");
}
if (isOnce(listener) !== once) {
OptionWasIgnored.warn("once");
}
if (listener.signal !== signal) {
OptionWasIgnored.warn("signal");
}
}
var keys$1 = Object.getOwnPropertyNames(EventTarget.prototype);
for (let i = 0; i < keys$1.length; ++i) {
if (keys$1[i] === "constructor") {
continue;
}
Object.defineProperty(EventTarget.prototype, keys$1[i], { enumerable: true });
}
if (typeof Global !== "undefined" && typeof Global.EventTarget !== "undefined") {
Object.setPrototypeOf(EventTarget.prototype, Global.EventTarget.prototype);
}
// src/upchunk.ts
var import_xhr = __toESM(require_xhr());
var DEFAULT_CHUNK_SIZE = 30720;
var DEFAULT_MAX_CHUNK_SIZE = 512e3;
var DEFAULT_MIN_CHUNK_SIZE = 256;
var isValidChunkSize = (chunkSize, {
minChunkSize = DEFAULT_MIN_CHUNK_SIZE,
maxChunkSize = DEFAULT_MAX_CHUNK_SIZE
} = {}) => {
return chunkSize == null || typeof chunkSize === "number" && chunkSize >= 256 && chunkSize % 256 === 0 && chunkSize >= minChunkSize && chunkSize <= maxChunkSize;
};
var getChunkSizeError = (chunkSize, {
minChunkSize = DEFAULT_MIN_CHUNK_SIZE,
maxChunkSize = DEFAULT_MAX_CHUNK_SIZE
} = {}) => {
return new TypeError(`chunkSize ${chunkSize} must be a positive number in multiples of 256, between ${minChunkSize} and ${maxChunkSize}`);
};
var ChunkedStreamIterable = class {
constructor(readableStream, options = {}) {
this.readableStream = readableStream;
var _a, _b, _c;
if (!isValidChunkSize(options.defaultChunkSize, options)) {
throw getChunkSizeError(options.defaultChunkSize, options);
}
this.defaultChunkSize = (_a = options.defaultChunkSize) != null ? _a : DEFAULT_CHUNK_SIZE;
this.minChunkSize = (_b = options.minChunkSize) != null ? _b : DEFAULT_MIN_CHUNK_SIZE;
this.maxChunkSize = (_c = options.maxChunkSize) != null ? _c : DEFAULT_MAX_CHUNK_SIZE;
}
get chunkSize() {
var _a;
return (_a = this._chunkSize) != null ? _a : this.defaultChunkSize;
}
set chunkSize(value) {
if (!isValidChunkSize(value, this)) {
throw getChunkSizeError(value, this);
}
this._chunkSize = value;
}
get chunkByteSize() {
return this.chunkSize * 1024;
}
get error() {
return this._error;
}
async *[Symbol.asyncIterator]() {
let chunk;
const reader = this.readableStream.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) {
if (chunk) {
const outgoingChunk = chunk;
chunk = void 0;
yield outgoingChunk;
}
break;
}
const normalizedBlobChunk = value instanceof Uint8Array ? new Blob([value], { type: "application/octet-stream" }) : value;
chunk = chunk ? new Blob([chunk, normalizedBlobChunk]) : normalizedBlobChunk;
while (chunk) {
if (chunk.size === this.chunkByteSize) {
const outgoingChunk = chunk;
chunk = void 0;
yield outgoingChunk;
break;
} else if (chunk.size < this.chunkByteSize) {
break;
} else {
const outgoingChunk = chunk.slice(0, this.chunkByteSize);
chunk = chunk.slice(this.chunkByteSize);
yield outgoingChunk;
}
}
}
} catch (e) {
this._error = e;
} finally {
if (chunk) {
const outgoingChunk = chunk;
chunk = void 0;
yield outgoingChunk;
}
reader.releaseLock();
return;
}
}
};
var ChunkedFileIterable = class {
constructor(file, options = {}) {
this.file = file;
var _a, _b, _c;
if (!isValidChunkSize(options.defaultChunkSize, options)) {
throw getChunkSizeError(options.defaultChunkSize, options);
}
this.defaultChunkSize = (_a = options.defaultChunkSize) != null ? _a : DEFAULT_CHUNK_SIZE;
this.minChunkSize = (_b = options.minChunkSize) != null ? _b : DEFAULT_MIN_CHUNK_SIZE;
this.maxChunkSize = (_c = options.maxChunkSize) != null ? _c : DEFAULT_MAX_CHUNK_SIZE;
}
get chunkSize() {
var _a;
return (_a = this._chunkSize) != null ? _a : this.defaultChunkSize;
}
set chunkSize(value) {
if (!isValidChunkSize(value, this)) {
throw getChunkSizeError(value, this);
}
this._chunkSize = value;
}
get chunkByteSize() {
return this.chunkSize * 1024;
}
get error() {
return this._error;
}
async *[Symbol.asyncIterator]() {
const reader = new FileReader();
let nextChunkRangeStart = 0;
const getChunk = () => {
return new Promise((resolve) => {
if (nextChunkRangeStart >= this.file.size) {
resolve(void 0);
return;
}
const length = Math.min(this.chunkByteSize, this.file.size - nextChunkRangeStart);
reader.onload = () => {
if (reader.result !== null) {
resolve(new Blob([reader.result], {
type: "application/octet-stream"
}));
} else {
resolve(void 0);
}
};
reader.readAsArrayBuffer(this.file.slice(nextChunkRangeStart, nextChunkRangeStart + length));
});
};
try {
while (true) {
const nextChunk = await getChunk();
if (!!nextChunk) {
nextChunkRangeStart += nextChunk.size;
yield nextChunk;
} else {
break;
}
}
} catch (e) {
this._error = e;
}
}
};
var SUCCESSFUL_CHUNK_UPLOAD_CODES = [200, 201, 202, 204, 308];
var TEMPORARY_ERROR_CODES = [408, 502, 503, 504];
var RESUME_INCOMPLETE_CODES = [308];
var isSuccessfulChunkUpload = (res, _options) => !!res && SUCCESSFUL_CHUNK_UPLOAD_CODES.includes(res.statusCode);
var isRetriableChunkUpload = (res, { retryCodes = TEMPORARY_ERROR_CODES }) => !res || retryCodes.includes(res.statusCode);
var isFailedChunkUpload = (res, options) => {
return options.attemptCount >= options.attempts || !(isSuccessfulChunkUpload(res) || isRetriableChunkUpload(res, options));
};
var isIncompleteChunkUploadNeedingRetry = (res, _options) => {
var _a;
if (!res || !RESUME_INCOMPLETE_CODES.includes(res.statusCode) || !((_a = res.headers) == null ? void 0 : _a["range"])) {
return false;
}
const range = res.headers["range"].match(/bytes=(\d+)-(\d+)/);
if (!range) {
return false;
}
const endByte = parseInt(range[2], 10);
return endByte < _options.currentChunkEndByte;
};
var UpChunk = class {
static createUpload(options) {
return new UpChunk(options);
}
constructor(options) {
this.eventTarget = new EventTarget();
this.endpoint = options.endpoint;
this.file = options.file;
this.headers = options.headers || {};
this.method = options.method || "PUT";
this.attempts = options.attempts || 5;
this.delayBeforeAttempt = options.delayBeforeAttempt || 1;
this.retryCodes = options.retryCodes || TEMPORARY_ERROR_CODES;
this.dynamicChunkSize = options.dynamicChunkSize || false;
this.maxFileBytes = (options.maxFileSize || 0) * 1024;
this.chunkCount = 0;
this.attemptCount = 0;
this._offline = typeof window !== "undefined" && !window.navigator.onLine;
this._paused = false;
this.success = false;
this.nextChunkRangeStart = 0;
if (options.useLargeFileWorkaround) {
const readableStreamErrorCallback = (event) => {
if (this.chunkedIterable.error) {
console.warn(`Unable to read file of size ${this.file.size} bytes via a ReadableStream. Falling back to in-memory FileReader!`);
event.stopImmediatePropagation();
this.chunkedIterable = new ChunkedFileIterable(this.file, {
...options,
defaultChunkSize: options.chunkSize
});
this.chunkedIterator = this.chunkedIterable[Symbol.asyncIterator]();
this.getEndpoint().then(() => {
this.sendChunks();
}).catch((e) => {
const message = (e == null ? void 0 : e.message) ? `: ${e.message}` : "";
this.dispatch("error", {
message: `Failed to get endpoint${message}`
});
});
this.off("error", readableStreamErrorCallback);
}
};
this.on("error", readableStreamErrorCallback);
}
this.chunkedIterable = new ChunkedStreamIterable(this.file.stream(), { ...options, defaultChunkSize: options.chunkSize });
this.chunkedIterator = this.chunkedIterable[Symbol.asyncIterator]();
this.totalChunks = Math.ceil(this.file.size / this.chunkByteSize);
this.validateOptions();
this.getEndpoint().then(() => this.sendChunks()).catch((e) => {
const message = (e == null ? void 0 : e.message) ? `: ${e.message}` : "";
this.dispatch("error", {
message: `Failed to get endpoint${message}`
});
});
if (typeof window !== "undefined") {
window.addEventListener("online", () => {
if (!this.offline)
return;
this._offline = false;
this.dispatch("online");
this.sendChunks();
});
window.addEventListener("offline", () => {
if (this.offline)
return;
this._offline = true;
this.dispatch("offline");
});
}
}
get maxChunkSize() {
var _a, _b;
return (_b = (_a = this.chunkedIterable) == null ? void 0 : _a.maxChunkSize) != null ? _b : DEFAULT_MAX_CHUNK_SIZE;
}
get minChunkSize() {
var _a, _b;
return (_b = (_a = this.chunkedIterable) == null ? void 0 : _a.minChunkSize) != null ? _b : DEFAULT_MIN_CHUNK_SIZE;
}
get chunkSize() {
var _a, _b;
return (_b = (_a = this.chunkedIterable) == null ? void 0 : _a.chunkSize) != null ? _b : DEFAULT_CHUNK_SIZE;
}
set chunkSize(value) {
this.chunkedIterable.chunkSize = value;
}
get chunkByteSize() {
return this.chunkedIterable.chunkByteSize;
}
get totalChunkSize() {
return Math.ceil(this.file.size / this.chunkByteSize);
}
on(eventName, fn) {
this.eventTarget.addEventListener(eventName, fn);
}
once(eventName, fn) {
this.eventTarget.addEventListener(eventName, fn, {
once: true
});
}
off(eventName, fn) {
this.eventTarget.removeEventListener(eventName, fn);
}
get offline() {
return this._offline;
}
get paused() {
return this._paused;
}
abort() {
var _a;
this.pause();
(_a = this.currentXhr) == null ? void 0 : _a.abort();
}
pause() {
this._paused = true;
}
resume() {
if (this._paused) {
this._paused = false;
this.sendChunks();
}
}
get successfulPercentage() {
return this.nextChunkRangeStart / this.file.size;
}
dispatch(eventName, detail) {
const event = new CustomEvent(eventName, {
detail
});
this.eventTarget.dispatchEvent(event);
}
validateOptions() {
if (!this.endpoint || typeof this.endpoint !== "function" && typeof this.endpoint !== "string") {
throw new TypeError("endpoint must be defined as a string or a function that returns a promise");
}
if (!(this.file instanceof File)) {
throw new TypeError("file must be a File object");
}
if (this.headers && typeof this.headers !== "function" && typeof this.headers !== "object") {
throw new TypeError("headers must be null, an object, or a function that returns an object or a promise");
}
if (!isValidChunkSize(this.chunkSize, {
maxChunkSize: this.maxChunkSize,
minChunkSize: this.minChunkSize
})) {
throw getChunkSizeError(this.chunkSize, {
maxChunkSize: this.maxChunkSize,
minChunkSize: this.minChunkSize
});
}
if (this.maxChunkSize && (typeof this.maxChunkSize !== "number" || this.maxChunkSize < 256 || this.maxChunkSize % 256 !== 0 || this.maxChunkSize < this.chunkSize || this.maxChunkSize < this.minChunkSize)) {
throw new TypeError(`maxChunkSize must be a positive number in multiples of 256, and larger than or equal to both ${this.minChunkSize} and ${this.chunkSize}`);
}
if (this.minChunkSize && (typeof this.minChunkSize !== "number" || this.minChunkSize < 256 || this.minChunkSize % 256 !== 0 || this.minChunkSize > this.chunkSize || this.minChunkSize > this.maxChunkSize)) {
throw new TypeError(`minChunkSize must be a positive number in multiples of 256, and smaller than ${this.chunkSize} and ${this.maxChunkSize}`);
}
if (this.maxFileBytes > 0 && this.maxFileBytes < this.file.size) {
throw new Error(`file size exceeds maximum (${this.file.size} > ${this.maxFileBytes})`);
}
if (this.attempts && (typeof this.attempts !== "number" || this.attempts <= 0)) {
throw new TypeError("retries must be a positive number");
}
if (this.delayBeforeAttempt && (typeof this.delayBeforeAttempt !== "number" || this.delayBeforeAttempt < 0)) {
throw new TypeError("delayBeforeAttempt must be a positive number");
}
}
getEndpoint() {
if (typeof this.endpoint === "string") {
this.endpointValue = this.endpoint;
return Promise.resolve(this.endpoint);
}
return this.endpoint(this.file).then((value) => {
this.endpointValue = value;
if (typeof value !== "string") {
throw new TypeError("endpoint must return a string");
}
return this.endpointValue;
});
}
xhrPromise(options) {
const beforeSend = (xhrObject) => {
xhrObject.upload.onprogress = (event) => {
var _a;
const remainingChunks = this.totalChunks - this.chunkCount;
const percentagePerChunk = (this.file.size - this.nextChunkRangeStart) / this.file.size / remainingChunks;
const currentChunkProgress = event.loaded / ((_a = event.total) != null ? _a : this.chunkByteSize);
const chunkPercentage = currentChunkProgress * percentagePerChunk;
this.dispatch("progress", Math.min((this.successfulPercentage + chunkPercentage) * 100, 100));
};
};
return new Promise((resolve, reject) => {
this.currentXhr = (0, import_xhr.default)({ ...options, beforeSend }, (err, resp) => {
this.currentXhr = void 0;
if (err) {
return reject(err);
}
return resolve(resp);
});
});
}
async sendChunk(chunk) {
const rangeStart = this.nextChunkRangeStart;
const rangeEnd = rangeStart + chunk.size - 1;
const extraHeaders = await (typeof this.headers === "function" ? this.headers() : this.headers);
const headers = {
...extraHeaders,
"Content-Type": this.file.type,
"Content-Range": `bytes ${rangeStart}-${rangeEnd}/${this.file.size}`
};
this.dispatch("attempt", {
chunkNumber: this.chunkCount,
totalChunks: this.totalChunks,
chunkSize: this.chunkSize
});
return this.xhrPromise({
headers,
url: this.endpointValue,
method: this.method,
body: chunk
});
}
async sendChunkWithRetries(chunk) {
const successfulChunkUploadCb = async (res2, _chunk) => {
var _a;
const lastChunkEnd = new Date();
const lastChunkInterval = (lastChunkEnd.getTime() - this.lastChunkStart.getTime()) / 1e3;
this.dispatch("chunkSuccess", {
chunk: this.chunkCount,
chunkSize: this.chunkSize,
attempts: this.attemptCount,
timeInterval: lastChunkInterval,
response: res2
});
this.attemptCount = 0;
this.chunkCount = ((_a = this.chunkCount) != null ? _a : 0) + 1;
this.nextChunkRangeStart = this.nextChunkRangeStart + this.chunkByteSize;
if (this.dynamicChunkSize) {
let unevenChunkSize = this.chunkSize;
if (lastChunkInterval < 10) {
unevenChunkSize = Math.min(this.chunkSize * 2, this.maxChunkSize);
} else if (lastChunkInterval > 30) {
unevenChunkSize = Math.max(this.chunkSize / 2, this.minChunkSize);
}
this.chunkSize = Math.ceil(unevenChunkSize / 256) * 256;
const remainingChunks = (this.file.size - this.nextChunkRangeStart) / this.chunkByteSize;
this.totalChunks = Math.ceil(this.chunkCount + remainingChunks);
}
return true;
};
const failedChunkUploadCb = async (res2, _chunk) => {
this.dispatch("progress", Math.min(this.successfulPercentage * 100, 100));
this.dispatch("error", {
message: `Server responded with ${res2.statusCode}. Stopping upload.`,
chunk: this.chunkCount,
attempts: this.attemptCount,
response: res2
});
return false;
};
const retriableChunkUploadCb = async (res2, _chunk) => {
this.dispatch("attemptFailure", {
message: `An error occured uploading chunk ${this.chunkCount}. ${this.attempts - this.attemptCount} retries left.`,
chunkNumber: this.chunkCount,
attemptsLeft: this.attempts - this.attemptCount,
response: res2
});
return new Promise((resolve) => {
setTimeout(async () => {
if (this._paused || this.offline) {
this.pendingChunk = chunk;
resolve(false);
return;
}
const chunkUploadSuccess = await this.sendChunkWithRetries(chunk);
resolve(chunkUploadSuccess);
}, this.delayBeforeAttempt * 1e3);
});
};
let res;
try {
this.attemptCount = this.attemptCount + 1;
this.lastChunkStart = new Date();
res = await this.sendChunk(chunk);
} catch (err) {
if (typeof (err == null ? void 0 : err.statusCode) === "number") {
res = err;
}
}
const options = {
retryCodes: this.retryCodes,
attemptCount: this.attemptCount,
attempts: this.attempts,
currentChunkEndByte: this.nextChunkRangeStart + chunk.size - 1
};
if (isIncompleteChunkUploadNeedingRetry(res, options)) {
return retriableChunkUploadCb(res, chunk);
}
if (isSuccessfulChunkUpload(res, options)) {
return successfulChunkUploadCb(res, chunk);
}
if (isFailedChunkUpload(res, options)) {
return failedChunkUploadCb(res, chunk);
}
return retriableChunkUploadCb(res, chunk);
}
async sendChunks() {
if (this.pendingChunk && !(this._paused || this.offline)) {
const chunk = this.pendingChunk;
this.pendingChunk = void 0;
const chunkUploadSuccess = await this.sendChunkWithRetries(chunk);
if (this.success && chunkUploadSuccess) {
this.dispatch("success");
}
}
while (!(this.success || this._paused || this.offline)) {
const { value: chunk, done } = await this.chunkedIterator.next();
let chunkUploadSuccess = !chunk && done;
if (chunk) {
chunkUploadSuccess = await this.sendChunkWithRetries(chunk);
}
if (this.chunkedIterable.error) {
chunkUploadSuccess = false;
this.dispatch("error", {
message: `Unable to read file of size ${this.file.size} bytes. Try loading from another browser.`
});
return;
}
this.success = !!done;
if (this.success && chunkUploadSuccess) {
this.dispatch("success");
}
if (!chunkUploadSuccess) {
return;
}
}
}
};
function createUpload(options) {
return UpChunk.createUpload(options);
}
export {
ChunkedFileIterable,
ChunkedStreamIterable,
UpChunk,
createUpload,
getChunkSizeError,
isIncompleteChunkUploadNeedingRetry,
isValidChunkSize
};
//# sourceMappingURL=upchunk.mjs.map