1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Move all utility functions to separate package

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-03-02 09:39:29 -05:00
parent 83950f46ce
commit 13673eaac4
66 changed files with 210 additions and 274 deletions

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { join, nth, reduce, concat } from "../iter";
import { join, nth, reduce, concat } from "@k8slens/utilities/src/iter";
describe("iter", () => {
describe("reduce", () => {

View File

@ -1,13 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
/**
* A inference typed version of `Array(length).fill(value)`
* @param length The number of entries
* @param value The value of each of the indices
*/
export function filled<T>(length: number, value: T): T[] {
return Array(length).fill(value);
}

View File

@ -1,18 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Options } from "auto-bind";
import autoBindClass from "auto-bind";
import autoBindReactClass from "auto-bind/react";
import React from "react";
// Automatically bind methods to their class instance
export function autoBind<T extends object>(obj: T, opts?: Options): T {
if (obj instanceof React.Component) {
return autoBindReactClass(obj, opts);
}
return autoBindClass(obj, opts);
}

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectionToken } from "@ogre-tools/injectable";
import type { Disposer } from "../disposer";
import type { Disposer } from "@k8slens/utilities";
import type { MessageChannel, MessageChannelListener } from "./message-channel-listener-injection-token";
export type EnlistMessageChannelListener = (listener: MessageChannelListener<MessageChannel<unknown>>) => Disposer;

View File

@ -1,10 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
// Helper to sanitize / escape special chars for passing to RegExp-constructor
export function escapeRegExp(str: string) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

View File

@ -1,12 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
// Create random system name
export function getRandId({ prefix = "", suffix = "", sep = "_" } = {}) {
const randId = () => Math.random().toString(16).slice(2);
return [prefix, randId(), suffix].filter(s => s).join(sep);
}

View File

@ -3,50 +3,5 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export * from "./abort-controller";
export * from "./autobind";
export * from "./camelCase";
export * from "./cluster-id-url-parsing";
export * from "./collection-functions";
export * from "./convertCpu";
export * from "./convertMemory";
export * from "./debouncePromise";
export * from "./delay";
export * from "./disposer";
export * from "./escapeRegExp";
export * from "./formatDuration";
export * from "./getRandId";
export * from "./hash-set";
export * from "./n-fircate";
export * from "./noop";
export * from "./observable-crate/impl";
export * from "./promise-exec";
export * from "./readonly";
export * from "./reject-promise";
export * from "./singleton";
export * from "./sort-compare";
export * from "./splitArray";
export * from "./tar";
export * from "./toJS";
export * from "./type-narrowing";
export * from "./types";
export * from "./wait-for-path";
export * from "./wait";
export type { Tuple } from "./tuple";
import * as iter from "./iter";
import * as array from "./array";
import * as tuple from "./tuple";
import * as base64 from "./base64";
import * as object from "./objects";
import * as json from "./json";
export {
iter,
array,
tuple,
base64,
object,
json,
};

View File

@ -1,31 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { isPromise } from "./is-promise";
describe("isPromise", () => {
it("given promise, returns true", () => {
const actual = isPromise(new Promise(() => {}));
expect(actual).toBe(true);
});
it("given non-promise, returns false", () => {
const actual = isPromise({});
expect(actual).toBe(false);
});
it("given thenable, returns false", () => {
const actual = isPromise({ then: () => {} });
expect(actual).toBe(false);
});
it("given nothing, returns false", () => {
const actual = isPromise(undefined);
expect(actual).toBe(false);
});
});

View File

@ -1,7 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export function isPromise(reference: any): reference is Promise<any> {
return reference?.constructor === Promise;
}

View File

@ -1,10 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { JsonValue } from "type-fest";
export function parse(input: string): JsonValue {
return JSON.parse(input);
}

View File

@ -1,36 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
/**
* Split an iterable into several arrays with matching fields
* @param from The iterable of items to split up
* @param field The field of each item to split over
* @param parts What each array will be filtered to
* @returns A `parts.length` tuple of `T[]` where each array has matching `field` values
*/
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: []): [];
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: [T[typeof field]]): [T[]];
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: [T[typeof field], T[typeof field]]): [T[], T[]];
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: [T[typeof field], T[typeof field], T[typeof field]]): [T[], T[], T[]];
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: T[typeof field][]): T[][] {
if (new Set(parts).size !== parts.length) {
throw new TypeError("Duplicate parts entries");
}
const res = Array.from(parts, () => [] as T[]);
for (const item of from) {
const index = parts.indexOf(item[field]);
if (index < 0) {
continue;
}
res[index].push(item);
}
return res;
}

