Skip to content

Commit

Permalink
feat(api): add writeImages and purgeCache
Browse files Browse the repository at this point in the history
  • Loading branch information
ElMassimo committed Jan 12, 2022
1 parent d0879b3 commit 1c831d3
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 20 deletions.
42 changes: 27 additions & 15 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const debug = {
load: createDebugger('image-presets:load'),
write: createDebugger('image-presets:write'),
total: createDebugger('image-presets:total'),
cache: createDebugger('image-presets:cache'),
}

export const VIRTUAL_ID = '/@imagepresets/'
Expand All @@ -25,14 +26,35 @@ export function createImageApi (config: Config) {
const imageFilenamesById: Record<string, Promise<string>> = {}

return {
get config () {
return config
},
async getImageById (id: string) {
return await requestedImagesById[id]
},
async waitForImages () {
debug.total('%i image(s)', generatedImages.length)
const assets = await Promise.all(generatedImages)
cleanCacheDir(assets.map(asset => asset.name!))
return assets
return await Promise.all(generatedImages)
},
async writeImages (outDir: string) {
const images = await Promise.all(generatedImages.map(async imagePromise => {
const image = await imagePromise
fs.writeFile(join(outDir, image.fileName), image.source)
return image
}))
this.purgeCache(images)
},
async purgeCache (assets: OutputAsset[]) {
if (!config.purgeCache)
return

const usedFiles = new Set(assets.map(asset => asset.name!))
const cachedFiles = await fs.readdir(config.cacheDir)
const unusedFiles = cachedFiles.filter(file => !usedFiles.has(file))
debug.cache('%i unused files', unusedFiles.length)
unusedFiles.forEach(file => {
fs.rm(resolve(config.cacheDir, file), { force: true })
})
},
async resolveImage (filename: string, params: Record<string, any>): Promise<ImageResult> {
const presetName = params[config.urlParam]
Expand Down Expand Up @@ -83,17 +105,16 @@ export function createImageApi (config: Config) {
}

async function writeImageFile (filename: string, image: Image): Promise<OutputAsset> {
const { cacheDir, assetsDir, outDir } = config
const { cacheDir, assetsDir } = config
const cachedFilename = join(cacheDir, filename)
const destFilename = join(outDir, assetsDir, filename)

if (!await exists(cachedFilename)) {
debug.write('%s', filename)
await image.toFile(cachedFilename)
}

return {
fileName: relative(config.outDir, destFilename),
fileName: join(config.assetsDir, filename),
name: filename,
source: await fs.readFile(cachedFilename) as any,
isAsset: true,
Expand All @@ -115,13 +136,4 @@ export function createImageApi (config: Config) {

return VIRTUAL_ID + id
}

async function cleanCacheDir (newFiles: string[]) {
const usedFiles = new Set(newFiles)
const cachedFiles = await fs.readdir(config.cacheDir)
cachedFiles.forEach(file => {
if (!usedFiles.has(file))
fs.rm(resolve(config.cacheDir, file), { force: true })
})
}
}
14 changes: 10 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@ export default function ImagePresetsPlugin (presets?: ImagePresets, options?: Op
name: 'image-presets',
enforce: 'pre',
get api () { return api },
async configResolved ({ base, command, root, build: { outDir, assetsDir } }) {
async configResolved ({ base, command, root, build: { assetsDir } }) {
if (api) return // NOTE: When reusing plugins for SSR build.

config = {
presets: presets!,
urlParam: 'preset',
base,
root,
outDir: resolve(root, outDir),
assetsDir,
cacheDir: join(root, 'node_modules', '.images'),
purgeCache: true,
writeToBundle: true,
isBuild: command === 'build',
...options,
}
Expand Down Expand Up @@ -67,8 +70,11 @@ export default function ImagePresetsPlugin (presets?: ImagePresets, options?: Op
})
},
async generateBundle (_, output) {
const images = await api.waitForImages()
images.forEach(asset => { output[asset.fileName] = asset })
if (config.writeToBundle) {
const images = await api.waitForImages()
images.forEach(asset => { output[asset.fileName] = asset })
api.purgeCache(images)
}
},
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,20 @@ export interface Options {
* @default 'preset'
*/
urlParam?: string
/**
* Whether to remove cached files that are no longer used.
* @default true
*/
purgeCache?: boolean
/**
* Whether to write generated images in the bundle.
* @default true
*/
writeToBundle?: boolean
}

export interface Config extends Required<Options> {
isBuild: boolean
outDir: string
base: string
root: string
}

0 comments on commit 1c831d3

Please sign in to comment.