-
-
Notifications
You must be signed in to change notification settings - Fork 151
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dl-asset): split src, extract
downloadWithMime()
- new fn improves tree shaking and can avoid inclusion of @thi.ng/mime if mime type is explicitly provided by user
- Loading branch information
1 parent
d637996
commit d749819
Showing
4 changed files
with
105 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
export interface DownloadOpts { | ||
/** | ||
* MIME type. If not given, attempts to derive MIME type from given | ||
* filename extension (e.g. `.svg`) and if that fails, falls back to | ||
* default value. | ||
* | ||
* @defaultValue application/octet-stream | ||
*/ | ||
mime: string; | ||
/** | ||
* If true, converts source string to UTF-8. Only used if input is a | ||
* string. | ||
* | ||
* @defaultValue false | ||
*/ | ||
utf8: boolean; | ||
/** | ||
* Expiry time for generated object URL. Use value < 0 to disable. | ||
* | ||
* @defaultValue 10000 | ||
*/ | ||
expire: number; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type { TypedArray } from "@thi.ng/api"; | ||
import { preferredType } from "@thi.ng/mime"; | ||
import type { DownloadOpts } from "./api"; | ||
import { downloadWithMime } from "./raw"; | ||
|
||
/** | ||
* Similar to (and wrapping) {@link downloadWithMime} with additional | ||
* automatic MIME type detection. If no MIME type is given, attempts to | ||
* derive it from the given filename's extension (e.g. `.svg`) and if | ||
* that fails, falls back to default value. | ||
* | ||
* @param name | ||
* @param src | ||
* @param opts | ||
*/ | ||
export const download = ( | ||
name: string, | ||
src: string | TypedArray | ArrayBuffer | Blob, | ||
opts: Partial<DownloadOpts> = {} | ||
) => { | ||
if (opts.mime === undefined) { | ||
const match = /\.(\w+)$/.exec(name); | ||
opts.mime = preferredType(match ? match[1] : "bin"); | ||
} | ||
return downloadWithMime(name, src, <any>opts); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,3 @@ | ||
import { isString } from "@thi.ng/checks"; | ||
import { preferredType } from "@thi.ng/mime"; | ||
import type { TypedArray } from "@thi.ng/api"; | ||
|
||
export interface DownloadOpts { | ||
/** | ||
* MIME type. If not given, attempts to derive MIME type from given | ||
* filename extension (e.g. `.svg`) and if that fails, falls back to | ||
* default value. | ||
* | ||
* @defaultValue application/octet-stream | ||
*/ | ||
mime: string; | ||
/** | ||
* If true, converts source string to UTF-8. Only used if input is a | ||
* string. | ||
* | ||
* @defaultValue false | ||
*/ | ||
utf8: boolean; | ||
/** | ||
* Expiry time for generated object URL. Use value < 0 to disable. | ||
* | ||
* @defaultValue 10000 | ||
*/ | ||
expire: number; | ||
} | ||
|
||
/** | ||
* Triggers download of given `src` blob (or typed array or string) as | ||
* local file with filename `name`. MIME type, text encoding and URL | ||
* expiry can be defined via the optional `opts` config object. See | ||
* {@link DownloadOpts} for details & defaults. | ||
* | ||
* @remarks | ||
* If `src` is not a blob already, it will be wrapped as such | ||
* automatically. The `mime` option is only used for that wrapping | ||
* purpose. If no MIME type is given, attempts to derive it from the | ||
* given filename extension (e.g. `.svg`) and if that fails, falls back | ||
* to default value. The `utf8` option is only used if `src` is a string | ||
* and will trigger UTF-8 encoding of `src`. | ||
* | ||
* The function creates an object URL for download, which auto-expires | ||
* again after `expire` millseconds (default: 10000) to free up memory. | ||
* The URL won't be expired if `expire <= 0`. | ||
* | ||
* @param name | ||
* @param src | ||
* @param opts | ||
*/ | ||
export const download = ( | ||
name: string, | ||
src: string | TypedArray | ArrayBuffer | Blob, | ||
opts?: Partial<DownloadOpts> | ||
) => { | ||
const _opts = { | ||
mime: undefined, | ||
expire: 1e4, | ||
utf8: false, | ||
...opts, | ||
}; | ||
if (_opts.mime === undefined) { | ||
const match = /\.(\w+)$/.exec(name); | ||
_opts.mime = preferredType(match ? match[1] : "bin"); | ||
} | ||
if (isString(src) && _opts.utf8) { | ||
src = new TextEncoder().encode(src); | ||
_opts.mime += ";charset=UTF-8"; | ||
} | ||
const uri = URL.createObjectURL( | ||
!(src instanceof Blob) ? new Blob([src], { type: _opts.mime }) : src | ||
); | ||
const link = document.createElement("a"); | ||
link.setAttribute("download", name); | ||
link.setAttribute("href", uri); | ||
document.body.appendChild(link); | ||
link.click(); | ||
document.body.removeChild(link); | ||
if (_opts.expire > 0) { | ||
setTimeout(() => URL.revokeObjectURL(uri), _opts.expire); | ||
} | ||
}; | ||
export * from "./api"; | ||
export * from "./download"; | ||
export * from "./raw"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import type { TypedArray } from "@thi.ng/api"; | ||
import { isString } from "@thi.ng/checks"; | ||
import type { DownloadOpts } from "./api"; | ||
|
||
/** | ||
* Triggers download of given `src` blob (or typed array or string) as | ||
* local file with filename `name`. MIME type option MUST be given. | ||
* UTF-8 text encoding and URL expiry can be defined via the optional | ||
* `opts` config object. See {@link DownloadOpts} for details & | ||
* defaults. Use {@link download} if auto-detection of MIME type is | ||
* required. | ||
* | ||
* @remarks | ||
* If `src` is not a blob already, it will be wrapped as such | ||
* automatically. The `mime` option is only used for that wrapping | ||
* purpose. The `utf8` option is only used if `src` is a string and will | ||
* trigger UTF-8 encoding of `src`. | ||
* | ||
* The function creates an object URL for download, which auto-expires | ||
* again after `expire` millseconds (default: 10000) to free up memory. | ||
* The URL won't be expired if `expire <= 0`. | ||
* | ||
* @param name | ||
* @param src | ||
* @param opts | ||
*/ | ||
export const downloadWithMime = ( | ||
name: string, | ||
src: string | TypedArray | ArrayBuffer | Blob, | ||
opts: Partial<DownloadOpts> & { mime: string } | ||
) => { | ||
const _opts = { | ||
expire: 1e4, | ||
utf8: false, | ||
...opts, | ||
}; | ||
if (isString(src) && _opts.utf8) { | ||
src = new TextEncoder().encode(src); | ||
_opts.mime += ";charset=UTF-8"; | ||
} | ||
const uri = URL.createObjectURL( | ||
!(src instanceof Blob) ? new Blob([src], { type: _opts.mime }) : src | ||
); | ||
const link = document.createElement("a"); | ||
link.setAttribute("download", name); | ||
link.setAttribute("href", uri); | ||
document.body.appendChild(link); | ||
link.click(); | ||
document.body.removeChild(link); | ||
if (_opts.expire > 0) { | ||
setTimeout(() => URL.revokeObjectURL(uri), _opts.expire); | ||
} | ||
}; |