View File

@ -1,9 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import * as util from "util";
import { execFile } from "child_process";
export const promiseExecFile = util.promisify(execFile);

View File

@ -4,7 +4,6 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import logErrorInjectable from "../../log-error.injectable";
import { isPromise } from "../is-promise/is-promise";
export type WithErrorLoggingFor = (
getErrorMessage: (error: unknown) => string
@ -33,7 +32,7 @@ const withErrorLoggingInjectable = getInjectable({
throw e;
}
if (isPromise(returnValue)) {
if ((returnValue as any) instanceof Promise) {
return returnValue.catch((e: unknown) => {
const errorMessage = getErrorMessage(e);

View File

@ -12,7 +12,7 @@ export function withErrorSuppression(toBeDecorated: any) {
try {
const returnValue = toBeDecorated(...args);
if (isPromise(returnValue)) {
if ((returnValue as any) instanceof Promise) {
return returnValue.catch(noop);
}
@ -22,7 +22,3 @@ export function withErrorSuppression(toBeDecorated: any) {
}
};
}
function isPromise(reference: any): reference is Promise<any> {
return !!reference?.then;
}

View File

@ -1,20 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
// Common usage utils & helpers
export * from "../../common/utils";
export * from "../../common/event-emitter";
export * from "./cssNames";
export * from "./cssVar";
export * from "./display-mode";
export * from "./interval";
export * from "./isMiddleClick";
export * from "./isReactNode";
export * from "./metricUnitsToNumber";
export * from "./name-parts";
export * from "./prevDefault";
export * from "./saveFile";
export * from "./storage-helper";

View File

@ -0,0 +1,3 @@
# @k8slens/utilities
This package contains many useful types.

View File

@ -0,0 +1,45 @@
export * from "./src/abort-controller";
export * from "./src/backoff-caller";
export * from "./src/camelCase";
export * from "./src/collection-functions";
export * from "./src/computed-or";
export * from "./src/convertCpu";
export * from "./src/convertMemory";
export * from "./src/cssNames";
export * from "./src/cssVar";
export * from "./src/debouncePromise";
export * from "./src/delay";
export * from "./src/display-mode";
export * from "./src/disposer";
export * from "./src/formatDuration";
export * from "./src/hash-set";
export * from "./src/interval";
export * from "./src/is-node-falsy";
export * from "./src/isMiddleClick";
export * from "./src/isReactNode";
export * from "./src/json";
export * from "./src/jsonPath";
export * from "./src/metricUnitsToNumber";
export * from "./src/name-parts";
export * from "./src/noop";
export * from "./src/observable-crate";
export * from "./src/on-keyboard-shortcut";
export * from "./src/prevDefault";
export * from "./src/readableStream";
export * from "./src/readonly";
export * from "./src/reject-promise";
export * from "./src/result";
export * from "./src/sort-compare";
export * from "./src/sort-function";
export * from "./src/tar";
export * from "./src/tuple";
export * from "./src/type-narrowing";
export * from "./src/types";
export * from "./src/union-env-path";
export * from "./src/wait";
export * from "./src/with-concurrency-limit";
export * as iter from "./src/iter";
export * as array from "./src/array";
export * as object from "./src/object";
export * as base64 from "./src/base64";

View File

@ -0,0 +1,2 @@
module.exports =
require("@k8slens/jest").monorepoPackageConfig(__dirname).configForReact;

View File

@ -0,0 +1,31 @@
{
"name": "@k8slens/utilities",
"description": "A collection of useful types",
"version": "1.0.0",
"type": "commonjs",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"private": false,
"files": [
"dist"
],
"author": {
"name": "OpenLens Authors",
"email": "info@k8slens.dev"
},
"license": "MIT",
"homepage": "https://github.com/lensapp/lens",
"scripts": {
"build": "webpack",
"dev": "webpack --mode=development --watch",
"test": "jest --coverage --runInBand"
},
"peerDependencies": {
"mobx": "^6.8.0",
"type-fest": "^2.19.0"
}
}

View File

@ -3,6 +3,15 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
/**
* A inference typed version of `Array(length).fill(value)`
* @param length The number of entries
* @param value The value of each of the indices
*/
export function filled<T>(length: number, value: T): T[] {
return Array(length).fill(value);
}
/**
* This function splits an array into two sub arrays on the first instance of
* element (from the left). If the array does not contain the element. The
@ -14,29 +23,27 @@
* @returns the left and right sub-arrays which when conjoined with `element`
* is the same as `array`, and `true`
*/
export function splitArray<T>(array: T[], element: T): [T[], T[], boolean] {
const index = array.indexOf(element);
export function split<T>(src: T[], element: T): [T[], T[], boolean] {
const index = src.indexOf(element);
if (index < 0) {
return [array, [], false];
return [src, [], false];
}
return [array.slice(0, index), array.slice(index + 1, array.length), true];
return [src.slice(0, index), src.slice(index + 1, src.length), true];
}
/**
* Splits an array into two parts based on the outcome of `condition`. If `true`
* the value will be returned as part of the right array. If `false` then part of
* the left array.
* @param src the full array to bifurcate
* @param condition the function to determine which set each is in
*/
export function bifurcateArray<T>(src: T[], condition: (item: T) => boolean): [falses: T[], trues: T[]] {
const res: [T[], T[]] = [[], []];
export function bifurcate<T>(src: T[], condition: (item: T) => any): [falses: T[], trues: T[]] {
const trues: T[] = [];
const falses: T[] = [];
for (const item of src) {
res[+condition(item)].push(item);
if (condition(item)) {
trues.push(item);
} else {
falses.push(item);
}
}
return res;
return [falses, trues];
}

View File

@ -5,7 +5,7 @@
import type { AsyncResult } from "./async-result";
import { delay } from "./delay";
import { noop } from "./noop";
import { noop } from "@k8slens/utilities/src/noop";
/**
* @param error The error that resulted in the failure

View File

@ -7,7 +7,7 @@
import { camelCase } from "lodash";
import type { SingleOrMany } from "./types";
import { isObject, isString } from "./type-narrowing";
import * as object from "./objects";
import * as object from "./object";
export function toCamelCase<T extends Record<string, unknown>[]>(obj: T): T;
export function toCamelCase<T extends Record<string, unknown>>(obj: T): T;

View File

@ -19,7 +19,6 @@ export function getOrInsert<K, V>(map: Map<K, V>, key: K, value: V): V {
map.set(key, value);
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return map.get(key)!;
}
@ -67,7 +66,6 @@ export function getOrInsertWith<K extends object, V>(map: Map<K, V> | WeakMap<K,
map.set(key, builder());
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return map.get(key)!;
}
@ -107,7 +105,6 @@ export function strictGet<K, V>(map: Map<K, V>, key: K): V {
throw new TypeError(`Map does not contains key: ${inspect(key)}`);
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return map.get(key)!;
}

View File

@ -4,7 +4,7 @@
*/
import assert from "assert";
import * as iter from "./iter";
import { iter } from "@k8slens/utilities";
// Helper to convert memory from units Ki, Mi, Gi, Ti, Pi to bytes and vise versa

View File

@ -3,7 +3,9 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { iter } from "../../common/utils";
import * as iter from "./iter";
import * as object from "./object";
import { isObject } from "./type-narrowing";
export type IgnoredClassNames = number | symbol | Function;
export type IClassName = string | string[] | Record<string, any> | undefined | null | false | IgnoredClassNames;
@ -18,15 +20,15 @@ export function cssNames(...classNames: IClassName[]): string {
for (const name of className) {
classNamesEnabled.set(name, true);
}
} else if (className && typeof className === "object") {
for (const [name, value] of Object.entries(className)) {
} else if (isObject(className)) {
for (const [name, value] of object.entries(className)) {
classNamesEnabled.set(name, Boolean(value));
}
}
}
return iter.chain(classNamesEnabled.entries())
.filter(([, isActive]) => !!isActive)
.filter(([, isActive]) => isActive)
.filterMap(([className]) => className.trim())
.join(" ");
}

View File

@ -10,6 +10,6 @@ export function debouncePromise<T, F extends any[]>(func: (...args: F) => T | Pr
return (...params: F) => new Promise(resolve => {
clearTimeout(timer);
timer = global.setTimeout(() => resolve(func(...params)), timeout);
timer = setTimeout(() => resolve(func(...params)), timeout);
});
}

View File

@ -5,8 +5,6 @@
import type { SingleOrMany } from "./types";
export interface Disposer {
(): void;
}
@ -16,7 +14,7 @@ export interface Disposable {
}
export interface ExtendableDisposer extends Disposer {
push(...vals: (Disposer | ExtendableDisposer | Disposable)[]): void;
push(...values: (Disposer | ExtendableDisposer | Disposable)[]): void;
}
export function disposer(...items: SingleOrMany<Disposer | Disposable | undefined | null>[]): ExtendableDisposer {

View File

@ -3,11 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export type Falsey = false | 0 | "" | null | undefined;
export type Falsy = false | 0 | "" | null | undefined;
interface Iterator<T> extends Iterable<T> {
filter(fn: (val: T) => unknown): Iterator<T>;
filterMap<U>(fn: (val: T) => Falsey | U): Iterator<U>;
filterMap<U>(fn: (val: T) => Falsy | U): Iterator<U>;
find(fn: (val: T) => unknown): T | undefined;
collect<U>(fn: (values: Iterable<T>) => U): U;
map<U>(fn: (val: T) => U): Iterator<U>;
@ -67,11 +67,11 @@ export function* map<T, U>(src: Iterable<T>, fn: (from: T) => U): IterableIterat
}
/**
* The single layer flattening of an iterator, discarding `Falsey` values.
* The single layer flattening of an iterator, discarding `Falsy` values.
* @param src A type that can be iterated over
* @param fn The function that returns either an iterable over items that should be filtered out or a `Falsey` value indicating that it should be ignored
* @param fn The function that returns either an iterable over items that should be filtered out or a `Falsy` value indicating that it should be ignored
*/
export function* filterFlatMap<T, U>(src: Iterable<T>, fn: (from: T) => Iterable<U | Falsey> | Falsey): IterableIterator<U> {
export function* filterFlatMap<T, U>(src: Iterable<T>, fn: (from: T) => Iterable<U | Falsy> | Falsy): IterableIterator<U> {
for (const from of src) {
if (!from) {
continue;
@ -122,7 +122,7 @@ export function* filter<T>(src: Iterable<T>, fn: (from: T) => any): IterableIter
* @param src A type that can be iterated over
* @param fn The function that is called for each value
*/
export function* filterMap<T, U>(src: Iterable<T>, fn: (from: T) => U | Falsey): IterableIterator<U> {
export function* filterMap<T, U>(src: Iterable<T>, fn: (from: T) => U | Falsy): IterableIterator<U> {
for (const from of src) {
const res = fn(from);
@ -166,9 +166,9 @@ export function find<T>(src: Iterable<T>, match: (i: T) => any): T | undefined {
/**
* Iterate over `src` calling `reducer` with the previous produced value and the current
* yielded value until `src` is exausted. Then return the final value.
* yielded value until `src` is exhausted. Then return the final value.
* @param src The value to iterate over
* @param reducer A function for producing the next item from an accumilation and the current item
* @param reducer A function for producing the next item from an accumulation and the current item
* @param initial The initial value for the iteration
*/
export function reduce<T, R extends Iterable<any>>(src: Iterable<T>, reducer: (acc: R, cur: T) => R, initial: R): R;
@ -224,7 +224,7 @@ export function first<T>(src: Iterable<T>): T | undefined {
}
/**
* Iterate through `src` and return `true` if `fn` returns a thruthy value for every yielded value.
* Iterate through `src` and return `true` if `fn` returns a truthy value for every yielded value.
* Otherwise, return `false`. This function short circuits.
* @param src The type to be iterated over
* @param fn A function to check each iteration
@ -246,3 +246,35 @@ export function* concat<T>(...sources: IterableIterator<T>[]): IterableIterator<
}
}
}
/**
* Split an iterable into several arrays with matching fields
* @param from The iterable of items to split up
* @param field The field of each item to split over
* @param parts What each array will be filtered to
* @returns A `parts.length` tuple of `T[]` where each array has matching `field` values
*/
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: []): [];
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: [T[typeof field]]): [T[]];
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: [T[typeof field], T[typeof field]]): [T[], T[]];
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: [T[typeof field], T[typeof field], T[typeof field]]): [T[], T[], T[]];
export function nFircate<T>(from: Iterable<T>, field: keyof T, parts: T[typeof field][]): T[][] {
if (new Set(parts).size !== parts.length) {
throw new TypeError("Duplicate parts entries");
}
const res = Array.from(parts, () => [] as T[]);
for (const item of from) {
const index = parts.indexOf(item[field]);
if (index < 0) {
continue;
}
res[index].push(item);
}
return res;
}

View File

@ -0,0 +1,22 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Result } from "./result";
export const json = {
parse: (input: string): Result<unknown, Error> => {
try {
return {
callWasSuccessful: true,
response: JSON.parse(input) as unknown,
}
} catch (error) {
return {
callWasSuccessful: false,
error: error as Error,
}
}
},
};

View File

@ -2,9 +2,11 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
/**
* A function that does nothing
*/
export function noop<T extends any[]>(...args: T): void {
return void args;
}

View File

@ -12,7 +12,6 @@ export function fromEntries<T, Key extends string>(entries: Iterable<readonly [K
}
export function keys<K extends keyof any>(obj: Partial<Record<K, any>>): K[];
export function keys<K extends keyof any>(obj: Record<K, any>): K[] {
return Object.keys(obj) as K[];
}
@ -20,7 +19,6 @@ export function keys<K extends keyof any>(obj: Record<K, any>): K[] {
export function entries<K extends string, V>(obj: Partial<Record<K, V>> | null | undefined): [K, V][];
export function entries<K extends string | number | symbol, V>(obj: Partial<Record<K, V>> | null | undefined): [K, V][];
export function entries<K extends string | number | symbol, V>(obj: Record<K, V> | null | undefined): [K, V][];
export function entries<K extends string | number | symbol, V>(obj: Record<K, V> | null | undefined): [K, V][] {
if (obj && typeof obj == "object") {
return Object.entries(obj) as never;

View File

@ -3,8 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { ObservableCrate } from "./impl";
import { observableCrate } from "./impl";
import type { ObservableCrate } from "./observable-crate";
import { observableCrate } from "./observable-crate";
describe("observable-crate", () => {
it("can be constructed with initial value", () => {

View File

@ -4,8 +4,8 @@
*/
import { observable, runInAction } from "mobx";
import { getOrInsertMap } from "../collection-functions";
import { noop } from "../noop";
import { getOrInsertMap } from "./collection-functions";
import { noop } from "./noop";
export interface ObservableCrate<T> {
get(): T;

View File

@ -2,7 +2,17 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export type AsyncResult<Response, Error = string> =
/**
* A helper type for async functions that return a `Result`
*/
export type AsyncResult<Response, Error = string> = Promise<Result<Response, Error>>;
/**
* Result describes the "error is just more data" pattern instead of using exceptions for
* normal execution
*/
export type Result<Response, Error = string> =
| (
Response extends void
? { callWasSuccessful: true; response?: undefined }

View File

@ -7,7 +7,6 @@
// Docs: https://github.com/npm/node-tar
import tar from "tar";
import path from "path";
import { parse } from "./json";
import type { JsonValue } from "type-fest";
export type ReadFileFromTarOpts<ParseJson extends boolean> = {
@ -43,7 +42,7 @@ export function readFileFromTar<ParseJson extends boolean>({ tarPath, filePath,
});
entry.once("end", () => {
const data = Buffer.concat(fileChunks);
const result = parseJson ? parse(data.toString("utf8")) : data;
const result = parseJson ? JSON.parse(data.toString("utf8")) : data;
resolve(result);
});

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import * as array from "../utils/array";
import * as array from "./array";
/**
* A strict N-tuple of type T

View File

@ -14,7 +14,7 @@ export type RemoveUndefinedFromValues<K> = {
*/
export type Defaulted<Params, DefaultParams extends keyof Params> = RemoveUndefinedFromValues<Required<Pick<Params, DefaultParams>>> & Omit<Params, DefaultParams>;
export type OptionVarient<Key, Base, RequiredKey extends keyof Base> = {
export type OptionVariant<Key, Base, RequiredKey extends keyof Base> = {
type: Key;
} & Pick<Base, RequiredKey> & {
[OtherKey in Exclude<keyof Base, RequiredKey>]?: undefined;

View File

@ -4,10 +4,10 @@
*/
import path from "path";
import * as iter from "./iter";
import * as iter from "@k8slens/utilities/src/iter";
/**
* Join all entires with a PATH env var delimated string together
* Join all entires with a PATH env var delimited string together
* @param PATHs Any number of PATH env variables
*
* NOTE: This function does not attempt to handle any sort of escape sequences since after testing

View File

@ -4,7 +4,7 @@
*/
import type { IComputedValue } from "mobx";
import { runInAction, when } from "mobx";
import type { Disposer } from "./disposer";
import type { Disposer } from "@k8slens/utilities";
export async function waitUntilDefined<T>(getter: (() => T | null | undefined) | IComputedValue<T | null | undefined>, opts?: { timeout?: number }): Promise<T> {
return new Promise<T>((resolve, reject) => {

View File

@ -2,12 +2,12 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import plimit from "p-limit";
import pLimit from "p-limit";
export type ConcurrencyLimiter = <Args extends any[], Res>(fn: (...args: Args) => Res) => (...args: Args) => Promise<Res>;
export function withConcurrencyLimit(limit: number): ConcurrencyLimiter {
const limiter = plimit(limit);
const limiter = pLimit(limit);
return fn => (...args) => limiter(() => fn(...args));
}

View File

@ -0,0 +1,3 @@
{
"extends": "@k8slens/typescript/config/base.json"
}

View File

@ -0,0 +1 @@
module.exports = require("@k8slens/webpack").configForNode;