diff --git a/README.md b/README.md
index 5d3b1fc..5b284b3 100755
--- a/README.md
+++ b/README.md
@@ -55,6 +55,24 @@ console.log(text);
## Functions
+- fetchText(url, options) ⇒
Promise.<string>
+Load an item and parse the Response as text
+
+- fetchJson(url, options) ⇒
Promise.<JSON>
+Load an item and parse the Response as json
+
+- fetchArrayBuffer(url, options) ⇒
Promise.<ArrayBuffer>
+Load an item and parse the Response as arrayBuffer
+
+- fetchBlob(url, options) ⇒
Promise.<Blob>
+Load an item and parse the Response as blob
+
+- fetchImage(urlOrOpts, options) ⇒
Promise.<HTMLImageElement>
+Load an item, parse the Response as blob and create a HTML Image
+
+- fetchAll(resources) ⇒
Promise.<Object.<string, LoadedResource>>
+Loads resources from a named map
+
- load(resources, callback) ⇒
Promise.<Object.<string, LoadedResource>>
| undefined
Loads resources from a named map
@@ -93,6 +111,102 @@ console.log(text);
+
+
+## fetchText(url, options) ⇒ Promise.<string>
+
+Load an item and parse the Response as text
+
+**Kind**: global function
+
+| Param | Type |
+| ------- | ------------------------ |
+| url | RequestInfo
|
+| options | RequestInit
|
+
+
+
+## fetchJson(url, options) ⇒ Promise.<JSON>
+
+Load an item and parse the Response as json
+
+**Kind**: global function
+
+| Param | Type |
+| ------- | ------------------------ |
+| url | RequestInfo
|
+| options | RequestInit
|
+
+
+
+## fetchArrayBuffer(url, options) ⇒ Promise.<ArrayBuffer>
+
+Load an item and parse the Response as arrayBuffer
+
+**Kind**: global function
+
+| Param | Type |
+| ------- | ------------------------ |
+| url | RequestInfo
|
+| options | RequestInit
|
+
+
+
+## fetchBlob(url, options) ⇒ Promise.<Blob>
+
+Load an item and parse the Response as blob
+
+**Kind**: global function
+
+| Param | Type |
+| ------- | ------------------------ |
+| url | RequestInfo
|
+| options | RequestInit
|
+
+
+
+## fetchImage(urlOrOpts, options) ⇒ Promise.<HTMLImageElement>
+
+Load an item, parse the Response as blob and create a HTML Image
+
+**Kind**: global function
+
+| Param | Type |
+| --------- | ----------------------------------------------------------------- |
+| urlOrOpts | string
\| [ImageOptions
](#ImageOptions) |
+| options | RequestInit
|
+
+
+
+## fetchAll(resources) ⇒ Promise.<Object.<string, LoadedResource>>
+
+Loads resources from a named map
+
+**Kind**: global function
+
+| Param | Type |
+| --------- | -------------------------------------------- |
+| resources | Object.<string, Resource>
|
+
+**Example**
+
+```js
+const resources = {
+ hello: { text: "assets/hello.txt" },
+ data: { json: "assets/data.json" },
+ img: { image: "assets/tex.jpg" },
+ hdrImg: { binary: "assets/tex.hdr" },
+ blob: { binary: "assets/blob" },
+};
+
+const res = await io.fetchAll(resources);
+res.hello; // => DOMString
+res.data; // => Object
+res.img; // => HTMLImageElement
+res.hdrImg; // => ArrayBuffer
+res.blob; // => Blob
+```
+
## load(resources, callback) ⇒ Promise.<Object.<string, LoadedResource>>
\| undefined
diff --git a/fetch.js b/fetch.js
new file mode 100644
index 0000000..6ebb234
--- /dev/null
+++ b/fetch.js
@@ -0,0 +1,130 @@
+/**
+ * Load an item and parse the Response as text
+ * @function
+ * @param {RequestInfo} url
+ * @param {RequestInit} options
+ * @returns {Promise}
+ */
+export const fetchText = async (url, options = {}) =>
+ await (await fetch(url, options)).text();
+
+/**
+ * Load an item and parse the Response as json
+ * @function
+ * @param {RequestInfo} url
+ * @param {RequestInit} options
+ * @returns {Promise}
+ */
+export const fetchJson = async (url, options = {}) =>
+ await (await fetch(url, options)).json();
+
+/**
+ * Load an item and parse the Response as arrayBuffer
+ * @function
+ * @param {RequestInfo} url
+ * @param {RequestInit} options
+ * @returns {Promise}
+ */
+export const fetchArrayBuffer = async (url, options = {}) =>
+ await (await fetch(url, options)).arrayBuffer();
+
+/**
+ * Load an item and parse the Response as blob
+ * @function
+ * @param {RequestInfo} url
+ * @param {RequestInit} options
+ * @returns {Promise}
+ */
+export const fetchBlob = async (url, options = {}) =>
+ await (await fetch(url, options)).blob();
+
+/**
+ * Load an item, parse the Response as blob and create a HTML Image
+ * @function
+ * @param {string | ImageOptions} urlOrOpts
+ * @param {RequestInit} options
+ * @returns {Promise}
+ */
+export const fetchImage = async (urlOrOpts, options = {}) => {
+ const img = new Image();
+
+ let src = urlOrOpts;
+ if (urlOrOpts.url) {
+ const { url, ...rest } = urlOrOpts;
+ src = url;
+ try {
+ Object.assign(img, rest);
+ } catch (error) {
+ return Promise.reject(new Error(error));
+ }
+ }
+
+ const data = await fetchBlob(src, options);
+
+ return await new Promise((resolve, reject) => {
+ img.addEventListener("load", function load() {
+ img.removeEventListener("load", load);
+ resolve(img);
+ });
+ img.addEventListener("error", function error() {
+ img.removeEventListener("error", error);
+ reject(img);
+ });
+
+ img.src = URL.createObjectURL(data);
+ });
+};
+
+const LOADERS_MAP = {
+ text: fetchText,
+ json: fetchJson,
+ image: fetchImage,
+ blob: fetchBlob,
+ binary: fetchArrayBuffer,
+};
+const LOADERS_MAP_KEYS = Object.keys(LOADERS_MAP);
+
+/**
+ * Loads resources from a named map
+ * @function
+ * @param {Object.} resources
+ * @returns {Promise>}
+ *
+ * @example
+ * const resources = {
+ * hello: { text: "assets/hello.txt" },
+ * data: { json: "assets/data.json" },
+ * img: { image: "assets/tex.jpg" },
+ * hdrImg: { binary: "assets/tex.hdr" },
+ * blob: { binary: "assets/blob" },
+ * };
+ *
+ * const res = await io.fetchAll(resources);
+ * res.hello; // => DOMString
+ * res.data; // => Object
+ * res.img; // => HTMLImageElement
+ * res.hdrImg; // => ArrayBuffer
+ * res.blob; // => Blob
+ */
+export const fetchAll = (resources) => {
+ const names = Object.keys(resources);
+
+ return Promise.allSettled(
+ names.map(async (name) => {
+ const res = resources[name];
+ const loader = LOADERS_MAP_KEYS.find((loader) => res[loader]);
+ if (loader) return await LOADERS_MAP[loader](res[loader]);
+ return Promise.reject(
+ new Error(`io.load: unknown resource type "${Object.keys(res)}".
+Resource needs one of ${LOADERS_MAP_KEYS.join("|")} set to an url.`)
+ );
+ })
+ ).then((values) =>
+ Object.fromEntries(
+ Array.from(
+ values.map((v) => v.value || v.reason),
+ (v, i) => [names[i], v]
+ )
+ )
+ );
+};
diff --git a/index.html b/index.html
index 399fcb0..9575c3e 100644
--- a/index.html
+++ b/index.html
@@ -48,6 +48,7 @@ pex-io
json: "assets/color.json",
image: "assets/pex.png",
binary: "assets/data.bin",
+ blob: "assets/hello.txt",
errorNotFound: "assets/not-found.ext",
};
@@ -58,9 +59,12 @@ pex-io
"callback-batch": { ...assetState },
async: { ...assetState },
"async-batch": { ...assetState },
+ fetch: { ...assetState, blob: null },
+ "fetch-batch": { ...assetState, blob: null },
error: { ...assetState, error: null },
"image-options": { all: null, readOnly: null, urlOnly: null },
};
+ window.state = state;
const app = () => () => {
return [
@@ -176,6 +180,63 @@ pex-io
state["async-batch"].binary = res.data;
})();
+ // fetch
+ (async () => {
+ try {
+ state.fetch.text = await io.fetchText(ASSETS.text);
+ } catch (error) {
+ state.fetch.text = error;
+ console.log("fetch", error);
+ }
+ try {
+ state.fetch.json = await io.fetchJson(ASSETS.json);
+ } catch (error) {
+ state.fetch.json = error;
+ console.log("fetch", error);
+ }
+ try {
+ state.fetch.image = await io.fetchImage(ASSETS.image);
+ } catch (error) {
+ state.fetch.image = error;
+ console.log("fetch", error);
+ }
+ try {
+ state.fetch.binary = await io.fetchArrayBuffer(ASSETS.binary);
+ } catch (error) {
+ state.fetch.binary = error;
+ console.log("fetch", error);
+ }
+ try {
+ state.fetch.blob = await io.fetchBlob(ASSETS.blob);
+ state.fetch.blob = await state.fetch.blob.text();
+ } catch (error) {
+ state.fetch.blob = error;
+ console.log("fetch", error);
+ }
+ })();
+
+ // fetch-batch
+ (async () => {
+ let res;
+ try {
+ res = await io.fetchAll({
+ hello: { text: ASSETS.text },
+ color: { json: ASSETS.json },
+ pex: { image: ASSETS.image },
+ data: { binary: ASSETS.binary },
+ blob: { blob: ASSETS.blob },
+ });
+ } catch (err) {
+ res = err;
+ console.log("fetch batch", filterResultsErrors(err));
+ }
+ state["fetch-batch"].text = res.hello;
+ state["fetch-batch"].json = res.color;
+ state["fetch-batch"].image = res.pex;
+ state["fetch-batch"].binary = res.data;
+ state["fetch-batch"].blob = await res.blob.text();
+ })();
+
// Error
(() => {
io.loadText(ASSETS.errorNotFound, (err, text) => {
diff --git a/index.js b/index.js
index ca290d6..ac37ad8 100644
--- a/index.js
+++ b/index.js
@@ -3,3 +3,4 @@ export { default as loadText } from "./loadText.js";
export { default as loadJSON } from "./loadJSON.js";
export { default as loadImage } from "./loadImage.js";
export { default as loadBinary } from "./loadBinary.js";
+export * from "./fetch.js";
diff --git a/load.js b/load.js
index 90dc1ee..73270df 100644
--- a/load.js
+++ b/load.js
@@ -60,14 +60,11 @@ function load(resources, callback) {
Promise.allSettled(
names.map(async (name) => {
const res = resources[name];
-
const loader = LOADERS_MAP_KEYS.find((loader) => res[loader]);
if (loader) return await LOADERS_MAP[loader](res[loader]);
return Promise.reject(
- new Error(
- `io.load: unknown resource type "${Object.keys(res)}".
-Resource needs one of ${LOADERS_MAP_KEYS.join("|")} set to an url.`
- )
+ new Error(`io.load: unknown resource type "${Object.keys(res)}".
+Resource needs one of ${LOADERS_MAP_KEYS.join("|")} set to an url.`)
);
})
).then((values) => {