Skip to content

Commit

Permalink
test(core): add tests for rxSwr
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoerge committed Sep 30, 2024
1 parent c68bba8 commit 75e3e83
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
55 changes: 55 additions & 0 deletions packages/sanity/src/core/util/__tests__/rxSwr.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {describe, expect, it} from '@jest/globals'
import {lastValueFrom, timer} from 'rxjs'
import {map, toArray} from 'rxjs/operators'

import {createSWR} from '../rxSwr'

describe('rxSwr', () => {
it('should cache the last known value and emit sync', async () => {
const swr = createSWR({maxSize: 1})

const observable = timer(100).pipe(
map(() => 'value!'),
swr('someKey'),
toArray(),
)

expect(await lastValueFrom(observable)).toEqual([{fromCache: false, value: 'value!'}])

// Second subscription, now with warm cache
expect(await lastValueFrom(observable)).toEqual([
{fromCache: true, value: 'value!'},
{fromCache: false, value: 'value!'},
])
})

it('should discard old cache keys when exceeding maxSize', async () => {
const swr = createSWR({maxSize: 1})

const observable1 = timer(100).pipe(
map(() => 'observable1!'),
swr('key1'),
toArray(),
)

expect(await lastValueFrom(observable1)).toEqual([{fromCache: false, value: 'observable1!'}])

// Second subscription, now with warm cache
expect(await lastValueFrom(observable1)).toEqual([
{fromCache: true, value: 'observable1!'},
{fromCache: false, value: 'observable1!'},
])

const observable2 = timer(100).pipe(
map(() => 'observable2!'),
swr('key2'),
toArray(),
)

// Subscribing to observable2 should purge the key of observable1
expect(await lastValueFrom(observable2)).toEqual([{fromCache: false, value: 'observable2!'}])

// re-subscribing to the first should now not have a cache
expect(await lastValueFrom(observable1)).toEqual([{fromCache: false, value: 'value!'}])
})
})
7 changes: 7 additions & 0 deletions packages/sanity/src/core/util/rxSwr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import QuickLRU from 'quick-lru'
import {concat, defer, EMPTY, map, type Observable, of, type OperatorFunction} from 'rxjs'
import {tap} from 'rxjs/operators'

/**
* The interface that any caching layer must implement
*/
interface SWRCache<T> {
/**
* Note: This will throw if key does not exist. Always check for existence with `has` before calling
Expand Down Expand Up @@ -32,6 +35,10 @@ export function createSWR<T>(options: {maxSize: number}) {
}
}

/**
* For now, the only cache layer implemented is an in-memory LRU.
* @param options - LRU options
*/
function createLRUCache<T>(options: {maxSize: number}): SWRCache<T> {
const lru = new QuickLRU<string, {value: T}>(options)
return {
Expand Down

0 comments on commit 75e3e83

Please sign in to comment.