lot more stuff

This commit is contained in:
Morten Olsen
2025-08-04 23:44:14 +02:00
parent daf0ea21bb
commit 757b2fcfac
185 changed files with 115899 additions and 1874 deletions

View File

@@ -0,0 +1,91 @@
import { EventEmitter } from 'eventemitter3';
import equal from 'deep-equal';
import type { CustomResource } from './custom-resources.custom-resource.ts';
import type { CustomResourceStatus } from './custom-resources.types.ts';
type CustomResourceStatusOptions = {
resource: CustomResource<ExpectedAny>;
};
type CustomResourceConditionsEvents = {
changed: (type: string, condition: Condition) => void;
};
type Condition = {
lastTransitionTime: Date;
status: 'True' | 'False' | 'Unknown';
syncing?: boolean;
failed?: boolean;
resource?: boolean;
reason?: string;
message?: string;
observedGeneration?: number;
};
class CustomResourceConditions extends EventEmitter<CustomResourceConditionsEvents> {
#options: CustomResourceStatusOptions;
#conditions: Record<string, Condition>;
constructor(options: CustomResourceStatusOptions) {
super();
this.#options = options;
this.#conditions = Object.fromEntries(
(options.resource.status?.conditions || []).map(({ type, lastTransitionTime, ...condition }) => [
type,
{
...condition,
lastTransitionTime: new Date(lastTransitionTime),
},
]),
);
options.resource.on('changed', this.#handleChange);
}
#handleChange = () => {
const { resource } = this.#options;
for (const { type, ...condition } of resource.status?.conditions || []) {
const next = {
...condition,
lastTransitionTime: new Date(condition.lastTransitionTime),
};
const current = this.#conditions[type];
const isEqual = equal(current, next);
const isNewer = !current || next.lastTransitionTime > current.lastTransitionTime;
if (isEqual || !isNewer) {
return;
}
this.#conditions[type] = next;
this.emit('changed', type, next);
}
};
public get = (type: string): Condition | undefined => {
return this.#conditions[type];
};
public set = async (type: string, condition: Omit<Condition, 'lastTransitionTime'>) => {
const current = this.#conditions[type];
this.#conditions[type] = {
...condition,
lastTransitionTime: current && current.status === condition.status ? current.lastTransitionTime : new Date(),
observedGeneration: this.#options.resource.metadata?.generation,
};
await this.save();
};
public save = async () => {
const { resource } = this.#options;
const status: CustomResourceStatus = {
conditions: Object.entries(this.#conditions).map(([type, condition]) => ({
...condition,
type,
lastTransitionTime: condition.lastTransitionTime.toISOString(),
})),
};
await resource.patchStatus(status);
};
}
export { CustomResourceConditions };