Added download utilities
All checks were successful
Build / Build NPM Project (push) Successful in 37s
Build / Tag Version (push) Successful in 7s
Build / Publish (push) Successful in 14s

This commit is contained in:
Zakary Timson 2024-04-21 21:33:38 -04:00
parent 67b314b507
commit d0e9cbcaa6
4 changed files with 49 additions and 18 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@ztimson/utils", "name": "@ztimson/utils",
"version": "0.5.0", "version": "0.6.0",
"description": "Utility library", "description": "Utility library",
"author": "Zak Timson", "author": "Zak Timson",
"license": "MIT", "license": "MIT",

46
src/download.ts Normal file
View File

@ -0,0 +1,46 @@
import {TypedEmitter, TypedEvents} from './emitter.ts';
export type downloadEvents = TypedEvents & {
complete: (blob: Blob) => any;
progress: (progress: number) => any;
}
export function download(href: any, name: string) {
const a = document.createElement('a');
a.href = href;
a.download = name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
export function downloadStream(url: string, name?: string) {
const emitter = new TypedEmitter<downloadEvents>();
fetch(url).then(response => {
const contentLength = response.headers.get('Content-Length') || '0';
const total = parseInt(contentLength, 10);
let chunks: any[] = [], loaded = 0;
const reader = response.body?.getReader();
reader?.read().then(function processResult(result) {
if(result.done) {
const blob = new Blob(chunks);
emitter.emit('progress', 1);
if(name) {
const url = URL.createObjectURL(blob);
download(url, name);
URL.revokeObjectURL(url);
}
emitter.emit('complete', blob);
return;
} else {
const chunk = result.value;
chunks.push(chunk);
loaded += chunk.length;
const progress = Math.round((loaded / total) * 100);
emitter.emit('progress', progress);
reader.read().then(processResult);
}
});
});
return emitter;
}

View File

@ -1,5 +1,6 @@
export * from './array'; export * from './array';
export * from './aset'; export * from './aset';
export * from './download.ts';
export * from './emitter'; export * from './emitter';
export * from './errors'; export * from './errors';
export * from './logger'; export * from './logger';

View File

@ -1,3 +1,4 @@
import {TypedEmitter, TypedEvents} from './emitter.ts';
import {clean} from './objects'; import {clean} from './objects';
export type Interceptor = (request: Response, next: () => void) => void; export type Interceptor = (request: Response, next: () => void) => void;
@ -45,14 +46,6 @@ export class XHR {
return () => { this.interceptors[key] = <any>null; } return () => { this.interceptors[key] = <any>null; }
} }
download(opts: RequestOptions & {url: string}) {
this.request<Response>({...opts, skipConverting: true}).then(async resp => {
const blob = await resp.blob();
download(URL.createObjectURL(blob), <string>opts.url.split('/').pop());
URL.revokeObjectURL(opts.url);
});
}
async request<T>(opts: RequestOptions = {}): Promise<T> { async request<T>(opts: RequestOptions = {}): Promise<T> {
if(!this.opts.url && !opts.url) throw new Error('URL needs to be set'); if(!this.opts.url && !opts.url) throw new Error('URL needs to be set');
const url = (opts.url?.startsWith('http') ? opts.url : (this.opts.url || '') + (opts.url || '')).replace(/([^:]\/)\/+/g, '$1'); const url = (opts.url?.startsWith('http') ? opts.url : (this.opts.url || '') + (opts.url || '')).replace(/([^:]\/)\/+/g, '$1');
@ -82,12 +75,3 @@ export class XHR {
}); });
} }
} }
export function download(href: any, name: string) {
const a = document.createElement('a');
a.href = href;
a.download = name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}