1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/packages/utility-features/utilities/src/collection-functions.ts
Sebastian Malton fe2fd4c1fd
Move Cluster.apiUrl to seperate injectable (#7354)
* Refactor out Cluster.apiUrl to direct reading

- Should help prevent using stale data

- Removes some uses of synchronous FS operations

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix type errors

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Rename helper function to better communicate intent

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Improve prometheus handler tests to override less things

Signed-off-by: Sebastian Malton <sebastian@malton.name>

---------

Signed-off-by: Sebastian Malton <sebastian@malton.name>
2023-03-31 15:28:14 -04:00

144 lines
3.9 KiB
TypeScript

/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { runInAction } from "mobx";
import { inspect } from "util";
import { isDefined } from "./type-narrowing";
/**
* Get the value behind `key`. If it was not present, first insert `value`
* @param map The map to interact with
* @param key The key to insert into the map with
* @param value The value to optional add to the map
* @returns The value in the map
*/
export function getOrInsert<K, V>(map: Map<K, V>, key: K, value: V): V {
if (!map.has(key)) {
map.set(key, value);
}
return map.get(key)!;
}
/**
* Updates map and returns the value that was just inserted
*/
export function put<K, V>(map: Map<K, V>, key: K, value: V): V {
map.set(key, value);
return value;
}
/**
* Like `getOrInsert` but specifically for when `V` is `Map<MK, MV>` so that
* the typings are inferred correctly.
*/
export function getOrInsertMap<K, MK, MV>(map: Map<K, Map<MK, MV>>, key: K): Map<MK, MV> {
return getOrInsert(map, key, new Map<MK, MV>());
}
/**
* Like `getOrInsert` but specifically for when `V` is `Set<any>` so that
* the typings are inferred.
*/
export function getOrInsertSet<K, SK>(map: Map<K, Set<SK>>, key: K): Set<SK> {
return getOrInsert(map, key, new Set<SK>());
}
/**
* A currying version of {@link getOrInsertSet}
*/
export function getOrInsertSetFor<K, SK>(map: Map<K, Set<SK>>): (key: K) => Set<SK> {
return (key) => getOrInsertSet(map, key);
}
/**
* Like `getOrInsert` but with delayed creation of the item. Which is useful
* if it is very expensive to create the initial value.
*/
export function getOrInsertWith<K, V>(map: Map<K, V>, key: K, builder: () => V): V;
export function getOrInsertWith<K extends object, V>(map: Map<K, V> | WeakMap<K, V>, key: K, builder: () => V): V;
export function getOrInsertWith<K extends object, V>(map: Map<K, V> | WeakMap<K, V>, key: K, builder: () => V): V {
if (!map.has(key)) {
map.set(key, builder());
}
return map.get(key)!;
}
/**
* Like {@link getOrInsertWith} but the builder is async and will be awaited before inserting into the map
*/
export async function getOrInsertWithAsync<K, V>(map: Map<K, V>, key: K, asyncBuilder: () => Promise<V>): Promise<V> {
if (!map.has(key)) {
const newValue = await asyncBuilder();
runInAction(() => {
map.set(key, newValue);
});
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return map.get(key)!;
}
/**
* Insert `val` into `map` under `key` and then get the value back
*/
export function setAndGet<K, V>(map: Map<K, V>, key: K, val: V): V {
map.set(key, val);
return map.get(key)!;
}
/**
* Set the value associated with `key` iff there was not a previous value
* @param map The map to interact with
* @throws if `key` already in map
* @returns `this` so that `strictSet` can be chained
*/
export function strictSet<K, V>(map: Map<K, V>, key: K, val: V): typeof map {
if (map.has(key)) {
throw new TypeError(`Map already contains key: ${inspect(key)}`);
}
return map.set(key, val);
}
/**
* Get the value associated with `key`
* @param map The map to interact with
* @throws if `key` did not a value associated with it
*/
export function strictGet<K, V>(map: Map<K, V>, key: K): V {
if (!map.has(key)) {
throw new TypeError(`Map does not contains key: ${inspect(key)}`);
}
return map.get(key)!;
}
/**
* If `key` is in `set`, remove it otherwise add it.
* @param set The set to manipulate
* @param key The key to toggle the "is in"-ness of
*/
export function toggle<K>(set: Set<K>, key: K): void {
runInAction(() => {
// Returns true if value was already in Set; otherwise false.
if (!set.delete(key)) {
set.add(key);
}
});
}
/**
* A helper function to also check for defined-ness
*/
export function includes<T>(src: T[], value: T | null | undefined): boolean {
return isDefined(value) && src.includes(value);
}