@colisweb/rescript-toolkit
Version:

53 lines (48 loc) • 1.08 kB
JSX
const cache = new Map();
function createResource(asyncFn) {
let status = "pending";
let result;
const promise = asyncFn().then(
(r) => {
status = "success";
result = r;
},
(e) => {
status = "error";
result = e;
},
);
return {
read() {
switch (status) {
case "pending":
throw promise;
case "error":
throw result;
case "success":
return result;
}
},
};
}
function loadImage(source) {
let resource = cache.get(source);
if (resource) return resource;
resource = createResource(
() =>
new Promise((resolve, reject) => {
const img = new window.Image();
img.src = source;
img.addEventListener("load", () => resolve(source));
img.addEventListener("error", () =>
reject(new Error(`Failed to load image ${source}`)),
);
}),
);
cache.set(source, resource);
return resource;
}
export default function SuspenseImage(props) {
loadImage(props.src).read();
return <img {...props} />;
}