Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dmnsgn/async-preloader
Assets preloader using async/await and fetch for usage both in the browser and Node.js.
https://github.com/dmnsgn/async-preloader
async async-await es2017 fetch preloader typescript
Last synced: about 4 hours ago
JSON representation
Assets preloader using async/await and fetch for usage both in the browser and Node.js.
- Host: GitHub
- URL: https://github.com/dmnsgn/async-preloader
- Owner: dmnsgn
- License: mit
- Created: 2017-08-08T15:18:05.000Z (over 7 years ago)
- Default Branch: main
- Last Pushed: 2024-11-06T02:09:50.000Z (12 days ago)
- Last Synced: 2024-11-09T14:42:21.058Z (8 days ago)
- Topics: async, async-await, es2017, fetch, preloader, typescript
- Language: JavaScript
- Homepage: https://dmnsgn.github.io/async-preloader/
- Size: 11.3 MB
- Stars: 62
- Watchers: 3
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
README
# async-preloader
[![npm version](https://img.shields.io/npm/v/async-preloader)](https://www.npmjs.com/package/async-preloader)
[![stability-stable](https://img.shields.io/badge/stability-stable-green.svg)](https://www.npmjs.com/package/async-preloader)
[![npm minzipped size](https://img.shields.io/bundlephobia/minzip/async-preloader)](https://bundlephobia.com/package/async-preloader)
[![dependencies](https://img.shields.io/librariesio/release/npm/async-preloader)](https://github.com/dmnsgn/async-preloader/blob/main/package.json)
[![types](https://img.shields.io/npm/types/async-preloader)](https://github.com/microsoft/TypeScript)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-fa6673.svg)](https://conventionalcommits.org)
[![styled with prettier](https://img.shields.io/badge/styled_with-Prettier-f8bc45.svg?logo=prettier)](https://github.com/prettier/prettier)
[![linted with eslint](https://img.shields.io/badge/linted_with-ES_Lint-4B32C3.svg?logo=eslint)](https://github.com/eslint/eslint)
[![tested with jest](https://img.shields.io/badge/tested_with-jest-99424f.svg)](https://github.com/facebook/jest)
[![license](https://img.shields.io/github/license/dmnsgn/async-preloader)](https://github.com/dmnsgn/async-preloader/blob/main/LICENSE.md)Assets preloader using async/await and fetch for usage both in the browser and Node.js.
[![paypal](https://img.shields.io/badge/donate-paypal-informational?logo=paypal)](https://paypal.me/dmnsgn)
[![coinbase](https://img.shields.io/badge/donate-coinbase-informational?logo=coinbase)](https://commerce.coinbase.com/checkout/56cbdf28-e323-48d8-9c98-7019e72c97f3)
[![twitter](https://img.shields.io/twitter/follow/dmnsgn?style=social)](https://twitter.com/dmnsgn)## Install
```bash
npm install --save async-preloader
```## Documentation
- [AsyncPreloader class](https://dmnsgn.github.io/async-preloader/classes/index.AsyncPreloader.html)
- [AsyncPreloader types](https://dmnsgn.github.io/async-preloader/modules/types.html)## Quick start
This section covers the basic usage of `AsyncPreloader`. For more informations about async/await, see [Async functions - making promises friendly](https://developers.google.com/web/fundamentals/primers/async-functions). Usage in Node.js environment is limited to its capacity to handle `fetch` requests and DOM APIs. Polyfills like [`undici`](https://www.npmjs.com/package/undici/)/[`node-fetch`](https://www.npmjs.com/package/node-fetch) (for Node.js below 18) and [`xmldom`](https://www.npmjs.com/package/xmldom) might come handy .
### Preload items and retrieve them
```javascript
import AsyncPreloader from "async-preloader";const items = [
{ id: "myDefaultFile", src: "assets/default" },
{ id: "myTextFile", src: "assets/text.txt" },
{ id: "myJsonFile", src: "assets/json.json" },
{ id: "myImageFile", src: "assets/image.jpg" },
{ id: "myVideoFile", src: "assets/video.mp4" },
{ id: "myAudioFile", src: "assets/audio.mp3" },
{ id: "myXmlFile", src: "assets/xml.xml" },
{ id: "mySvgFile", src: "assets/xml.svg" },
{ id: "myHtmlFile", src: "assets/xml.html" },
{ id: "myDefaultXmlFile", src: "assets/xml", loader: "Xml" },
{ id: "myFont", src: `assets/font.ttf` },
{ id: "Space Regular", loader: "Font", fontOptions: { timeout: 10000 } },
// Can be retrieved with the src property eg. AsyncPreloader.items.get("assets/fileWithoutId")
{ src: "assets/fileWithoutId" },
];// Pass an array of LoadItem
//
// Returns a Promise with an array of LoadedValue
const pItems = AsyncPreloader.loadItems(items);pItems
.then((items) => {
const element = AsyncPreloader.items.get("myVideoFile");
document.body.appendChild(element);
})
.catch((error) => console.error("Error loading items", error));
```---
Note: Font loader will try to detect the font in the page using [FontFaceObserver](https://github.com/dmnsgn/fontfaceobserver) when no src is specified.
### Load items from a manifest file
It works in a similar fashion as createjs's [PreloadJS](http://www.createjs.com/docs/preloadjs/classes/LoadQueue.html).
```javascript
import AsyncPreloader from "async-preloader";// Pass the file url and an optional path of the property to get in the JSON file.
// It will load the file using the Json loader and look for the path key expecting an array of `LoadItem`s.
// Default path is "items" eg the default manifest would look like this:
// `{ "items": [ { "src": "assets/file1" }, { "src": "assets/file2" }] }`
//
// Returns a Promise with an array of LoadedValue
const pItems = AsyncPreloader.loadManifest(
"assets/manifest.json",
"data.preloader.items"
);pItems
.then((items) => useLoadedItemsFromManifest(items)) // or AsyncPreloader.items.get("src or id")
.catch((error) => console.error("Error loading items", error));
```## Advanced usage
This section takes a closer look at the options of `AsyncPreloader`.
### Load a single item by using the [loaders](https://github.com/dmnsgn/async-preloader/blob/main/src/index.ts#L60) directly
```javascript
import AsyncPreloader from "async-preloader";// Pass a LoadItem
//
// Returns a Promise with the LoadedValue
const pItem = AsyncPreloader.loadJson({ src: "assets/json.json" });pItem
.then((item) => useLoadedItem(item))
.catch((error) => console.error("Error loading item", error));
```---
Note: Using the loaders directly won't add the item to the `items` Map.
Alternatively you could use `AsyncPreloader.loadItem` and rely on the file extension or add `{ loader: "Json"}` to the item.### Load a single item by using a string directly
```javascript
import AsyncPreloader from "async-preloader";try {
// Pass a string
//
// Returns a Promise with the LoadedValue
const pItem = await AsyncPreloader.loadItem("assets/json.json");
} catch (error) {
console.error(error);
}
```### Get an `ArrayBuffer` instead of the default `Blob`
You can specify how the response is handle by using the `body` key in a `LoadItem`.
Typical use case: get an ArrayBuffer for the WebAudio API to decode the data with `baseAudioContext.decodeAudioData()`.
```javascript
import AsyncPreloader from "async-preloader";const audioContext = new AudioContext();
const pItem = AsyncPreloader.loadAudio({
src: "assets/audio.mp3",
body: "arrayBuffer",
});pItem
.then((item) => audioContext.decodeAudioData(item))
.then((decodedData) => useDecodedData(decodedData))
.catch((error) => console.error("Error decoding audio", error));
```### Getting the progress
Since `fetch` doesn't support `Progress events` yet, you might want to get a per file progress.
```javascript
import AsyncPreloader from "async-preloader";const items = [
{ id: "myDefaultFile", src: "assets/default" }, // ...
];let loadedCount = 0;
async function preload() {
await Promise.all(
items.map(async (item) => {
const data = await AsyncPreloader.loadItem(item);
loadedCount++;
console.log(`Progress: ${(100 * loadedCount) / items.length}%`);
})
);
}await preload();
```### Abort one or more loadItem(s) request(s)
To abort a loadItem(s) call, you can create an `AbortController` instance and pass its signal to options.
```javascript
const controller = new AbortController();const timeoutId = setTimeout(() => {
controller.abort();
}, 150);try {
await AsyncPreloader.loadItems(
items.map((item) => ({
...item,
options: { ...(item.options || {}), signal: controller.signal },
}))
);
} catch (error) {
if (error.name === "AbortError") console.log("Request was aborted");
} finally {
clearTimeout(timeoutId);
}
```## License
MIT © [Damien Seguin](https://github.com/dmnsgn)