2024-07-22 01:40:00 +02:00
|
|
|
import { checkIsValidObject, checkMatchesObjectStructure } from "./typeSafety";
|
2024-07-21 22:42:32 +02:00
|
|
|
|
2024-07-19 19:49:55 +02:00
|
|
|
// date
|
|
|
|
|
export function createTimestamp(): string {
|
|
|
|
|
return new Date().toISOString();
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 01:58:34 +02:00
|
|
|
// handlers
|
|
|
|
|
export type Handler<T> = (item: T) => void;
|
|
|
|
|
|
|
|
|
|
export class HandlerManager<T> {
|
|
|
|
|
handlers: Set<Handler<T>> = new Set();
|
|
|
|
|
|
|
|
|
|
// manage
|
|
|
|
|
addHandler = (handler: Handler<T>): void => {
|
|
|
|
|
this.handlers.add(handler);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
deleteHandler = (handler: Handler<T>): void => {
|
|
|
|
|
this.handlers.delete(handler);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// trigger
|
|
|
|
|
trigger = (item: T): void => {
|
|
|
|
|
for (const handler of this.handlers) {
|
|
|
|
|
handler(item);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-25 00:26:40 +02:00
|
|
|
// objects
|
|
|
|
|
export type StringEntryObject = { [key: string]: string };
|
2024-07-24 23:34:11 +02:00
|
|
|
export function filterObjectsByStringEntries<T>(
|
2024-07-25 00:26:40 +02:00
|
|
|
reference: StringEntryObject,
|
|
|
|
|
converter: (T) => StringEntryObject,
|
2024-07-24 23:34:11 +02:00
|
|
|
objects: T[]
|
2024-07-25 00:27:08 +02:00
|
|
|
): Set<T> {
|
|
|
|
|
const matches: Set<T> = new Set()
|
2024-07-24 17:37:18 +02:00
|
|
|
|
|
|
|
|
object_loop: for (const object of objects) {
|
2024-07-24 23:34:11 +02:00
|
|
|
reference_entry_loop: for (const referenceEntry of Object.entries(
|
|
|
|
|
reference
|
|
|
|
|
)) {
|
2024-07-24 23:44:34 +02:00
|
|
|
const [referenceKey, referenceValue] = referenceEntry;
|
2024-07-25 00:26:40 +02:00
|
|
|
const stringEntryObject: StringEntryObject = converter(object);
|
|
|
|
|
const stringEntryObjectValue: string = stringEntryObject[referenceKey];
|
2024-07-24 23:44:34 +02:00
|
|
|
|
|
|
|
|
if (referenceValue[0] == "-") {
|
|
|
|
|
const strippedReferenceValue: string = referenceValue.substring(1);
|
|
|
|
|
// property may not exist
|
|
|
|
|
if (
|
|
|
|
|
strippedReferenceValue == "" &&
|
2024-07-25 00:26:40 +02:00
|
|
|
stringEntryObjectValue != undefined &&
|
|
|
|
|
stringEntryObjectValue != ""
|
2024-07-24 23:44:34 +02:00
|
|
|
) {
|
|
|
|
|
continue object_loop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// property may not match
|
2024-07-25 00:26:40 +02:00
|
|
|
if (stringEntryObjectValue == strippedReferenceValue) {
|
2024-07-24 23:44:34 +02:00
|
|
|
continue object_loop;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// property must exist but be anything
|
|
|
|
|
if (
|
|
|
|
|
referenceValue == "" &&
|
2024-07-25 00:26:40 +02:00
|
|
|
(stringEntryObjectValue == undefined || stringEntryObjectValue == "")
|
2024-07-24 23:44:34 +02:00
|
|
|
) {
|
|
|
|
|
continue object_loop;
|
|
|
|
|
} else if (referenceValue == "") {
|
|
|
|
|
continue reference_entry_loop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// property must match
|
2024-07-25 00:26:40 +02:00
|
|
|
if (stringEntryObjectValue != referenceValue) {
|
2024-07-24 23:44:34 +02:00
|
|
|
continue object_loop;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-07-24 17:37:18 +02:00
|
|
|
}
|
2024-07-25 00:27:08 +02:00
|
|
|
matches.add(object);
|
2024-07-24 17:37:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return matches;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-25 00:26:40 +02:00
|
|
|
export function collectObjectValuesForKey<T>(
|
|
|
|
|
key: string,
|
|
|
|
|
converter: (object: T) => StringEntryObject,
|
|
|
|
|
objects: T[]
|
|
|
|
|
): string[] {
|
|
|
|
|
const values: Set<string> = new Set();
|
|
|
|
|
|
|
|
|
|
for (const object of objects) {
|
|
|
|
|
const stringEntryObject: StringEntryObject = converter(object);
|
|
|
|
|
const stringEntryObjectValue: string = stringEntryObject[key];
|
|
|
|
|
if (stringEntryObjectValue == undefined || stringEntryObjectValue == "")
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
values.add(stringEntryObjectValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return [...values.values()];
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-23 14:15:01 +02:00
|
|
|
// sorting
|
|
|
|
|
export class IndexManager<T> {
|
|
|
|
|
private itemToString: (item: T) => string;
|
|
|
|
|
|
|
|
|
|
sortedStrings: string[] = [];
|
|
|
|
|
|
|
|
|
|
// methods
|
|
|
|
|
update = (items: T[]): void => {
|
|
|
|
|
this.sortedStrings = [];
|
|
|
|
|
|
|
|
|
|
let strings: string[] = [];
|
|
|
|
|
for (const item of items) {
|
|
|
|
|
const string: string = this.itemToString(item);
|
|
|
|
|
strings.push(string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.sortedStrings = strings.sort(localeCompare);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
getIndex = (item: T): number => {
|
|
|
|
|
const string: string = this.itemToString(item);
|
|
|
|
|
const index: number = this.sortedStrings.indexOf(string);
|
|
|
|
|
return index;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// init
|
|
|
|
|
constructor(itemToString: (item: T) => string) {
|
|
|
|
|
this.itemToString = itemToString;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-19 19:49:55 +02:00
|
|
|
// string
|
2024-07-19 17:56:18 +02:00
|
|
|
export function stringify(data: any): string {
|
2024-07-20 20:42:43 +02:00
|
|
|
return JSON.stringify(data, null, 4);
|
2024-07-19 17:56:18 +02:00
|
|
|
}
|
|
|
|
|
|
2024-07-24 14:34:28 +02:00
|
|
|
export function padZero(string: string | undefined, length: number): string {
|
|
|
|
|
return (string ?? "").padStart(length, "0");
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-19 17:56:18 +02:00
|
|
|
export function parse(string: string): any {
|
2024-07-21 22:42:32 +02:00
|
|
|
try {
|
|
|
|
|
return JSON.parse(string);
|
|
|
|
|
} catch {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-22 01:40:00 +02:00
|
|
|
export function parseValidObject<T>(string: string, reference: T): T | null {
|
2024-07-21 22:42:32 +02:00
|
|
|
const parsed: any = parse(string);
|
|
|
|
|
if (checkIsValidObject(parsed) == false) return null;
|
2024-07-22 01:40:00 +02:00
|
|
|
|
|
|
|
|
const doesMatchReference: boolean = checkMatchesObjectStructure(
|
|
|
|
|
parsed,
|
|
|
|
|
reference
|
|
|
|
|
);
|
|
|
|
|
if (doesMatchReference == false) return null;
|
|
|
|
|
|
2024-07-21 22:42:32 +02:00
|
|
|
return parsed;
|
2024-07-19 19:49:55 +02:00
|
|
|
}
|
2024-07-20 18:58:25 +02:00
|
|
|
|
|
|
|
|
// sort
|
|
|
|
|
export function localeCompare(a: string, b: string): number {
|
|
|
|
|
return a.localeCompare(b);
|
2024-07-21 22:42:32 +02:00
|
|
|
}
|