I'm creating a custom cycle.js driver with the purpose of preloading images. The main function exports a sink stream imagesToLoad
emitting an array of image URLs. Those are then loaded by the driver and should return a stream that emits when the images are finished loading.
Problem
I can subscribe to the stream returned by the driver inside the driver's code and see that the loaded images are indeed emitted but never when mapping from inside the main function.
I am probably doing something wrong but I cannot see what exactly.
The driver
import { from, Subject } from 'rxjs'
import { adapt } from '@cycle/run/lib/adapt'
const loadImage = (src) =>
new Promise((resolve, reject) => {
const img = new Image()
img.addEventListener('load', () => resolve(img))
img.addEventListener('error', (err) => reject(err))
img.src = src
})
export const makeImageLoaderDriver = () => {
const imageLoaderDriver = (sink$) => {
const imageCache = {}
const source$ = new Subject()
from(source$).subscribe({
next(images) {
const imagesPromises = images.map((src) => {
const imgSuccess = { src, loaded: true }
if (!!imageCache[src]) return Promise.resolve(imgSuccess)
return loadImage(src)
.then(() => {
imageCache[src] = imgSuccess
})
.catch((error) => {
imageCache[src] = { src, loaded: false, error }
})
})
Promise.all(imagesPromises).then(() => {
source$.next(imageCache)
})
},
})
return adapt(source$)
}
return imageLoaderDriver
}
The index.js
const drivers = {
imagesToLoad: makeImageLoaderDriver(),
}
run(main, drivers)
The main function
export function main(sources) {
sources.imagesToLoad.pipe(map(console.log)) // THIS NEVER LOGS ANYTHING
return {
imagesToLoad: of([ imageUrl1, imageUrl2 ]),
}
}