Files
renovate/lib/modules/datasource/docker/dockerhub-cache.ts
T
renovate[bot] c2aa761c1e chore(deps): update linters (main) (#41417)
* chore(deps): update linters

| datasource | package              | from   | to     |
| ---------- | -------------------- | ------ | ------ |
| npm        | @eslint/js           | 9.39.2 | 9.39.3 |
| npm        | eslint               | 9.39.2 | 9.39.3 |
| npm        | eslint-plugin-oxlint | 1.46.0 | 1.49.0 |
| npm        | oxlint               | 1.47.0 | 1.49.0 |
| npm        | typescript-eslint    | 8.55.0 | 8.56.0 |

* chore(deps): update linters

| datasource | package              | from   | to     |
| ---------- | -------------------- | ------ | ------ |
| npm        | @eslint/js           | 9.39.2 | 9.39.3 |
| npm        | eslint               | 9.39.2 | 9.39.3 |
| npm        | eslint-plugin-oxlint | 1.46.0 | 1.49.0 |
| npm        | oxlint               | 1.47.0 | 1.49.0 |
| npm        | typescript-eslint    | 8.55.0 | 8.56.0 |

* Radix rule has been deprecated

* fixup! Radix rule has been deprecated

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: secustor <sebastian@poxhofer.at>
2026-02-28 11:23:25 +00:00

115 lines
2.7 KiB
TypeScript

import { dequal } from 'dequal';
import { DateTime } from 'luxon';
import * as packageCache from '../../../util/cache/package/index.ts';
import type { DockerHubTag } from './schema.ts';
export interface DockerHubCacheData {
items: Record<number, DockerHubTag>;
updatedAt: string | null;
}
const cacheNamespace = 'datasource-docker-hub-cache';
export class DockerHubCache {
private isChanged = false;
private reconciledIds = new Set<number>();
private dockerRepository: string;
private cache: DockerHubCacheData;
private constructor(dockerRepository: string, cache: DockerHubCacheData) {
this.dockerRepository = dockerRepository;
this.cache = cache;
}
static async init(dockerRepository: string): Promise<DockerHubCache> {
let repoCache = await packageCache.get<DockerHubCacheData>(
cacheNamespace,
dockerRepository,
);
repoCache ??= {
items: {},
updatedAt: null,
};
return new DockerHubCache(dockerRepository, repoCache);
}
reconcile(items: DockerHubTag[], expectedCount: number): boolean {
let needNextPage = true;
let earliestDate = null;
let { updatedAt } = this.cache;
let latestDate = updatedAt ? DateTime.fromISO(updatedAt) : null;
for (const newItem of items) {
const id = newItem.id;
this.reconciledIds.add(id);
const oldItem = this.cache.items[id];
const itemDate = DateTime.fromISO(newItem.last_updated);
if (!earliestDate || earliestDate > itemDate) {
earliestDate = itemDate;
}
if (!latestDate || latestDate < itemDate) {
latestDate = itemDate;
updatedAt = newItem.last_updated;
}
if (dequal(oldItem, newItem)) {
needNextPage = false;
continue;
}
this.cache.items[newItem.id] = newItem;
this.isChanged = true;
}
this.cache.updatedAt = updatedAt;
if (earliestDate && latestDate) {
for (const [key, item] of Object.entries(this.cache.items)) {
const id = parseInt(key, 10);
const itemDate = DateTime.fromISO(item.last_updated);
if (
itemDate < earliestDate ||
itemDate > latestDate ||
this.reconciledIds.has(id)
) {
continue;
}
delete this.cache.items[id];
this.isChanged = true;
}
if (Object.keys(this.cache.items).length > expectedCount) {
return true;
}
}
return needNextPage;
}
async save(): Promise<void> {
if (this.isChanged) {
await packageCache.set(
cacheNamespace,
this.dockerRepository,
this.cache,
3 * 60 * 24 * 30,
);
}
}
getItems(): DockerHubTag[] {
return Object.values(this.cache.items);
}
}