@stylable/core
Version:
CSS for Components
66 lines (58 loc) • 1.86 kB
text/typescript
export type processFn<T> = (fullpath: string, content: string) => T;
export interface CacheItem<T> {
value: T;
content: string;
}
export interface MinimalFS {
readFileSync: (filePath: string, encoding: 'utf8') => string;
}
export interface FileProcessor<T> {
process: (filePath: string, invalidateCache?: boolean) => T;
add: (filePath: string, value: T) => void;
processContent: (content: string, filePath: string) => T;
cache: Record<string, CacheItem<T>>;
postProcessors: Array<(value: T, path: string) => T>;
}
export function cachedProcessFile<T = any>(
processor: processFn<T>,
readFileSync: MinimalFS['readFileSync'],
postProcessors: Array<(value: T, path: string) => T> = [],
cache: { [key: string]: CacheItem<T> } = {}
): FileProcessor<T> {
function process(filePath: string, invalidateCache = false) {
const content = readFileSync(filePath, 'utf8');
const cached = cache[filePath];
if (invalidateCache || !cached || (cached && cached.content !== content)) {
cache[filePath] = {
value: processContent(content, filePath),
content,
};
}
return cache[filePath].value;
}
function processContent(content: string, filePath: string): T {
return postProcessors.reduce<T>(
(value, postProcessor) => postProcessor(value, filePath),
processor(filePath, content)
);
}
function add(filePath: string, value: T) {
let content;
try {
content = readFileSync(filePath, 'utf8');
} catch (e) {
content = '';
}
cache[filePath] = {
value,
content,
};
}
return {
processContent,
postProcessors,
cache,
process,
add,
};
}