UNPKG

sflow

Version:

sflow is a powerful and highly-extensible library designed for processing and manipulating streams of data effortlessly. Inspired by the functional programming paradigm, it provides a rich set of utilities for transforming streams, including chunking, fil

84 lines (74 loc) 2.6 kB
import Keyv from "keyv"; import { cacheLists } from "./cacheLists"; import { cacheTails } from "./cacheTails"; import sflow, { forEachs } from "./index"; import { sleep } from "./utils"; it("caches stream", async () => { const store = new Keyv<any>({ ttl: 10e3 }); const heavyFlow = () => sflow([1, 2, 3, 4]); const fn0 = jest.fn(); const fn1 = jest.fn(); const fn2 = jest.fn(); // slow without cache expect(await heavyFlow().forEach(fn0).toArray()).toEqual([1, 2, 3, 4]); expect(fn0).toHaveBeenCalledTimes(4); // slow with cache miss expect( await heavyFlow() .by(forEachs(fn1)) .byLazy(cacheLists(store, "heavy-step")) .toArray(), ).toEqual([1, 2, 3, 4]); expect(fn1).toHaveBeenCalledTimes(4); expect(await store.get("heavy-step")).toEqual([1, 2, 3, 4]); // fast with cache hit expect( await heavyFlow() .by(forEachs(fn2)) .byLazy(cacheLists(store, "heavy-step")) .toArray(), ).toEqual([1, 2, 3, 4]); expect(fn2).toHaveBeenCalledTimes(1); await sleep(100); expect(fn2).toHaveBeenCalledTimes(1); }); it("caches stream tail", async () => { const store = new Keyv<any>({ ttl: 10e3 }); const heavyFlowHead1 = () => sflow([3, 2, 1]); const heavyFlowHead2 = () => sflow([5, 4, 3, 2, 1]); const heavyFlowHead3 = () => sflow([5, 4, 3, 2, 1]); const heavyFlowHead = () => sflow([6]); const fn1 = jest.fn(); const fn2 = jest.fn(); const fn3 = jest.fn(); const fn4 = jest.fn(); const fn6 = jest.fn(); // 1st time, we got page emit 3,2,1, cache [3,2,1] await heavyFlowHead1() .forEach(fn2) .by(cacheTails(store, "page")) .toArray(); expect(fn2).toHaveBeenCalledTimes(3); expect(await store.get("page")).toEqual([3, 2, 1]); // 2th time, new element appeared 5,4,3 // flow emit 5,4,3,2,1, hit cache from [2,], store [5,4,3]+[2,1] => [5,4,3,2,1] // fn will run at 5,4,3,2 // Upstream terminates after 1 item emitted // await heavyFlowHead2() // .forEach(fn3) // .byLazy(cacheTails(store, "page")) // .toArray(); // expect(await store.get("page")).toEqual([5, 4, 3, 2, 1]); // await sleep(100); // expect(fn3).toHaveBeenCalledTimes(2 + 1); // // 3th time, page content is not changed // // flow emit 4,3,2,1, hit cache from [4,], store [4,3,2,1] => [4,3,2,1] // // Upstream terminates after 1 item emitted // await heavyFlowHead3() // .forEach(fn1) // .byLazy(cacheTails(store, "page")) // .toArray(); // await sleep(100); // expect(fn1).toHaveBeenCalledTimes(1); // expect(await store.get("page")).toEqual([5, 4, 3, 2, 1]); });