Socket
Socket
Sign inDemoInstall

asset-preloader

Package Overview
Dependencies
1
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.3 to 0.1.4

dist/lib/events.d.ts

288

dist/asset-preloader.cjs.development.js

@@ -7,102 +7,64 @@ 'use strict';

function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return target;
};
return arr2;
return _extends.apply(this, arguments);
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
if (it) return (it = it.call(o)).next.bind(it);
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var getItemByUrl = function getItemByUrl(context) {
var getItemByUrl = function getItemByUrl(items) {
return function (url) {
for (var _iterator = _createForOfIteratorHelperLoose(context.state), _step; !(_step = _iterator()).done;) {
var item = _step.value;
if (item.url == url) return item;
}
return null;
return items.find(function (item) {
return item.url === url;
});
};
};
var cancel = function cancel(context) {
return function () {
for (var _iterator2 = _createForOfIteratorHelperLoose(context.state), _step2; !(_step2 = _iterator2()).done;) {
var item = _step2.value;
if (item.completion < 1) {
item.xhr.abort();
item.status = 0;
}
}
var getTotalProgress = function getTotalProgress(items) {
var maxProgress = items.length;
var sumProgress = items.reduce(function (acc, itemState) {
return itemState.progress ? acc + itemState.progress : acc;
}, 0);
var totalProgress = sumProgress / maxProgress;
return totalProgress;
};
context.onCancel(context.state);
return context.state;
var preloadAsset = function preloadAsset(_ref) {
var url = _ref.url,
onProgress = _ref.onProgress,
onComplete = _ref.onComplete,
onError = _ref.onError,
_ref$responseType = _ref.responseType,
responseType = _ref$responseType === void 0 ? 'blob' : _ref$responseType;
var asset = {
url: url
};
};
var updateProgress = function updateProgress(context) {
return function (item) {
var sumCompletion = 0;
var maxCompletion = context.state.length;
for (var _iterator3 = _createForOfIteratorHelperLoose(context.state), _step3; !(_step3 = _iterator3()).done;) {
var itemState = _step3.value;
if (itemState.completion) {
sumCompletion += itemState.completion;
}
}
var totalCompletion = sumCompletion / maxCompletion;
if (!isNaN(totalCompletion)) {
context.onProgress({
progress: totalCompletion,
item: item
});
}
};
};
var preloadItem = function preloadItem(context) {
return function (url, done) {
var request = function request() {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
var item = getItemByUrl(context)(url);
item.xhr = xhr;
xhr.open('GET', asset.url, true);
xhr.responseType = responseType;
asset.xhr = xhr;
xhr.onprogress = function (event) {
if (event.lengthComputable) {
item.completion = event.loaded / event.total;
item.downloaded = event.loaded;
item.total = event.total;
updateProgress(context)(item);
asset.progress = event.loaded / event.total;
asset.downloaded = event.loaded;
asset.total = event.total;
onProgress({
progress: asset.progress,
event: event,
asset: asset
});
}

@@ -117,10 +79,10 @@ };

var responseURL = event.target.responseURL;
item.fileName = responseURL.substring(responseURL.lastIndexOf('/') + 1);
item.type = type;
item.status = xhr.status;
asset.fileName = responseURL.substring(responseURL.lastIndexOf('/') + 1);
asset.type = type;
asset.status = xhr.status;
if (xhr.status == 404) {
item.blobUrl = item.size = null;
item.error = true;
context.onError(item);
asset.blobUrl = asset.size = null;
asset.error = true;
onError(asset);
} else {

@@ -132,8 +94,8 @@ // TODO: fix

});
item.blobUrl = URL.createObjectURL(blob);
item.size = blob.size;
item.error = false;
asset.blobUrl = URL.createObjectURL(blob);
asset.size = blob.size;
asset.error = false;
}
done(item);
onComplete(asset);
};

@@ -143,64 +105,100 @@

};
request();
return asset;
};
var fetch = function fetch(context) {
return function (urls) {
return new Promise(function (resolve) {
context.loaded = urls.length;
for (var _iterator4 = _createForOfIteratorHelperLoose(urls), _step4; !(_step4 = _iterator4()).done;) {
var itemUrl = _step4.value;
// the item isn't a full StateItem yet but for the sake of simplicity we just cast
context.state.push({
url: itemUrl
});
preloadItem(context)(itemUrl, function (loadedItem) {
context.onFetched(loadedItem);
context.loaded--;
if (context.loaded == 0) {
context.onComplete(context.state);
resolve(context.state);
}
});
}
});
var createEvents = function createEvents() {
return {
onProgress: lightcast.createPubSub(),
onComplete: lightcast.createPubSub(),
onFetched: lightcast.createPubSub(),
onError: lightcast.createPubSub(),
onCancel: lightcast.createPubSub()
};
};
var createPreloader = function createPreloader() {
var onProgress = lightcast.createPubSub();
var onComplete = lightcast.createPubSub();
var onFetched = lightcast.createPubSub();
var onError = lightcast.createPubSub();
var onCancel = lightcast.createPubSub();
var context = {
state: [],
loaded: 0,
onProgress: onProgress.dispatch,
onComplete: onComplete.dispatch,
onFetched: onFetched.dispatch,
onError: onError.dispatch,
onCancel: onCancel.dispatch
var events = createEvents();
var assets = [];
var assetsToLoad = 0;
var pending = [];
var start = function start() {
pending.forEach(function (pendingAsset) {
assets.push(pendingAsset());
});
pending.length = 0;
};
var cancel = function cancel() {
assets.forEach(function (item) {
if (item.progress < 1) {
item.xhr.abort();
item.status = 0;
}
});
events.onCancel.dispatch(assets);
};
var dispose = function dispose() {
cancel(context)();
onProgress.dispose();
onComplete.dispose();
onFetched.dispose();
onError.dispose();
onCancel.dispose();
cancel();
Object.values(events).forEach(function (_ref) {
var dispose = _ref.dispose;
return dispose();
});
};
var load = function load(url, _temp) {
var _ref2 = _temp === void 0 ? {} : _temp,
responseType = _ref2.responseType,
_ref2$onProgress = _ref2.onProgress,
_onProgress = _ref2$onProgress === void 0 ? function () {} : _ref2$onProgress;
return new Promise(function (resolve, reject) {
assetsToLoad++;
var loadAsset = function loadAsset() {
return preloadAsset({
url: url,
responseType: responseType,
onProgress: function onProgress(payload) {
events.onProgress.dispatch(_extends({}, payload, {
progress: getTotalProgress(assets)
}));
_onProgress(payload);
},
onError: function onError(item) {
reject();
events.onError.dispatch(item);
},
onComplete: function onComplete(asset) {
events.onFetched.dispatch(asset);
resolve(asset);
assetsToLoad--;
if (assetsToLoad === 0) {
events.onComplete.dispatch(assets);
dispose();
}
}
});
};
pending.push(loadAsset);
});
};
return {
fetch: fetch(context),
updateProgress: updateProgress(context),
preloadItem: preloadItem(context),
getItemByUrl: getItemByUrl(context),
cancel: cancel(context),
onProgress: onProgress.subscribe,
onComplete: onComplete.subscribe,
onFetched: onFetched.subscribe,
onError: onError.subscribe,
onCancel: onCancel.subscribe,
dispose: dispose
load: load,
start: start,
cancel: cancel,
dispose: dispose,
getItemByUrl: getItemByUrl(assets),
onCancel: events.onCancel.subscribe,
onProgress: events.onProgress.subscribe,
onComplete: events.onComplete.subscribe,
onFetched: events.onFetched.subscribe,
onError: events.onError.subscribe
};

@@ -207,0 +205,0 @@ };

@@ -1,2 +0,2 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("lightcast");function t(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,o=new Array(t);r<t;r++)o[r]=e[r];return o}function r(e,r){var o="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(o)return(o=o.call(e)).next.bind(o);if(Array.isArray(e)||(o=function(e,r){if(e){if("string"==typeof e)return t(e,void 0);var o=Object.prototype.toString.call(e).slice(8,-1);return"Object"===o&&e.constructor&&(o=e.constructor.name),"Map"===o||"Set"===o?Array.from(e):"Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?t(e,void 0):void 0}}(e))||r&&e&&"number"==typeof e.length){o&&(e=o);var n=0;return function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o=function(e){return function(t){for(var o,n=r(e.state);!(o=n()).done;){var a=o.value;if(a.url==t)return a}return null}},n=function(e){return function(){for(var t,o=r(e.state);!(t=o()).done;){var n=t.value;n.completion<1&&(n.xhr.abort(),n.status=0)}return e.onCancel(e.state),e.state}},a=function(e){return function(t){for(var o,n=0,a=e.state.length,s=r(e.state);!(o=s()).done;){var u=o.value;u.completion&&(n+=u.completion)}var i=n/a;isNaN(i)||e.onProgress({progress:i,item:t})}},s=function(e){return function(t,r){var n=new XMLHttpRequest;n.open("GET",t,!0),n.responseType="blob";var s=o(e)(t);s.xhr=n,n.onprogress=function(t){t.lengthComputable&&(s.completion=t.loaded/t.total,s.downloaded=t.loaded,s.total=t.total,a(e)(s))},n.onload=function(t){var o=t.target.response.type,a=t.target.responseURL;if(s.fileName=a.substring(a.lastIndexOf("/")+1),s.type=o,s.status=n.status,404==n.status)s.blobUrl=s.size=null,s.error=!0,e.onError(s);else{var u=new Blob([t.target.response],{type:o});s.blobUrl=URL.createObjectURL(u),s.size=u.size,s.error=!1}r(s)},n.send()}},u=function(e){return function(t){return new Promise((function(o){e.loaded=t.length;for(var n,a=r(t);!(n=a()).done;){var u=n.value;e.state.push({url:u}),s(e)(u,(function(t){e.onFetched(t),e.loaded--,0==e.loaded&&(e.onComplete(e.state),o(e.state))}))}}))}};exports.createPreloader=function(){var t=e.createPubSub(),r=e.createPubSub(),i=e.createPubSub(),l=e.createPubSub(),c=e.createPubSub(),d={state:[],loaded:0,onProgress:t.dispatch,onComplete:r.dispatch,onFetched:i.dispatch,onError:l.dispatch,onCancel:c.dispatch};return{fetch:u(d),updateProgress:a(d),preloadItem:s(d),getItemByUrl:o(d),cancel:n(d),onProgress:t.subscribe,onComplete:r.subscribe,onFetched:i.subscribe,onError:l.subscribe,onCancel:c.subscribe,dispose:function(){n(d)(),t.dispose(),r.dispose(),i.dispose(),l.dispose(),c.dispose()}}};
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("lightcast");function r(){return(r=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var o=arguments[r];for(var n in o)Object.prototype.hasOwnProperty.call(o,n)&&(e[n]=o[n])}return e}).apply(this,arguments)}exports.createPreloader=function(){var o,n={onProgress:e.createPubSub(),onComplete:e.createPubSub(),onFetched:e.createPubSub(),onError:e.createPubSub(),onCancel:e.createPubSub()},t=[],s=0,u=[],c=function(){t.forEach((function(e){e.progress<1&&(e.xhr.abort(),e.status=0)})),n.onCancel.dispatch(t)},a=function(){c(),Object.values(n).forEach((function(e){return(0,e.dispose)()}))};return{load:function(e,o){var c=void 0===o?{}:o,i=c.responseType,l=c.onProgress,p=void 0===l?function(){}:l;return new Promise((function(o,c){s++,u.push((function(){return function(e){var r,o=e.onProgress,n=e.onComplete,t=e.onError,s=e.responseType,u=void 0===s?"blob":s,c={url:e.url};return(r=new XMLHttpRequest).open("GET",c.url,!0),r.responseType=u,c.xhr=r,r.onprogress=function(e){e.lengthComputable&&(c.progress=e.loaded/e.total,c.downloaded=e.loaded,c.total=e.total,o({progress:c.progress,event:e,asset:c}))},r.onload=function(e){var o=e.target.response.type,s=e.target.responseURL;if(c.fileName=s.substring(s.lastIndexOf("/")+1),c.type=o,c.status=r.status,404==r.status)c.blobUrl=c.size=null,c.error=!0,t(c);else{var u=new Blob([e.target.response],{type:o});c.blobUrl=URL.createObjectURL(u),c.size=u.size,c.error=!1}n(c)},r.send(),c}({url:e,responseType:i,onProgress:function(e){var o,s;n.onProgress.dispatch(r({},e,{progress:(o=t,s=o.length,o.reduce((function(e,r){return r.progress?e+r.progress:e}),0)/s)})),p(e)},onError:function(e){c(),n.onError.dispatch(e)},onComplete:function(e){n.onFetched.dispatch(e),o(e),0==--s&&(n.onComplete.dispatch(t),a())}})}))}))},start:function(){u.forEach((function(e){t.push(e())})),u.length=0},cancel:c,dispose:a,getItemByUrl:(o=t,function(e){return o.find((function(r){return r.url===e}))}),onCancel:n.onCancel.subscribe,onProgress:n.onProgress.subscribe,onComplete:n.onComplete.subscribe,onFetched:n.onFetched.subscribe,onError:n.onError.subscribe}};
//# sourceMappingURL=asset-preloader.cjs.production.min.js.map
import { createPubSub } from 'lightcast';
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return target;
};
return arr2;
return _extends.apply(this, arguments);
}
function _createForOfIteratorHelperLoose(o, allowArrayLike) {
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
if (it) return (it = it.call(o)).next.bind(it);
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var getItemByUrl = function getItemByUrl(context) {
var getItemByUrl = function getItemByUrl(items) {
return function (url) {
for (var _iterator = _createForOfIteratorHelperLoose(context.state), _step; !(_step = _iterator()).done;) {
var item = _step.value;
if (item.url == url) return item;
}
return null;
return items.find(function (item) {
return item.url === url;
});
};
};
var cancel = function cancel(context) {
return function () {
for (var _iterator2 = _createForOfIteratorHelperLoose(context.state), _step2; !(_step2 = _iterator2()).done;) {
var item = _step2.value;
if (item.completion < 1) {
item.xhr.abort();
item.status = 0;
}
}
var getTotalProgress = function getTotalProgress(items) {
var maxProgress = items.length;
var sumProgress = items.reduce(function (acc, itemState) {
return itemState.progress ? acc + itemState.progress : acc;
}, 0);
var totalProgress = sumProgress / maxProgress;
return totalProgress;
};
context.onCancel(context.state);
return context.state;
var preloadAsset = function preloadAsset(_ref) {
var url = _ref.url,
onProgress = _ref.onProgress,
onComplete = _ref.onComplete,
onError = _ref.onError,
_ref$responseType = _ref.responseType,
responseType = _ref$responseType === void 0 ? 'blob' : _ref$responseType;
var asset = {
url: url
};
};
var updateProgress = function updateProgress(context) {
return function (item) {
var sumCompletion = 0;
var maxCompletion = context.state.length;
for (var _iterator3 = _createForOfIteratorHelperLoose(context.state), _step3; !(_step3 = _iterator3()).done;) {
var itemState = _step3.value;
if (itemState.completion) {
sumCompletion += itemState.completion;
}
}
var totalCompletion = sumCompletion / maxCompletion;
if (!isNaN(totalCompletion)) {
context.onProgress({
progress: totalCompletion,
item: item
});
}
};
};
var preloadItem = function preloadItem(context) {
return function (url, done) {
var request = function request() {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
var item = getItemByUrl(context)(url);
item.xhr = xhr;
xhr.open('GET', asset.url, true);
xhr.responseType = responseType;
asset.xhr = xhr;
xhr.onprogress = function (event) {
if (event.lengthComputable) {
item.completion = event.loaded / event.total;
item.downloaded = event.loaded;
item.total = event.total;
updateProgress(context)(item);
asset.progress = event.loaded / event.total;
asset.downloaded = event.loaded;
asset.total = event.total;
onProgress({
progress: asset.progress,
event: event,
asset: asset
});
}

@@ -112,10 +74,10 @@ };

var responseURL = event.target.responseURL;
item.fileName = responseURL.substring(responseURL.lastIndexOf('/') + 1);
item.type = type;
item.status = xhr.status;
asset.fileName = responseURL.substring(responseURL.lastIndexOf('/') + 1);
asset.type = type;
asset.status = xhr.status;
if (xhr.status == 404) {
item.blobUrl = item.size = null;
item.error = true;
context.onError(item);
asset.blobUrl = asset.size = null;
asset.error = true;
onError(asset);
} else {

@@ -127,8 +89,8 @@ // TODO: fix

});
item.blobUrl = URL.createObjectURL(blob);
item.size = blob.size;
item.error = false;
asset.blobUrl = URL.createObjectURL(blob);
asset.size = blob.size;
asset.error = false;
}
done(item);
onComplete(asset);
};

@@ -138,64 +100,100 @@

};
request();
return asset;
};
var fetch = function fetch(context) {
return function (urls) {
return new Promise(function (resolve) {
context.loaded = urls.length;
for (var _iterator4 = _createForOfIteratorHelperLoose(urls), _step4; !(_step4 = _iterator4()).done;) {
var itemUrl = _step4.value;
// the item isn't a full StateItem yet but for the sake of simplicity we just cast
context.state.push({
url: itemUrl
});
preloadItem(context)(itemUrl, function (loadedItem) {
context.onFetched(loadedItem);
context.loaded--;
if (context.loaded == 0) {
context.onComplete(context.state);
resolve(context.state);
}
});
}
});
var createEvents = function createEvents() {
return {
onProgress: createPubSub(),
onComplete: createPubSub(),
onFetched: createPubSub(),
onError: createPubSub(),
onCancel: createPubSub()
};
};
var createPreloader = function createPreloader() {
var onProgress = createPubSub();
var onComplete = createPubSub();
var onFetched = createPubSub();
var onError = createPubSub();
var onCancel = createPubSub();
var context = {
state: [],
loaded: 0,
onProgress: onProgress.dispatch,
onComplete: onComplete.dispatch,
onFetched: onFetched.dispatch,
onError: onError.dispatch,
onCancel: onCancel.dispatch
var events = createEvents();
var assets = [];
var assetsToLoad = 0;
var pending = [];
var start = function start() {
pending.forEach(function (pendingAsset) {
assets.push(pendingAsset());
});
pending.length = 0;
};
var cancel = function cancel() {
assets.forEach(function (item) {
if (item.progress < 1) {
item.xhr.abort();
item.status = 0;
}
});
events.onCancel.dispatch(assets);
};
var dispose = function dispose() {
cancel(context)();
onProgress.dispose();
onComplete.dispose();
onFetched.dispose();
onError.dispose();
onCancel.dispose();
cancel();
Object.values(events).forEach(function (_ref) {
var dispose = _ref.dispose;
return dispose();
});
};
var load = function load(url, _temp) {
var _ref2 = _temp === void 0 ? {} : _temp,
responseType = _ref2.responseType,
_ref2$onProgress = _ref2.onProgress,
_onProgress = _ref2$onProgress === void 0 ? function () {} : _ref2$onProgress;
return new Promise(function (resolve, reject) {
assetsToLoad++;
var loadAsset = function loadAsset() {
return preloadAsset({
url: url,
responseType: responseType,
onProgress: function onProgress(payload) {
events.onProgress.dispatch(_extends({}, payload, {
progress: getTotalProgress(assets)
}));
_onProgress(payload);
},
onError: function onError(item) {
reject();
events.onError.dispatch(item);
},
onComplete: function onComplete(asset) {
events.onFetched.dispatch(asset);
resolve(asset);
assetsToLoad--;
if (assetsToLoad === 0) {
events.onComplete.dispatch(assets);
dispose();
}
}
});
};
pending.push(loadAsset);
});
};
return {
fetch: fetch(context),
updateProgress: updateProgress(context),
preloadItem: preloadItem(context),
getItemByUrl: getItemByUrl(context),
cancel: cancel(context),
onProgress: onProgress.subscribe,
onComplete: onComplete.subscribe,
onFetched: onFetched.subscribe,
onError: onError.subscribe,
onCancel: onCancel.subscribe,
dispose: dispose
load: load,
start: start,
cancel: cancel,
dispose: dispose,
getItemByUrl: getItemByUrl(assets),
onCancel: events.onCancel.subscribe,
onProgress: events.onProgress.subscribe,
onComplete: events.onComplete.subscribe,
onFetched: events.onFetched.subscribe,
onError: events.onError.subscribe
};

@@ -202,0 +200,0 @@ };

@@ -1,1 +0,2 @@

export { createPreloader, Asset, ProgressPayload } from './lib/preloader';
export { createPreloader } from './lib/preloader';
export { Asset, ProgressPayload } from './lib/preloadAsset';

@@ -1,46 +0,20 @@

export declare const getItemByUrl: (context: PreloaderContext) => (url: string) => Asset | null;
export declare const cancel: (context: PreloaderContext) => () => Assets;
export declare const updateProgress: (context: PreloaderContext) => (item: Asset) => void;
export declare const preloadItem: (context: PreloaderContext) => (url: string, done: (item: Asset) => void) => void;
export declare const fetch: (context: PreloaderContext) => (urls: Array<string>) => Promise<Assets>;
export declare type Asset = {
xhr: XMLHttpRequest;
blobUrl: string | null;
completion: number;
downloaded: number;
error: boolean;
fileName: string;
size: number | null;
status: number;
total: number;
type: string;
url: string;
};
declare type Assets = Array<Asset>;
export declare type ProgressPayload = {
item: Asset;
progress: number;
};
declare type PreloaderContext = {
state: Assets;
loaded: number;
import { Asset, ProgressPayload } from './preloadAsset';
declare type LoadOptions = {
onProgress: (payload: ProgressPayload) => void;
onComplete: (payload: Assets) => void;
onFetched: (payload: Asset) => void;
onError: (payload: any) => void;
onCancel: (payload: Assets) => void;
responseType: XMLHttpRequestResponseType;
};
export declare const createPreloader: () => {
fetch: (urls: Array<string>) => Promise<Assets>;
updateProgress: (item: Asset) => void;
preloadItem: (url: string, done: (item: Asset) => void) => void;
getItemByUrl: (url: string) => Asset | null;
cancel: () => Assets;
load: (url: string, { responseType, onProgress }?: Partial<LoadOptions>) => Promise<Asset>;
start: () => void;
cancel: () => void;
dispose: () => void;
getItemByUrl: (url: string) => {
url: string;
} | undefined;
onCancel: (callback: (payload: Asset[]) => void) => () => void;
onProgress: (callback: (payload: ProgressPayload) => void) => () => void;
onComplete: (callback: (payload: Assets) => void) => () => void;
onComplete: (callback: (payload: Asset[]) => void) => () => void;
onFetched: (callback: (payload: Asset) => void) => () => void;
onError: (callback: (payload: string) => void) => () => void;
onCancel: (callback: (payload: Assets) => void) => () => void;
dispose: () => void;
onError: (callback: (payload: Asset) => void) => () => void;
};
export {};
{
"name": "asset-preloader",
"version": "0.1.3",
"version": "0.1.4",
"author": "skulptur",

@@ -68,4 +68,4 @@ "license": "MIT",

"dependencies": {
"lightcast": "^0.1.2"
"lightcast": "^0.1.3"
}
}
## `asset-preloader`
A tiny Typescript asset preloader for the browser via XHR2. It can preload assets of different file types and composite progress together and supports multiple event subscriptions.
A tiny asset preloader for the browser via XHR2. It can preload assets of different file types and composite progress together, with support for multiple event subscriptions.

@@ -22,12 +22,12 @@ ## Get started

preloader
.fetch([
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4',
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
])
.then((assets) => {
// use the promise or the onComplete event
console.log('resolved', assets)
})
const urls = [
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4',
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
]
urls.forEach((url) => preloader.load(url))
preloader.start()
// event subscriptions
preloader.onComplete((assets) => {

@@ -34,0 +34,0 @@ console.log('completed', assets)

@@ -1,1 +0,2 @@

export { createPreloader, Asset, ProgressPayload } from './lib/preloader'
export { createPreloader } from './lib/preloader'
export { Asset, ProgressPayload } from './lib/preloadAsset'

@@ -1,182 +0,93 @@

// code adapted from and improved upon https://github.com/andreupifarre/preload-it
import { createPubSub } from 'lightcast'
import { getItemByUrl } from './getItemByUrl'
import { getTotalProgress } from './getTotalProgress'
import { preloadAsset, Asset, ProgressPayload } from './preloadAsset'
import { createEvents } from './events'
export const getItemByUrl = (context: PreloaderContext) => (url: string) => {
for (var item of context.state) {
if (item.url == url) return item
}
return null
type LoadOptions = {
onProgress: (payload: ProgressPayload) => void
responseType: XMLHttpRequestResponseType
}
export const cancel = (context: PreloaderContext) => () => {
for (var item of context.state) {
if (item.completion < 1) {
item.xhr.abort()
item.status = 0
}
}
export const createPreloader = () => {
const events = createEvents()
context.onCancel(context.state)
let assets: Array<Asset> = []
let assetsToLoad: number = 0
let hasStarted = false
let pending: Array<() => Asset> = []
return context.state
}
export const updateProgress = (context: PreloaderContext) => (item: Asset) => {
let sumCompletion = 0
let maxCompletion = context.state.length
for (const itemState of context.state) {
if (itemState.completion) {
sumCompletion += itemState.completion
}
const start = () => {
pending.forEach((pendingAsset) => {
assets.push(pendingAsset())
})
pending.length = 0
}
const totalCompletion = sumCompletion / maxCompletion
if (!isNaN(totalCompletion)) {
context.onProgress({
progress: totalCompletion,
item: item,
const cancel = () => {
assets.forEach((item) => {
if (item.progress < 1) {
item.xhr.abort()
item.status = 0
}
})
}
}
export const preloadItem = (context: PreloaderContext) => (
url: string,
done: (item: Asset) => void
) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.responseType = 'blob'
const item = getItemByUrl(context)(url) as Asset
item.xhr = xhr
xhr.onprogress = (event) => {
if (event.lengthComputable) {
item.completion = event.loaded / event.total
item.downloaded = event.loaded
item.total = event.total
updateProgress(context)(item)
}
events.onCancel.dispatch(assets)
}
xhr.onload = (event) => {
// TODO: fix
// @ts-expect-error
const type = event.target.response.type
// @ts-expect-error
const responseURL = event.target.responseURL
item.fileName = responseURL.substring(responseURL.lastIndexOf('/') + 1)
item.type = type
item.status = xhr.status
if (xhr.status == 404) {
item.blobUrl = item.size = null
item.error = true
context.onError(item)
} else {
// TODO: fix
// @ts-expect-error
const blob = new Blob([event.target.response], { type })
item.blobUrl = URL.createObjectURL(blob)
item.size = blob.size
item.error = false
}
done(item)
const dispose = () => {
cancel()
Object.values(events).forEach(({ dispose }) => dispose())
}
xhr.send()
}
export const fetch = (context: PreloaderContext) => (urls: Array<string>) => {
return new Promise<Assets>((resolve) => {
context.loaded = urls.length
for (let itemUrl of urls) {
// the item isn't a full StateItem yet but for the sake of simplicity we just cast
context.state.push({ url: itemUrl } as Asset)
preloadItem(context)(itemUrl, (loadedItem) => {
context.onFetched(loadedItem)
context.loaded--
if (context.loaded == 0) {
context.onComplete(context.state)
resolve(context.state)
}
})
}
})
}
const load = (
url: string,
{ responseType, onProgress = () => {} }: Partial<LoadOptions> = {}
) => {
return new Promise<Asset>((resolve, reject) => {
assetsToLoad++
export type Asset = {
xhr: XMLHttpRequest
blobUrl: string | null
completion: number
downloaded: number
error: boolean
fileName: string
size: number | null
status: number
total: number
type: string
url: string
}
const loadAsset = () =>
preloadAsset({
url,
responseType,
onProgress: (payload) => {
events.onProgress.dispatch({
...payload,
progress: getTotalProgress(assets),
})
type Assets = Array<Asset>
onProgress(payload)
},
onError: (item) => {
reject()
events.onError.dispatch(item)
},
onComplete: (asset) => {
events.onFetched.dispatch(asset)
resolve(asset)
export type ProgressPayload = {
item: Asset
progress: number
}
assetsToLoad--
if (assetsToLoad === 0) {
events.onComplete.dispatch(assets)
dispose()
}
},
})
type PreloaderContext = {
state: Assets
loaded: number
onProgress: (payload: ProgressPayload) => void
onComplete: (payload: Assets) => void
onFetched: (payload: Asset) => void
onError: (payload: any) => void
onCancel: (payload: Assets) => void
}
export const createPreloader = () => {
const onProgress = createPubSub<ProgressPayload>()
const onComplete = createPubSub<Assets>()
const onFetched = createPubSub<Asset>()
const onError = createPubSub<string>()
const onCancel = createPubSub<Assets>()
const context: PreloaderContext = {
state: [],
loaded: 0,
onProgress: onProgress.dispatch,
onComplete: onComplete.dispatch,
onFetched: onFetched.dispatch,
onError: onError.dispatch,
onCancel: onCancel.dispatch,
hasStarted ? assets.push(loadAsset()) : pending.push(loadAsset)
})
}
const dispose = () => {
cancel(context)()
onProgress.dispose()
onComplete.dispose()
onFetched.dispose()
onError.dispose()
onCancel.dispose()
}
return {
fetch: fetch(context),
updateProgress: updateProgress(context),
preloadItem: preloadItem(context),
getItemByUrl: getItemByUrl(context),
cancel: cancel(context),
onProgress: onProgress.subscribe,
onComplete: onComplete.subscribe,
onFetched: onFetched.subscribe,
onError: onError.subscribe,
onCancel: onCancel.subscribe,
load,
start,
cancel,
dispose,
getItemByUrl: getItemByUrl(assets),
onCancel: events.onCancel.subscribe,
onProgress: events.onProgress.subscribe,
onComplete: events.onComplete.subscribe,
onFetched: events.onFetched.subscribe,
onError: events.onError.subscribe,
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc