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. * 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("iter", () => {
describe("reduce", () => { 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. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
import { getInjectionToken } from "@ogre-tools/injectable"; 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"; import type { MessageChannel, MessageChannelListener } from "./message-channel-listener-injection-token";
export type EnlistMessageChannelListener = (listener: MessageChannelListener<MessageChannel<unknown>>) => Disposer; 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. * 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 "./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 "./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 { getInjectable } from "@ogre-tools/injectable";
import logErrorInjectable from "../../log-error.injectable"; import logErrorInjectable from "../../log-error.injectable";
import { isPromise } from "../is-promise/is-promise";
export type WithErrorLoggingFor = ( export type WithErrorLoggingFor = (
getErrorMessage: (error: unknown) => string getErrorMessage: (error: unknown) => string
@ -33,7 +32,7 @@ const withErrorLoggingInjectable = getInjectable({
throw e; throw e;
} }
if (isPromise(returnValue)) { if ((returnValue as any) instanceof Promise) {
return returnValue.catch((e: unknown) => { return returnValue.catch((e: unknown) => {
const errorMessage = getErrorMessage(e); const errorMessage = getErrorMessage(e);

View File

@ -12,7 +12,7 @@ export function withErrorSuppression(toBeDecorated: any) {
try { try {
const returnValue = toBeDecorated(...args); const returnValue = toBeDecorated(...args);
if (isPromise(returnValue)) { if ((returnValue as any) instanceof Promise) {
return returnValue.catch(noop); 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. * 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 * 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 * 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` * @returns the left and right sub-arrays which when conjoined with `element`
* is the same as `array`, and `true` * is the same as `array`, and `true`
*/ */
export function splitArray<T>(array: T[], element: T): [T[], T[], boolean] { export function split<T>(src: T[], element: T): [T[], T[], boolean] {
const index = array.indexOf(element); const index = src.indexOf(element);
if (index < 0) { 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];
} }
/** export function bifurcate<T>(src: T[], condition: (item: T) => any): [falses: T[], trues: T[]] {
* Splits an array into two parts based on the outcome of `condition`. If `true` const trues: T[] = [];
* the value will be returned as part of the right array. If `false` then part of const falses: T[] = [];
* 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[]] = [[], []];
for (const item of src) { 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 type { AsyncResult } from "./async-result";
import { delay } from "./delay"; import { delay } from "./delay";
import { noop } from "./noop"; import { noop } from "@k8slens/utilities/src/noop";
/** /**
* @param error The error that resulted in the failure * @param error The error that resulted in the failure

View File

@ -7,7 +7,7 @@
import { camelCase } from "lodash"; import { camelCase } from "lodash";
import type { SingleOrMany } from "./types"; import type { SingleOrMany } from "./types";
import { isObject, isString } from "./type-narrowing"; 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;
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); map.set(key, value);
} }
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return map.get(key)!; 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()); map.set(key, builder());
} }
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return map.get(key)!; 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)}`); throw new TypeError(`Map does not contains key: ${inspect(key)}`);
} }
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return map.get(key)!; return map.get(key)!;
} }

View File

@ -4,7 +4,7 @@
*/ */
import assert from "assert"; 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 // 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. * 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 IgnoredClassNames = number | symbol | Function;
export type IClassName = string | string[] | Record<string, any> | undefined | null | false | IgnoredClassNames; 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) { for (const name of className) {
classNamesEnabled.set(name, true); classNamesEnabled.set(name, true);
} }
} else if (className && typeof className === "object") { } else if (isObject(className)) {
for (const [name, value] of Object.entries(className)) { for (const [name, value] of object.entries(className)) {
classNamesEnabled.set(name, Boolean(value)); classNamesEnabled.set(name, Boolean(value));
} }
} }
} }
return iter.chain(classNamesEnabled.entries()) return iter.chain(classNamesEnabled.entries())
.filter(([, isActive]) => !!isActive) .filter(([, isActive]) => isActive)
.filterMap(([className]) => className.trim()) .filterMap(([className]) => className.trim())
.join(" "); .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 => { return (...params: F) => new Promise(resolve => {
clearTimeout(timer); 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"; import type { SingleOrMany } from "./types";
export interface Disposer { export interface Disposer {
(): void; (): void;
} }
@ -16,7 +14,7 @@ export interface Disposable {
} }
export interface ExtendableDisposer extends Disposer { 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 { 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. * 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> { interface Iterator<T> extends Iterable<T> {
filter(fn: (val: T) => unknown): Iterator<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; find(fn: (val: T) => unknown): T | undefined;
collect<U>(fn: (values: Iterable<T>) => U): U; collect<U>(fn: (values: Iterable<T>) => U): U;
map<U>(fn: (val: T) => U): Iterator<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 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) { for (const from of src) {
if (!from) { if (!from) {
continue; 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 src A type that can be iterated over
* @param fn The function that is called for each value * @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) { for (const from of src) {
const res = fn(from); 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 * 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 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 * @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; 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. * Otherwise, return `false`. This function short circuits.
* @param src The type to be iterated over * @param src The type to be iterated over
* @param fn A function to check each iteration * @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. * Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
/** /**
* A function that does nothing * A function that does nothing
*/ */
export function noop<T extends any[]>(...args: T): void { export function noop<T extends any[]>(...args: T): void {
return void args; 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: Partial<Record<K, any>>): K[];
export function keys<K extends keyof any>(obj: Record<K, any>): K[] { export function keys<K extends keyof any>(obj: Record<K, any>): K[] {
return Object.keys(obj) as 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, 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: 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][];
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") { if (obj && typeof obj == "object") {
return Object.entries(obj) as never; return Object.entries(obj) as never;

View File

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

View File

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

View File

@ -2,7 +2,17 @@
* Copyright (c) OpenLens Authors. All rights reserved. * Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information. * 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 Response extends void
? { callWasSuccessful: true; response?: undefined } ? { callWasSuccessful: true; response?: undefined }

View File

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

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information. * 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 * 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 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; type: Key;
} & Pick<Base, RequiredKey> & { } & Pick<Base, RequiredKey> & {
[OtherKey in Exclude<keyof Base, RequiredKey>]?: undefined; [OtherKey in Exclude<keyof Base, RequiredKey>]?: undefined;

View File

@ -4,10 +4,10 @@
*/ */
import path from "path"; 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 * @param PATHs Any number of PATH env variables
* *
* NOTE: This function does not attempt to handle any sort of escape sequences since after testing * 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 type { IComputedValue } from "mobx";
import { runInAction, when } 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> { export async function waitUntilDefined<T>(getter: (() => T | null | undefined) | IComputedValue<T | null | undefined>, opts?: { timeout?: number }): Promise<T> {
return new Promise<T>((resolve, reject) => { return new Promise<T>((resolve, reject) => {

View File

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