UNPKG

curvature

Version:

![avatar](https://avatars3.githubusercontent.com/u/640101?s=80&v=4)

568 lines (567 loc) 19.2 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } Object.defineProperty(exports, "__esModule", { value: true }); exports.Elicit = void 0; var _Mixin = require("curvature/base/Mixin"); var _EventTargetMixin = require("curvature/mixin/EventTargetMixin"); var _PromiseMixin = require("curvature/mixin/PromiseMixin"); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } var IterateDownload = Symbol('IterateDownload'); var Retry = Symbol('Retry'); var HandleFirstByte = Symbol('HandleFirstByte'); var HandleProgress = Symbol('HandleProgress'); var HandleComplete = Symbol('HandleComplete'); var HandleHeaders = Symbol('HandleHeaders'); var HandleClose = Symbol('HandleClose'); var HandleError = Symbol('HandleError'); var HandleOpen = Symbol('HandleOpen'); var HandleFail = Symbol('HandleFail'); var LastChunkSize = Symbol('LastChunkSize'); var LastChunkTime = Symbol('LastChunkTime'); var Options = Symbol('Options'); var Fetch = Symbol('Fetch'); var Type = Symbol('Type'); var Url = Symbol('Url'); var RetriesLeft = Symbol('RetriesLeft'); var TimeoutLeft = Symbol('TimeoutLeft'); var Timeout = Symbol('Timeout'); var Timer = Symbol('Timer'); var Canceller = Symbol('Canecller'); var Cancelled = Symbol('Caneclled'); var Paused = Symbol('Paused'); var Received = Symbol('Received'); var Length = Symbol('Length'); var Opened = Symbol('Opened'); var Closed = Symbol('Closed'); var Start = Symbol('Start'); var First = Symbol('First'); var End = Symbol('End'); var Elicit = /*#__PURE__*/function (_Mixin$with) { _inherits(Elicit, _Mixin$with); var _super = _createSuper(Elicit); function Elicit(url) { var _this2; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; _classCallCheck(this, Elicit); _this2 = _super.call(this); _this2[RetriesLeft] = options.retries || 5; _this2[Timeout] = options.timeout || 4500; _this2[TimeoutLeft] = options.maxTimeout || _this2[Timeout] * _this2[RetriesLeft]; _this2[LastChunkTime] = 0; _this2[LastChunkSize] = 0; _this2[Cancelled] = false; _this2[Received] = 0; _this2[Paused] = false; _this2[Closed] = 0; _this2[Options] = Object.assign({}, options); _this2[Url] = url; if (!options.defer) { _this2.open(); } return _this2; } _createClass(Elicit, [{ key: "open", value: function open() { var _this3 = this; if (this[Opened] && !this[Closed]) { return; } if (!this[Start]) { this[Start] = Date.now(); } this[Canceller] = new AbortController(); this[Options].signal = this[Canceller].signal; this[Opened] = Date.now(); this[Closed] = 0; this[First] = 0; this[Fetch] = fetch(this[Url], this[Options]).then(function (response) { return _this3[HandleOpen](response); })["catch"](function (error) { return _this3[HandleError](error); }); var onTimeout = function onTimeout() { if (!_this3[First]) { _this3[Canceller].abort(); _this3[HandleClose](); _this3[TimeoutLeft] = Math.max(0, _this3[TimeoutLeft] - _this3[Timeout]); if (!_this3[TimeoutLeft]) { return; } _this3[HandleFail](new Error('Timed out.')); } }; this[Timer] = setTimeout(onTimeout, this[Timeout]); } }, { key: "headers", value: function headers() { return this[Fetch].then(function (_ref) { var response = _ref.response, stream = _ref.stream; return response.headers; }); } }, { key: "json", value: function json() { var _this4 = this; return this[Fetch].then(function (_ref2) { var response = _ref2.response, stream = _ref2.stream; var wrapped = new Response(stream, { headers: { 'Content-Type': _this4.type } }); return wrapped.json(); }); } }, { key: "text", value: function text() { var _this5 = this; return this[Fetch].then(function (_ref3) { var response = _ref3.response, stream = _ref3.stream; var wrapped = new Response(stream, { headers: { 'Content-Type': _this5.type } }); return wrapped.text(); }); } }, { key: "css", value: function css() { return this.text().then(function (css) { var sheet = new CSSStyleSheet(); sheet.replace(css); return sheet; }); } }, { key: "blob", value: function blob() { var _this6 = this; return this[Fetch].then(function (_ref4) { var response = _ref4.response, stream = _ref4.stream; var wrapped = new Response(stream, { headers: { 'Content-Type': _this6.type } }); return wrapped.blob(); }); } }, { key: "objectUrl", value: function objectUrl() { return this.blob().then(function (blob) { return URL.createObjectURL(blob); }); } }, { key: "dataUri", value: function dataUri() { return this.blob().then(function (blob) { return new Promise(function (accept, reject) { var reader = new FileReader(); reader.onload = function (event) { return accept(reader.result); }; reader.onerror = function (event) { return reject(reader.error); }; reader.onabort = function (event) { return reject(new Error("Read aborted")); }; reader.readAsDataURL(blob); }); }); } }, { key: "buffer", value: function buffer() { return this.blob().then(function (blob) { return blob.arrayBuffer(); }); } }, { key: "bytes", value: function bytes() { return this.buffer().then(function (buffer) { return new Uint8Array(buffer); }); } }, { key: "cancel", value: function cancel() { if (!this.emitCancelEvent()) { return; } this[Canceller].abort(); this[Cancelled] = true; this.emitCancelledEvent(); } }, { key: "pause", value: function pause() { if (this[End] || this[Paused] || this[Closed]) { return; } if (!this.emitPauseEvent()) { return; } this[Paused] = true; this.emitPausedEvent(); } }, { key: "unpause", value: function unpause() { if (this[End] || !this[Paused]) { return; } if (!this.emitUnpauseEvent()) { return; } this[Paused] = false; this.emitUnpausedEvent(); } }, { key: "done", get: function get() { return !!this[End]; } }, { key: "type", get: function get() { return this[Type]; } }, { key: "totalTime", get: function get() { if (!this[End]) { return Date.now() - this[Start]; } return this[End] - this[Start]; } }, { key: "waitTime", get: function get() { if (!this[First]) { return Date.now() - this[Opened]; } return this[First] - this[Opened]; } }, { key: "loadTime", get: function get() { if (!this[Opened]) { return 0; } if (!this[Closed]) { return Date.now() - this[First]; } return this[Closed] - this[First]; } }, { key: "speed", get: function get() { if (!this[Opened]) { return 0; } var time; if (this[End]) { time = this[End] - this[LastChunkTime]; } else { time = Date.now() - this[LastChunkTime]; } if (!time) { time = 0.01; } return this[LastChunkSize] / time; } }, { key: "received", get: function get() { return this[Received]; } }, { key: "length", get: function get() { return this[Length]; } }, { key: "isPaused", get: function get() { return this[Paused]; } }, { key: IterateDownload, value: function value(reader, controller, length) { var _this7 = this; this[HandleProgress](length, 0, null); var lastTime = Date.now(); var lastSize = 1; var handleChunk = function handleChunk(_ref5) { var done = _ref5.done, value = _ref5.value; if (done) { controller.close(); return _this7[HandleComplete](); } controller.enqueue(value); _this7[Received] += value.length; if (!_this7[First]) { _this7[HandleFirstByte](value); } _this7[HandleProgress](length, _this7[Received]); _this7[LastChunkTime] = lastTime; _this7[LastChunkSize] = lastSize; lastTime = Date.now(); lastSize = value.length; return iterate(); }; var iterate = function iterate() { if (_this7[Cancelled]) { return reader.cancel(); } if (_this7[Paused]) { return new Promise(function (accept) { setTimeout(function () { return accept(iterate()); }, 100); }); } return reader.read().then(function (chunk) { return handleChunk(chunk); })["catch"](function (error) { return _this7[HandleError](error); }); }; return iterate(); } }, { key: Retry, value: function value() { if (!this.emitRetryEvent()) { return; } if (this[RetriesLeft] <= 0) { return; } this[Canceller].abort(); this[HandleClose](); this[Received] = 0; this[RetriesLeft]--; return this.open(); } }, { key: HandleOpen, value: function value(response) { var reader = response.body.getReader(); var length = this[Length] || Number(response.headers.get('Content-Length')); var type = this[type] || response.headers.get('Content-Type'); this[Length] = length; this[Type] = type; this[HandleHeaders](response.headers); var _this = this; var stream = new ReadableStream({ start: function start(controller) { _this[IterateDownload](reader, controller, length); } }); return { response: response, stream: stream }; } }, { key: HandleClose, value: function value() { this[Closed] = Date.now(); this.emitCloseEvent(); } }, { key: HandleHeaders, value: function value(headers) { this.emitHeadersEvent(headers); } }, { key: HandleProgress, value: function value(length, received, _value) { this.emitProgressEvent(length, received, _value); } }, { key: HandleComplete, value: function value() { this[End] = Date.now(); this[HandleClose](); this.emitCompleteEvent(); this[_PromiseMixin.PromiseMixin.Accept](); } }, { key: HandleError, value: function value(error) { console.warn(error); if (!this.emitErrorEvent(error)) { return this[Retry](); } return this[HandleFail](error); } }, { key: HandleFail, value: function value(error) { this[End] = Date.now(); this[HandleClose](); this.emitFailEvent(error); return this[_PromiseMixin.PromiseMixin.Reject](error); } }, { key: HandleFirstByte, value: function value(received) { clearInterval(this[Timer]); this[First] = Date.now(); this.emitFirstByteEvent(received); } }, { key: "emitProgressEvent", value: function emitProgressEvent(length, received, value) { var done = length ? received / length : 0; var totalTime = this.totalTime; var loadTime = this.loadTime; var waitTime = this.waitTime; var speed = this.speed; return this.dispatchEvent(new CustomEvent('progress', { detail: { length: length, received: received, done: done, speed: speed, loadTime: loadTime, waitTime: waitTime, totalTime: totalTime, value: value } })); } }, { key: "emitOpenEvent", value: function emitOpenEvent() { return this.dispatchEvent(new CustomEvent('open')); } }, { key: "emitCloseEvent", value: function emitCloseEvent() { return this.dispatchEvent(new CustomEvent('close')); } }, { key: "emitFirstByteEvent", value: function emitFirstByteEvent(received) { return this.dispatchEvent(new CustomEvent('firstByte', { detail: { received: received } })); } }, { key: "emitHeadersEvent", value: function emitHeadersEvent(headers) { return this.dispatchEvent(new CustomEvent('headers', { detail: { headers: headers } })); } }, { key: "emitCompleteEvent", value: function emitCompleteEvent() { return this.dispatchEvent(new CustomEvent('complete')); } }, { key: "emitErrorEvent", value: function emitErrorEvent() { return this.dispatchEvent(new CustomEvent('error', { cancelable: this[RetriesLeft] > 0 })); } }, { key: "emitRetryEvent", value: function emitRetryEvent() { return this.dispatchEvent(new CustomEvent('retry', { cancelable: true })); } }, { key: "emitFailEvent", value: function emitFailEvent() { return this.dispatchEvent(new CustomEvent('fail')); } }, { key: "emitPauseEvent", value: function emitPauseEvent() { return this.dispatchEvent(new CustomEvent('pause', { cancelable: true })); } }, { key: "emitPausedEvent", value: function emitPausedEvent() { this.dispatchEvent(new CustomEvent('paused')); } }, { key: "emitUnpauseEvent", value: function emitUnpauseEvent() { return this.dispatchEvent(new CustomEvent('unpause', { cancelable: true })); } }, { key: "emitUnpausedEvent", value: function emitUnpausedEvent() { this.dispatchEvent(new CustomEvent('unpaused')); } }, { key: "emitCancelEvent", value: function emitCancelEvent() { return this.dispatchEvent(new CustomEvent('cancel', { cancelable: true })); } }, { key: "emitCancelledEvent", value: function emitCancelledEvent() { return this.dispatchEvent(new CustomEvent('cancelled')); } }]); return Elicit; }(_Mixin.Mixin["with"](_EventTargetMixin.EventTargetMixin, _PromiseMixin.PromiseMixin)); // elicit.addEventListener('open', event => console.log(event)); // elicit.addEventListener('close', event => console.log(event)); // elicit.addEventListener('firstByte', event => console.log(event)); // elicit.addEventListener('headers', event => console.log(event)); // elicit.addEventListener('complete', event => console.log(event)); // elicit.addEventListener('error', event => console.log(event)); // elicit.addEventListener('fail', event => console.log(event)); // elicit.addEventListener('pause', event => console.log(event)); // elicit.addEventListener('paused', event => console.log(event)); // elicit.addEventListener('unpause', event => console.log(event)); // elicit.addEventListener('unpaused', event => console.log(event)); // elicit.addEventListener('cancelled', event => console.log(event)); // elicit.addEventListener('cancel', event => console.log(event)); exports.Elicit = Elicit;