Skip to content

Commit

Permalink
feat(custom-cache-provider): adds custom cache provider
Browse files Browse the repository at this point in the history
- adds custom cache provider interface
- makes the cache provider functions async
- adds .idea to .gitignore
- lints the changelog
  • Loading branch information
alexcondrea committed Feb 1, 2023
1 parent b9f9e3c commit fca69c3
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 39 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ test-manager.js
dist/
*.log
.DS_Store
.nuxt
.nuxt
.idea
4 changes: 1 addition & 3 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,20 @@ All notable changes to this project will be documented in this file.

# [Unreleased]


## [5.3.4] - 2023-01-24

### Fixed

- [Storyblok-JS-client](https://github.com/storyblok/storyblok-js-client/releases/tag/v5.3.4)
- Error handling is return the correct reject/resolve to the client


## [5.2.1] - 2022-12-20

### Fixed

- [Storyblok-JS-client](https://github.com/storyblok/storyblok-js-client/releases/tag/v5.2.1)
- Added content type header to fix a bug from the api calls.


## [5.2.0] - 2022-12-19

### Added
Expand All @@ -37,6 +34,7 @@ All notable changes to this project will be documented in this file.
- Added a simple playground for manual testing
- Build setup improvements
- Added svelte + ts and Nuxt 3 playgrounds

## [5.0.4] - 2022-10-28

### Fixed
Expand Down
62 changes: 29 additions & 33 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
ISbContentMangmntAPI,
ISbNode,
ThrottleFn,
IMemoryType,
ICacheProvider,
} from './interfaces'

let memory: Partial<IMemoryType> = {}
Expand All @@ -39,21 +41,10 @@ type RelationsType = {
[key: string]: any
}

interface IMemoryType extends ISbResult {
[key: string]: any
}

interface ISbFlatMapped {
data: any
}

interface ICacheProvider {
get: (key: string) => IMemoryType | void
set: (key: string, content: ISbResult) => void
getAll: () => IMemoryType | void
flush: () => void
}

interface ISbResponseData {
link_uuids: string[]
links: string[]
Expand Down Expand Up @@ -484,7 +475,7 @@ class Storyblok {
}
}

private cacheResponse(
private async cacheResponse(
url: string,
params: ISbStoriesParams,
retries?: number
Expand All @@ -493,21 +484,21 @@ class Storyblok {
retries = 0
}

return new Promise((resolve, reject) => {
const cacheKey = this.helpers.stringify({ url: url, params: params })
const provider = this.cacheProvider()
const cacheKey = this.helpers.stringify({ url: url, params: params })
const provider = this.cacheProvider()

if (this.cache.clear === 'auto' && params.version === 'draft') {
this.flushCache()
}
if (this.cache.clear === 'auto' && params.version === 'draft') {
await this.flushCache()
}

if (params.version === 'published' && url != '/cdn/spaces/me') {
const cache = provider.get(cacheKey)
if (cache) {
return resolve(cache)
}
if (params.version === 'published' && url != '/cdn/spaces/me') {
const cache = await provider.get(cacheKey)
if (cache) {
return Promise.resolve(cache)
}
}

return new Promise((resolve, reject) => {
try {
;(async () => {
const res = await this.throttle('get', url, params)
Expand All @@ -534,15 +525,15 @@ class Storyblok {
}

if (params.version === 'published' && url != '/cdn/spaces/me') {
provider.set(cacheKey, response)
await provider.set(cacheKey, response)
}

if (response.data.cv && params.token) {
if (
params.version == 'draft' &&
cacheVersions[params.token] != response.data.cv
) {
this.flushCache()
await this.flushCache()
}

cacheVersions[params.token] = response.data.cv
Expand Down Expand Up @@ -595,38 +586,43 @@ class Storyblok {
case 'memory':
return {
get(key: string) {
return memory[key]
return Promise.resolve(memory[key])
},
getAll() {
return memory as IMemoryType
return Promise.resolve(memory as IMemoryType)
},
set(key: string, content: ISbResult) {
memory[key] = content
return Promise.resolve(undefined)
},
flush() {
memory = {}
return Promise.resolve(undefined)
},
}
case 'custom':
if (this.cache.custom) return this.cache.custom
// eslint-disable-next-line no-fallthrough
default:
return {
get() {
return undefined
return Promise.resolve(undefined)
},
getAll() {
return undefined
return Promise.resolve(undefined)
},
set() {
return undefined
return Promise.resolve(undefined)
},
flush() {
return undefined
return Promise.resolve(undefined)
},
}
}
}

public flushCache(): this {
this.cacheProvider().flush()
public async flushCache(): Promise<this> {
await this.cacheProvider().flush()
return this
}
}
Expand Down
14 changes: 13 additions & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,21 @@ export interface ISbStory {
headers: any
}

export interface IMemoryType extends ISbResult {
[key: string]: any
}

export interface ICacheProvider {
get: (key: string) => Promise<IMemoryType | void>
set: (key: string, content: ISbResult) => Promise<void>
getAll: () => Promise<IMemoryType | void>
flush: () => Promise<void>
}

export interface ISbCache {
type?: 'none' | 'memory'
type?: 'none' | 'memory' | 'custom'
clear?: 'auto' | 'manual'
custom?: ICacheProvider
}

export interface ISbConfig {
Expand Down
2 changes: 1 addition & 1 deletion tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('getAll function', () => {
describe('test uncached requests', () => {
test("get('cdn/spaces/me') should not be cached", async () => {
let provider = Storyblok.cacheProvider()
provider.flush()
await provider.flush()
await Storyblok.get('cdn/spaces/me')
expect(Object.values(provider.getAll()).length).toBe(0)
})
Expand Down

0 comments on commit fca69c3

Please sign in to comment.