|
|
import { FluentConfiguration } from "./FluentConfiguration";
|
|
|
import { IDestroyable } from "./interfaces";
|
|
|
|
|
|
export function fluent<S extends object = object>() {
|
|
|
return new FluentConfiguration<S>();
|
|
|
}
|
|
|
|
|
|
export type key = string | number | symbol;
|
|
|
|
|
|
export const isKey = (v: unknown): v is key =>
|
|
|
typeof v === "string" || typeof v === "number" || typeof v === "symbol";
|
|
|
|
|
|
export const isString = (v: unknown): v is string =>
|
|
|
typeof v === "string";
|
|
|
|
|
|
|
|
|
export const isNotNull = <T>(v: T): v is NonNullable<T> => v !== null && v !== undefined;
|
|
|
|
|
|
export const each = <T extends object>(obj: T, cb: <X extends Extract<keyof T, string>>(v: NonNullable<T[X]>, k: X) => void) =>
|
|
|
(Object.keys(obj) as (Extract<keyof T, string>)[])
|
|
|
.forEach(k => {
|
|
|
const v = obj[k];
|
|
|
isNotNull(v) && cb(v, k);
|
|
|
});
|
|
|
|
|
|
export const argumentNotNull = (arg: unknown, name: string) => {
|
|
|
if (arg === null || arg === undefined)
|
|
|
throw new Error("The argument " + name + " can't be null or undefined");
|
|
|
};
|
|
|
|
|
|
export const isPromise = <T = unknown>(val: unknown): val is PromiseLike<T> =>
|
|
|
isNotNull(val) && typeof (val as PromiseLike<T>).then === "function";
|
|
|
|
|
|
export const isDestroyable = (d: unknown): d is IDestroyable =>
|
|
|
isNotNull(d) && typeof (d as IDestroyable).destroy === "function";
|
|
|
|
|
|
let _nextOid = 0;
|
|
|
const _oid = typeof Symbol === "function" ?
|
|
|
Symbol.for("__implab__oid__") :
|
|
|
"__implab__oid__";
|
|
|
|
|
|
type OidSlot = { [k in typeof _oid]?: string };
|
|
|
|
|
|
export const oid = <T extends object>(instance: T): string => {
|
|
|
argumentNotNull(instance, "instance");
|
|
|
const val = (instance as OidSlot)[_oid];
|
|
|
|
|
|
return val ? val : ((instance as OidSlot)[_oid] = `oid_${++_nextOid}`);
|
|
|
};
|