Last active
February 27, 2018 16:51
-
-
Save dakom/9dd56c6c1f16c43e91fd08be386cc624 to your computer and use it in GitHub Desktop.
Sodium loaders (wrapping loader-helpers)
This file contains hidden or 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
//Copied from https://github.com/dakom/sodium-loaders | |
import { | |
loadXhrFactory, LoaderXhr, LoaderXhrRequest, LoaderXhrResponse, LOADER_TYPE_XHR, | |
loadImageFactory, LoaderImage, LoaderImageRequest, LoaderImageResponse, LOADER_TYPE_IMAGE, | |
loadTextureFactory, LoaderTexture, LoaderTextureRequest, LoaderTextureResponse, LOADER_TYPE_TEXTURE, | |
LoaderResponseAny, | |
LoaderRequestAny, | |
LoaderCallbackAny, | |
LoaderAny, | |
isLoaderXhr | |
} from "loader-helpers"; | |
import {Cell, Stream, StreamSink} from "sodiumjs"; | |
import { Maybe, S, Either } from '../sanctuary/Sanctuary'; | |
//types for consistency | |
export type MaybeStreamOrCellRequest<A> = Cell<Maybe<A>> | Stream<Maybe<A>>; | |
export type StreamOrCellRequest<A> = Cell<A> | Stream<A>; | |
export type MultiMaybeStreamOrCellRequest<I, A> = Cell<{ id: I, mReq: Maybe<A> }> | Stream<{ id: I, mReq: Maybe<A> }> | |
export type MultiStreamOrCellRequest<I, A> = Cell<{ id: I, req: A }> | Stream<{ id: I, req: A }> | |
export type SodiumLoader<A> = {close: () => void, sResponse: Stream<Maybe<Either<A>>>}; | |
export type SodiumMultiLoader<I, A> = {close: (id:I) => void, sResponse: Stream<{ id: I, mResp: Maybe<Either<A>> }>}; | |
//generic helper/utils | |
const requestToMaybe = <A>(request: StreamOrCellRequest<A>) => (request as any).map(S.Just) as MaybeStreamOrCellRequest<A>; | |
const multiRequestToMaybe = <I, A>(request: MultiStreamOrCellRequest<I, A>) => (request as any).map(({id, req}) => ({id, mReq: S.Just(req)})) as MultiMaybeStreamOrCellRequest<I, A>; | |
const closeLoader = (ldr: LoaderAny) => { | |
if (isLoaderXhr(ldr)) { | |
ldr.close(); | |
} | |
} | |
/* | |
Generic functions are internal only. Exported versions are specific | |
*/ | |
const _baseSingle = <A, B> | |
(loadFactory: (req: A, callback: LoaderCallbackAny) => LoaderAny) => | |
(cache: Map<A, Either<B>>) => | |
(scRequest: MaybeStreamOrCellRequest<A>): SodiumLoader<B> => { | |
const sResponse = new StreamSink<Maybe<Either<B>>>(); | |
let mLdr: Maybe<LoaderAny> = S.Nothing; | |
const doClose = () => { | |
S.map(closeLoader)(mLdr) | |
mLdr = S.Nothing; | |
} | |
scRequest.listen(mReq => { | |
doClose(); | |
//listen->send must push to the next callstack | |
setTimeout(() => S.maybe_ | |
(() => sResponse.send(S.Nothing)) | |
(req => { | |
if (cache && cache.has(req)) { | |
sResponse.send(S.Just(cache.get(req))); | |
} else { | |
sResponse.send(S.Nothing); | |
//loading inherently will be on the next stack, or at worst as a microtask | |
mLdr = S.Just( | |
loadFactory(req, eResponse => { | |
if (cache) { | |
cache.set(req, eResponse); | |
} | |
sResponse.send(S.Just(eResponse)); | |
doClose(); | |
}) | |
); | |
} | |
}) | |
(mReq) | |
, 0); | |
}); | |
return {close: doClose, sResponse}; | |
} | |
const _baseMulti = <I, A, B> | |
(loadFactory: (req: A, callback: LoaderCallbackAny) => LoaderAny) => | |
(cache: Map<A, Either<B>>) => | |
(scRequest: MultiMaybeStreamOrCellRequest<I, A>): SodiumMultiLoader<I,B> => { | |
const sResponse = new StreamSink<{ id: I, mResp: Maybe<Either<B>> }>() | |
const loaderMap = new Map<I, LoaderAny>(); | |
const doClose = (id: I) => { | |
if (loaderMap.has(id)) { | |
closeLoader(loaderMap.get(id)); | |
loaderMap.delete(id); | |
} | |
} | |
scRequest.listen(request => { | |
const { id, mReq } = request; | |
//listen->send must push to the next callstack | |
setTimeout(() => S.maybe_ | |
(() => sResponse.send({ id, mResp: S.Nothing })) | |
(req => { | |
if (cache && cache.has(req)) { | |
sResponse.send({ id, mResp: S.Just(cache.get(req)) }); | |
} else { | |
sResponse.send({ id, mResp: S.Nothing }); | |
//loading inherently will be on the next stack, or at worst as a microtask | |
doClose(id); | |
loaderMap.set(id, loadFactory(req, eResponse => { | |
if (cache) { | |
cache.set(req, eResponse); | |
} | |
sResponse.send({ id, mResp: S.Just(eResponse) }); | |
doClose(id); | |
})) | |
} | |
}) | |
(mReq) | |
, 0); | |
}); | |
return {close: doClose, sResponse}; | |
} | |
//Style: Single, Maybe: Yes, Cache: Yes | |
export const createSodiumMaybeLoaderCacheTexture = | |
(cache: Map<LoaderTextureRequest, Either<LoaderTextureResponse>>) => | |
(scRequest: MaybeStreamOrCellRequest<LoaderTextureRequest>) => | |
_baseSingle<LoaderTextureRequest, LoaderTextureResponse>(loadTextureFactory) (cache) (scRequest); | |
export const createSodiumMaybeLoaderCacheImage = | |
(cache: Map<LoaderImageRequest, Either<LoaderImageResponse>>) => | |
(scRequest: MaybeStreamOrCellRequest<LoaderImageRequest>) => | |
_baseSingle<LoaderImageRequest, LoaderImageResponse>(loadImageFactory) (cache) (scRequest); | |
export const createSodiumMaybeLoaderCacheXhr = | |
(cache: Map<LoaderXhrRequest, Either<LoaderXhrResponse>>) => | |
(scRequest: MaybeStreamOrCellRequest<LoaderXhrRequest>) => | |
_baseSingle<LoaderXhrRequest, LoaderXhrResponse>(loadXhrFactory) (cache) (scRequest); | |
//Style: Single, Maybe: No, Cache: Yes | |
export const createSodiumLoaderCacheTexture= | |
(cache: Map<LoaderTextureRequest, Either<LoaderTextureResponse>>) => | |
(scRequest: StreamOrCellRequest<LoaderTextureRequest>) => | |
_baseSingle<LoaderTextureRequest, LoaderTextureResponse>(loadTextureFactory) (cache) (requestToMaybe(scRequest)); | |
export const createSodiumLoaderCacheImage = | |
(cache: Map<LoaderImageRequest, Either<LoaderImageResponse>>) => | |
(scRequest: StreamOrCellRequest<LoaderImageRequest>) => | |
_baseSingle<LoaderImageRequest, LoaderImageResponse>(loadImageFactory) (cache) (requestToMaybe(scRequest)); | |
export const createSodiumLoaderCacheXhr = | |
(cache: Map<LoaderXhrRequest, Either<LoaderXhrResponse>>) => | |
(scRequest: StreamOrCellRequest<LoaderXhrRequest>) => | |
_baseSingle<LoaderXhrRequest, LoaderXhrResponse>(loadXhrFactory) (cache) (requestToMaybe(scRequest)); | |
//Style: Single, Maybe: Yes, Cache: No | |
export const createSodiumMaybeLoaderTexture = | |
(scRequest: MaybeStreamOrCellRequest<LoaderTextureRequest>) => | |
_baseSingle<LoaderTextureRequest, LoaderTextureResponse>(loadTextureFactory) (null) (scRequest); | |
export const createSodiumMaybeLoaderImage = | |
(scRequest: MaybeStreamOrCellRequest<LoaderImageRequest>) => | |
_baseSingle<LoaderImageRequest, LoaderImageResponse>(loadImageFactory) (null) (scRequest); | |
export const createSodiumMaybeLoaderXhr = | |
(scRequest: MaybeStreamOrCellRequest<LoaderXhrRequest>) => | |
_baseSingle<LoaderXhrRequest, LoaderXhrResponse>(loadXhrFactory) (null) (scRequest); | |
//Style: Single, Maybe: No, Cache: No | |
export const createSodiumLoaderTexture = | |
(scRequest: StreamOrCellRequest<LoaderTextureRequest>) => | |
_baseSingle<LoaderTextureRequest, LoaderTextureResponse>(loadTextureFactory) (null) (requestToMaybe(scRequest)); | |
export const createSodiumLoaderImage = | |
(scRequest: StreamOrCellRequest<LoaderImageRequest>) => | |
_baseSingle<LoaderImageRequest, LoaderImageResponse>(loadImageFactory) (null) (requestToMaybe(scRequest)); | |
export const createSodiumLoaderXhr = | |
(scRequest: StreamOrCellRequest<LoaderXhrRequest>) => | |
_baseSingle<LoaderXhrRequest, LoaderXhrResponse>(loadXhrFactory) (null) (requestToMaybe(scRequest)); | |
///------------ | |
//Style: Multi, Maybe: Yes, Cache: Yes | |
export const createMultiSodiumMaybeLoaderCacheTexture = <I> | |
(cache: Map<LoaderTextureRequest, Either<LoaderTextureResponse>>) => | |
(scRequest: MultiMaybeStreamOrCellRequest<I, LoaderTextureRequest>) => | |
_baseMulti<I, LoaderTextureRequest, LoaderTextureResponse>(loadTextureFactory) (cache) (scRequest); | |
export const createMultiSodiumMaybeLoaderCacheImage = <I> | |
(cache: Map<LoaderImageRequest, Either<LoaderImageResponse>>) => | |
(scRequest: MultiMaybeStreamOrCellRequest<I, LoaderImageRequest>) => | |
_baseMulti<I, LoaderImageRequest, LoaderImageResponse>(loadImageFactory) (cache) (scRequest); | |
export const createMultiSodiumMaybeLoaderCacheXhr = <I> | |
(cache: Map<LoaderXhrRequest, Either<LoaderXhrResponse>>) => | |
(scRequest: MultiMaybeStreamOrCellRequest<I, LoaderXhrRequest>) => | |
_baseMulti<I, LoaderXhrRequest, LoaderXhrResponse>(loadXhrFactory) (cache) (scRequest); | |
//Style: Multi, Maybe: No, Cache: Yes | |
export const createMultiSodiumLoaderCacheTexture= <I> | |
(cache: Map<LoaderTextureRequest, Either<LoaderTextureResponse>>) => | |
(scRequest: MultiStreamOrCellRequest<I, LoaderTextureRequest>) => | |
_baseMulti<I, LoaderTextureRequest, LoaderTextureResponse>(loadTextureFactory) (cache) (multiRequestToMaybe(scRequest)); | |
export const createMultiSodiumLoaderCacheImage = <I> | |
(cache: Map<LoaderImageRequest, Either<LoaderImageResponse>>) => | |
(scRequest: MultiStreamOrCellRequest<I, LoaderImageRequest>) => | |
_baseMulti<I, LoaderImageRequest, LoaderImageResponse>(loadImageFactory) (cache) (multiRequestToMaybe(scRequest)); | |
export const createMultiSodiumLoaderCacheXhr = <I> | |
(cache: Map<LoaderXhrRequest, Either<LoaderXhrResponse>>) => | |
(scRequest: MultiStreamOrCellRequest<I, LoaderXhrRequest>) => | |
_baseMulti<I, LoaderXhrRequest, LoaderXhrResponse>(loadXhrFactory) (cache) (multiRequestToMaybe(scRequest)); | |
//Style: Multi, Maybe: Yes, Cache: No | |
export const createMultiSodiumMaybeLoaderTexture = <I> | |
(scRequest: MultiMaybeStreamOrCellRequest<I, LoaderTextureRequest>) => | |
_baseMulti<I, LoaderTextureRequest, LoaderTextureResponse>(loadTextureFactory) (null) (scRequest); | |
export const createMultiSodiumMaybeLoaderImage = <I> | |
(scRequest: MultiMaybeStreamOrCellRequest<I, LoaderImageRequest>) => | |
_baseMulti<I, LoaderImageRequest, LoaderImageResponse>(loadImageFactory) (null) (scRequest); | |
export const createMultiSodiumMaybeLoaderXhr = <I> | |
(scRequest: MultiMaybeStreamOrCellRequest<I, LoaderXhrRequest>) => | |
_baseMulti<I, LoaderXhrRequest, LoaderXhrResponse>(loadXhrFactory) (null) (scRequest); | |
//Style: Multi, Maybe: No, Cache: No | |
export const createMultiSodiumLoaderTexture = <I> | |
(scRequest: MultiStreamOrCellRequest<I, LoaderTextureRequest>) => | |
_baseMulti<I, LoaderTextureRequest, LoaderTextureResponse>(loadTextureFactory) (null) (multiRequestToMaybe(scRequest)); | |
export const createMultiSodiumLoaderImage = <I> | |
(scRequest: MultiStreamOrCellRequest<I, LoaderImageRequest>) => | |
_baseMulti<I, LoaderImageRequest, LoaderImageResponse>(loadImageFactory) (null) (multiRequestToMaybe(scRequest)); | |
export const createMultiSodiumLoaderXhr = <I> | |
(scRequest: MultiStreamOrCellRequest<I, LoaderXhrRequest>) => | |
_baseMulti<I, LoaderXhrRequest, LoaderXhrResponse>(loadXhrFactory) (null) (multiRequestToMaybe(scRequest)); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment