import SequentialIDGenerator from "./sequential-id-generator"; import sortMq from "./sort-css-media-queries"; type OnNewCacheFn = ( key: string, cache: Cache, value?: string | null, ) => any; type OnNewValueFn = (cache: Cache, id: string, value: T) => any; export class MultiCache { caches: { [x: string]: Cache; }; idGenerator: SequentialIDGenerator; onNewCache: OnNewCacheFn; onNewValue: OnNewValueFn; sortedCacheKeys: string[]; constructor( idGenerator: SequentialIDGenerator, onNewCache: OnNewCacheFn, onNewValue: OnNewValueFn, ) { this.idGenerator = idGenerator; this.onNewCache = onNewCache; this.onNewValue = onNewValue; this.sortedCacheKeys = []; this.caches = {}; } getCache(key: string): Cache { if (!this.caches[key]) { const cache = new Cache(this.idGenerator, this.onNewValue); cache.key = key; this.sortedCacheKeys.push(key); this.sortedCacheKeys.sort(sortMq); const keyIndex = this.sortedCacheKeys.indexOf(key); const insertBeforeMedia = keyIndex < this.sortedCacheKeys.length - 1 ? this.sortedCacheKeys[keyIndex + 1] : void 0; this.caches[key] = cache; this.onNewCache(key, cache, insertBeforeMedia); } return this.caches[key]; } getSortedCacheKeys() { return this.sortedCacheKeys; } } export class Cache { cache: { [x: string]: string; }; idGenerator: SequentialIDGenerator; key: string; onNewValue: (cache: Cache, id: string, value: any) => any; constructor( idGenerator: SequentialIDGenerator, onNewValue: (cache: Cache, id: string, value: any) => any, ) { this.cache = {}; this.idGenerator = idGenerator; this.onNewValue = onNewValue; } addValue(key: string, value: T) { const cached = this.cache[key]; if (cached) { return cached; } const id = this.idGenerator.next(); this.cache[key] = id; this.onNewValue(this, id, value); return id; } }