UNPKG

@oxog/kindof

Version:

Zero-dependency advanced type detection library with TypeScript support, plugin system, and 100% test coverage

2,173 lines 70.8 kB
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.kindOf = {}));
})(this, (function (exports) { 'use strict';

  const TYPE_TAG_MAP = {
    "[object Arguments]": "arguments",
    "[object Array]": "array",
    "[object ArrayBuffer]": "arraybuffer",
    "[object AsyncFunction]": "asyncfunction",
    "[object AsyncGeneratorFunction]": "asyncgeneratorfunction",
    "[object BigInt]": "bigint",
    "[object BigInt64Array]": "bigint64array",
    "[object BigUint64Array]": "biguint64array",
    "[object Boolean]": "boolean",
    "[object DataView]": "dataview",
    "[object Date]": "date",
    "[object Error]": "error",
    "[object Float32Array]": "float32array",
    "[object Float64Array]": "float64array",
    "[object Function]": "function",
    "[object GeneratorFunction]": "generatorfunction",
    "[object Int8Array]": "int8array",
    "[object Int16Array]": "int16array",
    "[object Int32Array]": "int32array",
    "[object Map]": "map",
    "[object Number]": "number",
    "[object Object]": "object",
    "[object Promise]": "promise",
    "[object Proxy]": "proxy",
    "[object RegExp]": "regexp",
    "[object Set]": "set",
    "[object SharedArrayBuffer]": "sharedarraybuffer",
    "[object String]": "string",
    "[object Symbol]": "symbol",
    "[object Uint8Array]": "uint8array",
    "[object Uint8ClampedArray]": "uint8clampedarray",
    "[object Uint16Array]": "uint16array",
    "[object Uint32Array]": "uint32array",
    "[object WeakMap]": "weakmap",
    "[object WeakSet]": "weakset",
    "[object Window]": "window",
    "[object HTMLDocument]": "document",
    "[object Document]": "document",
    "[object Null]": "null",
    "[object Undefined]": "undefined"
  };

  const toString$1 = Object.prototype.toString;
  const toStringTag = Symbol.toStringTag;
  function getNativeType(value) {
    if (value === void 0) return "undefined";
    if (value === null) return "null";
    const primitiveType = typeof value;
    switch (primitiveType) {
      case "boolean":
        return "boolean";
      case "number":
        return "number";
      case "string":
        return "string";
      case "symbol":
        return "symbol";
      case "bigint":
        return "bigint";
      case "function":
        return getFunctionType(value);
      case "object":
        return getObjectType(value);
      default:
        return null;
    }
  }
  function getFunctionType(fn) {
    var _a;
    const fnString = fn.toString();
    if (/^class\s/.test(fnString)) {
      return "function";
    }
    if (/^async\s*function\s*\*/.test(fnString) || /^async\s*\*/.test(fnString)) {
      return "asyncgeneratorfunction";
    }
    if (/^async\s/.test(fnString)) {
      return "asyncfunction";
    }
    if (/^function\s*\*/.test(fnString) || /^\*/.test(fnString)) {
      return "generatorfunction";
    }
    const ctorName = (_a = fn.constructor) == null ? void 0 : _a.name;
    if (ctorName === "AsyncFunction") return "asyncfunction";
    if (ctorName === "GeneratorFunction") return "generatorfunction";
    if (ctorName === "AsyncGeneratorFunction") return "asyncgeneratorfunction";
    return "function";
  }
  function getObjectType(obj) {
    const tag = toString$1.call(obj);
    const mappedType = TYPE_TAG_MAP[tag];
    if (mappedType) {
      return mappedType;
    }
    if (typeof Buffer !== "undefined" && Buffer.isBuffer && Buffer.isBuffer(obj)) {
      return "buffer";
    }
    if (typeof obj === "object" && "callee" in obj && typeof obj.callee === "function") {
      return "arguments";
    }
    if (isStream$1(obj)) {
      return "stream";
    }
    if (isEventEmitter$1(obj)) {
      return "eventemitter";
    }
    if (tag === "[object Object]") {
      const customTag = obj[toStringTag];
      if (typeof customTag === "string") {
        return customTag.toLowerCase();
      }
      const ctor = obj.constructor;
      if (ctor && ctor !== Object) {
        const ctorName = ctor.name;
        if (ctorName && ctorName !== "Object") {
          return ctorName.toLowerCase();
        }
      }
    }
    if (isDOMElement(obj)) {
      return "element";
    }
    if (isDOMNode(obj)) {
      return "node";
    }
    if (isGlobal$1(obj)) {
      return "global";
    }
    return "object";
  }
  function isStream$1(obj) {
    return obj !== null && typeof obj === "object" && typeof obj.pipe === "function";
  }
  function isEventEmitter$1(obj) {
    return obj !== null && typeof obj === "object" && typeof obj.on === "function" && typeof obj.emit === "function" && typeof obj.removeListener === "function";
  }
  function isDOMElement(obj) {
    if (typeof HTMLElement === "undefined") return false;
    return obj instanceof HTMLElement;
  }
  function isDOMNode(obj) {
    if (typeof Node === "undefined") return false;
    return obj instanceof Node;
  }
  function isGlobal$1(obj) {
    if (typeof globalThis !== "undefined" && obj === globalThis) return true;
    if (typeof global !== "undefined" && obj === global) return true;
    if (typeof window !== "undefined" && obj === window) return true;
    if (typeof self !== "undefined" && obj === self) return true;
    return false;
  }

  const WeakMapPrototype = WeakMap.prototype;
  const WeakSetPrototype = WeakSet.prototype;
  const MapPrototype = Map.prototype;
  const SetPrototype = Set.prototype;
  const ArrayBufferPrototype = ArrayBuffer.prototype;
  const DataViewPrototype = DataView.prototype;
  const SharedArrayBufferPrototype = typeof SharedArrayBuffer !== "undefined" ? SharedArrayBuffer.prototype : null;
  function checkModernType(value) {
    if (value === null || value === void 0) {
      return null;
    }
    try {
      if (value instanceof Promise || isThenable$1(value)) {
        return "promise";
      }
      if (value instanceof Map || value.__proto__ === MapPrototype) {
        return "map";
      }
      if (value instanceof Set || value.__proto__ === SetPrototype) {
        return "set";
      }
      if (value instanceof WeakMap || value.__proto__ === WeakMapPrototype) {
        return "weakmap";
      }
      if (value instanceof WeakSet || value.__proto__ === WeakSetPrototype) {
        return "weakset";
      }
      if (value instanceof ArrayBuffer || value.__proto__ === ArrayBufferPrototype) {
        return "arraybuffer";
      }
      if (SharedArrayBufferPrototype && (value instanceof SharedArrayBuffer || value.__proto__ === SharedArrayBufferPrototype)) {
        return "sharedarraybuffer";
      }
      if (value instanceof DataView || value.__proto__ === DataViewPrototype) {
        return "dataview";
      }
      if (isProxy$1(value)) {
        return "proxy";
      }
    } catch (e) {
    }
    return null;
  }
  function isThenable$1(value) {
    return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
  }
  function isProxy$1(value) {
    try {
      if (typeof value !== "object" && typeof value !== "function") {
        return false;
      }
      new Proxy({}, value);
      const descriptor = Object.getOwnPropertyDescriptor(value, Symbol.toStringTag);
      if (descriptor && !descriptor.configurable && descriptor.value === "Proxy") {
        return true;
      }
      return false;
    } catch (e) {
      return false;
    }
  }
  function getTypedArrayType(value) {
    var _a;
    if (!ArrayBuffer.isView(value)) {
      return null;
    }
    const proto = Object.getPrototypeOf(value);
    const ctorName = (_a = proto == null ? void 0 : proto.constructor) == null ? void 0 : _a.name;
    switch (ctorName) {
      case "Int8Array":
        return "int8array";
      case "Uint8Array":
        return "uint8array";
      case "Uint8ClampedArray":
        return "uint8clampedarray";
      case "Int16Array":
        return "int16array";
      case "Uint16Array":
        return "uint16array";
      case "Int32Array":
        return "int32array";
      case "Uint32Array":
        return "uint32array";
      case "Float32Array":
        return "float32array";
      case "Float64Array":
        return "float64array";
      case "BigInt64Array":
        return "bigint64array";
      case "BigUint64Array":
        return "biguint64array";
      default:
        return null;
    }
  }

  let typeCache = null;
  let cacheEnabled = true;
  function kindOfCore(value) {
    if (value === void 0) return "undefined";
    if (value === null) return "null";
    const primitiveType = getPrimitiveType(value);
    if (primitiveType) return primitiveType;
    if (typeof value === "object" && cacheEnabled && typeCache) {
      const cached = typeCache.get(value);
      if (cached) return cached;
    }
    let type = getNativeType(value);
    if (!type || type === "object") {
      const modernType = checkModernType(value);
      if (modernType) {
        type = modernType;
      } else {
        const arrayType = getTypedArrayType(value);
        if (arrayType) {
          type = arrayType;
        } else {
          type = getCustomType(value) || type || "object";
        }
      }
    }
    if (typeof value === "object" && cacheEnabled && type) {
      if (!typeCache) typeCache = /* @__PURE__ */ new WeakMap();
      typeCache.set(value, type);
    }
    return type || "object";
  }
  function fastKindOf(value) {
    if (value === void 0) return "undefined";
    if (value === null) return "null";
    const primitiveType = typeof value;
    if (primitiveType !== "object" && primitiveType !== "function") {
      return primitiveType;
    }
    if (Array.isArray(value)) return "array";
    if (value instanceof Date) return "date";
    if (value instanceof RegExp) return "regexp";
    if (value instanceof Error) return "error";
    return "object";
  }
  function kindOfMany(values) {
    const results = new Array(values.length);
    for (let i = 0; i < values.length; i++) {
      results[i] = kindOfCore(values[i]);
    }
    return results;
  }
  function getDetailedType(value) {
    const type = kindOfCore(value);
    const isPrimitive = value === null || typeof value !== "object" && typeof value !== "function";
    let constructor = null;
    let prototype = null;
    let isIterable = false;
    let isAsync = false;
    let customType = null;
    const metadata = {};
    if (!isPrimitive && value !== null) {
      const obj = value;
      if (obj.constructor) {
        constructor = obj.constructor.name || null;
      }
      const proto = Object.getPrototypeOf(obj);
      if (proto && proto.constructor) {
        prototype = proto.constructor.name || null;
      }
      isIterable = typeof obj[Symbol.iterator] === "function";
      isAsync = typeof obj[Symbol.asyncIterator] === "function" || type === "promise" || type === "asyncfunction" || type === "asyncgeneratorfunction";
      if (obj[Symbol.toStringTag]) {
        customType = String(obj[Symbol.toStringTag]);
      }
      if (type === "array") {
        metadata["length"] = obj.length;
      } else if (type === "map" || type === "set") {
        metadata["size"] = obj.size;
      } else if (type === "arraybuffer" || type === "sharedarraybuffer") {
        metadata["byteLength"] = obj.byteLength;
      } else if (type.includes("array") && obj.buffer) {
        metadata["byteLength"] = obj.byteLength;
        metadata["length"] = obj.length;
      }
    }
    return {
      type,
      constructor,
      prototype,
      isPrimitive,
      isBuiltIn: isBuiltInType(type),
      isNullish: value === null || value === void 0,
      isIterable,
      isAsync,
      customType,
      metadata: Object.keys(metadata).length > 0 ? metadata : void 0
    };
  }
  function getPrimitiveType(value) {
    const type = typeof value;
    switch (type) {
      case "boolean":
      case "number":
      case "string":
      case "symbol":
      case "bigint":
        return type;
      default:
        return null;
    }
  }
  function getCustomType(value) {
    try {
      const toStringTag = value[Symbol.toStringTag];
      if (typeof toStringTag === "string") {
        return toStringTag.toLowerCase();
      }
      if (value.constructor && value.constructor !== Object) {
        const ctorName = value.constructor.name;
        if (ctorName && ctorName !== "Object") {
          return ctorName.toLowerCase();
        }
      }
    } catch (e) {
    }
    return null;
  }
  function isBuiltInType(type) {
    const builtInTypes = /* @__PURE__ */ new Set([
      "undefined",
      "null",
      "boolean",
      "number",
      "string",
      "symbol",
      "bigint",
      "object",
      "array",
      "function",
      "date",
      "regexp",
      "error",
      "map",
      "set",
      "weakmap",
      "weakset",
      "int8array",
      "uint8array",
      "uint8clampedarray",
      "int16array",
      "uint16array",
      "int32array",
      "uint32array",
      "float32array",
      "float64array",
      "bigint64array",
      "biguint64array",
      "promise",
      "generatorfunction",
      "asyncfunction",
      "asyncgeneratorfunction",
      "proxy",
      "dataview",
      "arraybuffer",
      "sharedarraybuffer",
      "arguments"
    ]);
    return builtInTypes.has(type);
  }
  function enableCache() {
    cacheEnabled = true;
    if (!typeCache) typeCache = /* @__PURE__ */ new WeakMap();
  }
  function disableCache() {
    cacheEnabled = false;
    typeCache = null;
  }
  function clearCache() {
    if (typeCache) {
      typeCache = /* @__PURE__ */ new WeakMap();
    }
  }

  function isUndefined(value) {
    return value === void 0;
  }
  function isNull(value) {
    return value === null;
  }
  function isBoolean(value) {
    return typeof value === "boolean";
  }
  function isNumber(value) {
    return typeof value === "number";
  }
  function isString(value) {
    return typeof value === "string";
  }
  function isSymbol(value) {
    return typeof value === "symbol";
  }
  function isBigInt(value) {
    return typeof value === "bigint";
  }
  function isPrimitive(value) {
    return value === null || typeof value !== "object" && typeof value !== "function";
  }
  function isNullish(value) {
    return value === null || value === void 0;
  }
  function isFalsy(value) {
    return !value;
  }
  function isTruthy(value) {
    return !!value;
  }
  function isInteger(value) {
    return typeof value === "number" && Number.isInteger(value);
  }
  function isSafeInteger(value) {
    return typeof value === "number" && Number.isSafeInteger(value);
  }
  function isFinite(value) {
    return typeof value === "number" && Number.isFinite(value);
  }
  function isNaN$1(value) {
    return typeof value === "number" && Number.isNaN(value);
  }
  function isInfinity(value) {
    return value === Infinity || value === -Infinity;
  }
  function isEmptyString(value) {
    return value === "";
  }
  function isNumericString(value) {
    if (typeof value !== "string") return false;
    if (value === "") return false;
    return !isNaN$1(Number(value)) && !isNaN$1(parseFloat(value));
  }
  function isJsonString(value) {
    if (typeof value !== "string") return false;
    try {
      JSON.parse(value);
      return true;
    } catch (e) {
      return false;
    }
  }

  function isObject(value) {
    return value !== null && typeof value === "object";
  }
  function isArray(value) {
    return Array.isArray(value);
  }
  function isFunction(value) {
    return typeof value === "function";
  }
  function isDate(value) {
    return value instanceof Date;
  }
  function isRegExp(value) {
    return value instanceof RegExp;
  }
  function isError(value) {
    return value instanceof Error || value !== null && typeof value === "object" && "name" in value && "message" in value && "stack" in value;
  }
  function isPromise(value) {
    return value instanceof Promise || value !== null && typeof value === "object" && "then" in value && typeof value.then === "function";
  }
  function isArguments(value) {
    return Object.prototype.toString.call(value) === "[object Arguments]";
  }
  function isBuffer(value) {
    return typeof Buffer !== "undefined" && value !== null && typeof value === "object" && "isBuffer" in Buffer && Buffer.isBuffer(value);
  }
  function isPlainObject(value) {
    if (!isObject(value)) return false;
    const proto = Object.getPrototypeOf(value);
    if (proto === null) return true;
    const Ctor = Object.prototype.hasOwnProperty.call(proto, "constructor") && proto.constructor;
    return typeof Ctor === "function" && Ctor instanceof Ctor && Function.prototype.toString.call(Ctor) === Function.prototype.toString.call(Object);
  }
  function isEmpty(value) {
    if (value === null || value === void 0) return true;
    if (typeof value === "string" || Array.isArray(value)) return value.length === 0;
    if (value instanceof Map || value instanceof Set) return value.size === 0;
    if (isPlainObject(value)) return Object.keys(value).length === 0;
    return false;
  }
  function isEmptyArray(value) {
    return Array.isArray(value) && value.length === 0;
  }
  function isEmptyObject(value) {
    return isPlainObject(value) && Object.keys(value).length === 0;
  }
  function hasLength(value) {
    return value !== null && value !== void 0 && (typeof value === "object" || typeof value === "string") && (typeof value === "string" || "length" in value) && typeof value.length === "number";
  }
  function hasSize(value) {
    return value !== null && value !== void 0 && typeof value === "object" && "size" in value && typeof value.size === "number";
  }
  function isArrayLike(value) {
    return value !== null && value !== void 0 && typeof value !== "function" && hasLength(value) && value.length >= 0 && value.length <= Number.MAX_SAFE_INTEGER;
  }
  function isIterable(value) {
    return value !== null && value !== void 0 && typeof value[Symbol.iterator] === "function";
  }
  function isAsyncIterable(value) {
    return value !== null && value !== void 0 && typeof value[Symbol.asyncIterator] === "function";
  }
  function isConstructor(value) {
    if (typeof value !== "function") return false;
    try {
      const testObj = {};
      const BoundTest = value.bind(testObj);
      new BoundTest();
      return true;
    } catch (e) {
      return false;
    }
  }
  function isThenable(value) {
    return value !== null && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
  }
  function isObservable(value) {
    return value !== null && typeof value === "object" && "subscribe" in value && typeof value.subscribe === "function";
  }
  function isGenerator(value) {
    return value !== null && typeof value === "object" && typeof value.next === "function" && typeof value.throw === "function" && typeof value.return === "function";
  }
  function isAsyncGenerator(value) {
    return value !== null && typeof value === "object" && typeof value.next === "function" && typeof value.throw === "function" && typeof value.return === "function" && isAsyncIterable(value);
  }
  function isGeneratorFunction(value) {
    var _a;
    if (typeof value !== "function") return false;
    const name = (_a = value.constructor) == null ? void 0 : _a.name;
    return name === "GeneratorFunction" || /^function\s*\*/.test(value.toString());
  }
  function isAsyncFunction(value) {
    var _a;
    if (typeof value !== "function") return false;
    const name = (_a = value.constructor) == null ? void 0 : _a.name;
    return name === "AsyncFunction" || /^async\s/.test(value.toString());
  }
  function isAsyncGeneratorFunction(value) {
    var _a;
    if (typeof value !== "function") return false;
    const name = (_a = value.constructor) == null ? void 0 : _a.name;
    return name === "AsyncGeneratorFunction" || /^async\s*function\s*\*/.test(value.toString());
  }
  function isProxy(value) {
    try {
      if (typeof value !== "object" && typeof value !== "function") return false;
      if (value === null) return false;
      const testHandler = {
        get() {
          throw new Error("proxy trap");
        }
      };
      const proxy = new Proxy({}, testHandler);
      const isProxyLike = Object.prototype.toString.call(value) === Object.prototype.toString.call(proxy);
      return isProxyLike;
    } catch (e) {
      return false;
    }
  }
  function isTypeError(value) {
    return value instanceof TypeError;
  }
  function isRangeError(value) {
    return value instanceof RangeError;
  }
  function isSyntaxError(value) {
    return value instanceof SyntaxError;
  }
  function isReferenceError(value) {
    return value instanceof ReferenceError;
  }
  function isEvalError(value) {
    return value instanceof EvalError;
  }
  function isURIError(value) {
    return value instanceof URIError;
  }
  function isStream(value) {
    return value !== null && typeof value === "object" && typeof value.pipe === "function";
  }
  function isEventEmitter(value) {
    return value !== null && typeof value === "object" && typeof value.on === "function" && typeof value.emit === "function" && typeof value.removeListener === "function";
  }
  function isElement(value) {
    return typeof Element !== "undefined" && value instanceof Element;
  }
  function isNode(value) {
    return typeof Node !== "undefined" && value instanceof Node;
  }
  function isWindow(value) {
    return typeof Window !== "undefined" && value instanceof Window;
  }
  function isDocument(value) {
    return typeof Document !== "undefined" && value instanceof Document;
  }
  function isGlobal(value) {
    if (typeof globalThis !== "undefined" && value === globalThis) return true;
    if (typeof global !== "undefined" && value === global) return true;
    if (typeof window !== "undefined" && value === window) return true;
    if (typeof self !== "undefined" && value === self) return true;
    return false;
  }

  function isMap(value) {
    return value instanceof Map;
  }
  function isSet(value) {
    return value instanceof Set;
  }
  function isWeakMap(value) {
    return value instanceof WeakMap;
  }
  function isWeakSet(value) {
    return value instanceof WeakSet;
  }
  function isDataView(value) {
    return value instanceof DataView;
  }
  function isArrayBuffer(value) {
    return value instanceof ArrayBuffer;
  }
  function isSharedArrayBuffer(value) {
    return typeof SharedArrayBuffer !== "undefined" && value instanceof SharedArrayBuffer;
  }
  function isTypedArray(value) {
    return ArrayBuffer.isView(value) && !(value instanceof DataView);
  }
  function isInt8Array(value) {
    return value instanceof Int8Array;
  }
  function isUint8Array(value) {
    return value instanceof Uint8Array;
  }
  function isUint8ClampedArray(value) {
    return value instanceof Uint8ClampedArray;
  }
  function isInt16Array(value) {
    return value instanceof Int16Array;
  }
  function isUint16Array(value) {
    return value instanceof Uint16Array;
  }
  function isInt32Array(value) {
    return value instanceof Int32Array;
  }
  function isUint32Array(value) {
    return value instanceof Uint32Array;
  }
  function isFloat32Array(value) {
    return value instanceof Float32Array;
  }
  function isFloat64Array(value) {
    return value instanceof Float64Array;
  }
  function isBigInt64Array(value) {
    return typeof BigInt64Array !== "undefined" && value instanceof BigInt64Array;
  }
  function isBigUint64Array(value) {
    return typeof BigUint64Array !== "undefined" && value instanceof BigUint64Array;
  }

  function isType(value, type) {
    return kindOfCore(value) === type;
  }
  function assertType(value, type) {
    if (kindOfCore(value) !== type) {
      throw new TypeError(`Expected type "${type}" but got "${kindOfCore(value)}"`);
    }
  }
  function ensureType(value, type, defaultValue) {
    return isType(value, type) ? value : defaultValue;
  }

  var __defProp$1 = Object.defineProperty;
  var __defProps = Object.defineProperties;
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
  var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
  var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
  var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  var __spreadValues$1 = (a, b) => {
    for (var prop in b || (b = {}))
      if (__hasOwnProp$1.call(b, prop))
        __defNormalProp$1(a, prop, b[prop]);
    if (__getOwnPropSymbols$1)
      for (var prop of __getOwnPropSymbols$1(b)) {
        if (__propIsEnum$1.call(b, prop))
          __defNormalProp$1(a, prop, b[prop]);
      }
    return a;
  };
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
  function validateSchema(value, schema, options = {}) {
    var _a, _b, _c;
    const errors = [];
    const context = {
      path: options.path || "",
      strict: (_a = options.strict) != null ? _a : true,
      coerce: (_b = options.coerce) != null ? _b : false,
      partial: (_c = options.partial) != null ? _c : false
    };
    validateValue(value, schema, context, errors);
    return {
      valid: errors.length === 0,
      errors
    };
  }
  function validateValue(value, schema, context, errors) {
    if (typeof schema === "string") {
      const actualType = kindOfCore(value);
      if (actualType !== schema) {
        errors.push({
          path: context.path || "root",
          expected: schema,
          actual: actualType,
          message: `Expected type "${schema}" but got "${actualType}"`
        });
      }
    } else if (Array.isArray(schema)) {
      if (!Array.isArray(value)) {
        errors.push({
          path: context.path || "root",
          expected: "array",
          actual: kindOfCore(value),
          message: `Expected array but got "${kindOfCore(value)}"`
        });
        return;
      }
      const itemSchema = schema[0];
      if (itemSchema) {
        value.forEach((item, index) => {
          validateValue(
            item,
            itemSchema,
            __spreadProps(__spreadValues$1({}, context), { path: `${context.path}[${index}]` }),
            errors
          );
        });
      }
    } else if (schema && typeof schema === "object") {
      if (typeof value !== "object" || value === null) {
        errors.push({
          path: context.path || "root",
          expected: "object",
          actual: kindOfCore(value),
          message: `Expected object but got "${kindOfCore(value)}"`
        });
        return;
      }
      const obj = value;
      const schemaObj = schema;
      if (!context.partial) {
        for (const key of Object.keys(schemaObj)) {
          if (!(key in obj)) {
            errors.push({
              path: context.path ? `${context.path}.${key}` : key,
              expected: typeof schemaObj[key] === "string" ? schemaObj[key] : kindOfCore(schemaObj[key]),
              actual: "undefined",
              message: `Missing required property "${key}"`
            });
          }
        }
      }
      for (const key of Object.keys(obj)) {
        if (key in schemaObj) {
          const schemaValue = schemaObj[key];
          if (schemaValue !== void 0) {
            validateValue(
              obj[key],
              schemaValue,
              __spreadProps(__spreadValues$1({}, context), { path: context.path ? `${context.path}.${key}` : key }),
              errors
            );
          }
        } else if (context.strict) {
          errors.push({
            path: context.path ? `${context.path}.${key}` : key,
            expected: "undefined",
            actual: kindOfCore(obj[key]),
            message: `Unexpected property "${key}"`
          });
        }
      }
    }
  }
  function createValidator(schema, options) {
    return (value) => validateSchema(value, schema, options);
  }

  function toString(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "string":
        return value;
      case "number":
      case "boolean":
      case "bigint":
        return String(value);
      case "symbol":
        return value.toString();
      case "undefined":
        return "undefined";
      case "null":
        return "null";
      case "date":
        return value.toISOString();
      case "regexp":
        return value.toString();
      case "function":
        return value.toString();
      case "array":
        return JSON.stringify(value);
      case "object":
        try {
          return JSON.stringify(value);
        } catch (e) {
          return Object.prototype.toString.call(value);
        }
      default:
        return String(value);
    }
  }
  function toNumber(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "number":
        return value;
      case "string": {
        const num = Number(value);
        return isNaN(num) ? null : num;
      }
      case "boolean":
        return value ? 1 : 0;
      case "null":
        return 0;
      case "bigint": {
        const bigIntValue = Number(value);
        return bigIntValue > Number.MAX_SAFE_INTEGER || bigIntValue < Number.MIN_SAFE_INTEGER ? null : bigIntValue;
      }
      case "date":
        return value.getTime();
      default:
        return null;
    }
  }
  function toBoolean(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "boolean":
        return value;
      case "string": {
        const str = value.toLowerCase();
        return str !== "" && str !== "false" && str !== "0" && str !== "no" && str !== "null" && str !== "undefined";
      }
      case "number":
        return value !== 0 && !isNaN(value);
      case "null":
      case "undefined":
        return false;
      case "array":
        return value.length > 0;
      case "object":
        return Object.keys(value).length > 0;
      default:
        return !!value;
    }
  }
  function toBigInt(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "bigint":
        return value;
      case "number":
        if (Number.isInteger(value)) {
          return BigInt(value);
        }
        return null;
      case "string":
        try {
          return BigInt(value);
        } catch (e) {
          return null;
        }
      case "boolean":
        return BigInt(value ? 1 : 0);
      default:
        return null;
    }
  }
  function toSymbol(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "symbol":
        return value;
      case "string":
        return Symbol(value);
      case "number":
        return Symbol(String(value));
      default:
        return Symbol(toString(value));
    }
  }

  function toArray(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "array":
        return value;
      case "string":
        return Array.from(value);
      case "set":
        return Array.from(value);
      case "map":
        return Array.from(value);
      case "arguments":
        return Array.from(value);
      case "null":
      case "undefined":
        return [];
      default:
        if (value !== null && typeof value === "object" && "length" in value) {
          return Array.from(value);
        }
        return [value];
    }
  }
  function toObject(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "object":
        return value;
      case "array": {
        const arr = value;
        const obj = {};
        arr.forEach((item, index) => {
          obj[index] = item;
        });
        return obj;
      }
      case "map": {
        const map = value;
        const obj = {};
        for (const [key, val] of map) {
          obj[String(key)] = val;
        }
        return obj;
      }
      case "set": {
        const set = value;
        const obj = {};
        let index = 0;
        for (const item of set) {
          obj[index++] = item;
        }
        return obj;
      }
      case "string": {
        const str = value;
        const obj = {};
        for (let i = 0; i < str.length; i++) {
          obj[i] = str[i];
        }
        return obj;
      }
      case "null":
      case "undefined":
        return {};
      default:
        return { value };
    }
  }
  function toMap(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "map":
        return value;
      case "object": {
        const obj = value;
        const map = /* @__PURE__ */ new Map();
        for (const [key, val] of Object.entries(obj)) {
          map.set(key, val);
        }
        return map;
      }
      case "array": {
        const arr = value;
        const map = /* @__PURE__ */ new Map();
        arr.forEach((item, index) => {
          map.set(index, item);
        });
        return map;
      }
      case "set": {
        const set = value;
        const map = /* @__PURE__ */ new Map();
        let index = 0;
        for (const item of set) {
          map.set(index++, item);
        }
        return map;
      }
      default:
        return null;
    }
  }
  function toSet(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "set":
        return value;
      case "array":
        return new Set(value);
      case "string":
        return new Set(Array.from(value));
      case "map":
        return new Set(value.values());
      case "object":
        return new Set(Object.values(value));
      default:
        return value !== null && value !== void 0 ? /* @__PURE__ */ new Set([value]) : /* @__PURE__ */ new Set();
    }
  }
  function toDate(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "date":
        return value;
      case "string": {
        const date = new Date(value);
        return isNaN(date.getTime()) ? null : date;
      }
      case "number": {
        const date = new Date(value);
        return isNaN(date.getTime()) ? null : date;
      }
      default:
        return null;
    }
  }
  function toRegExp(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "regexp":
        return value;
      case "string":
        try {
          return new RegExp(value);
        } catch (e) {
          return null;
        }
      default:
        return null;
    }
  }
  function toError(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "error":
        return value;
      case "string":
        return new Error(value);
      case "object":
        if (value && typeof value === "object" && "message" in value) {
          return new Error(String(value.message));
        }
        return new Error(String(value));
      default:
        return new Error(String(value));
    }
  }
  function toFunction(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "function":
      case "asyncfunction":
      case "generatorfunction":
      case "asyncgeneratorfunction":
        return value;
      case "string":
        try {
          return new Function("return " + String(value));
        } catch (e) {
          return null;
        }
      default:
        return null;
    }
  }
  function toPromise(value) {
    const type = kindOfCore(value);
    switch (type) {
      case "promise":
        return value;
      case "function":
        try {
          const result = value();
          return Promise.resolve(result);
        } catch (error) {
          return Promise.reject(error);
        }
      default:
        return Promise.resolve(value);
    }
  }
  function toBuffer(value) {
    if (typeof Buffer === "undefined") {
      return null;
    }
    const type = kindOfCore(value);
    switch (type) {
      case "buffer":
        return value;
      case "string":
        return Buffer.from(value);
      case "array":
        return Buffer.from(value);
      case "uint8array":
        return Buffer.from(value);
      case "arraybuffer":
        return Buffer.from(value);
      default:
        return null;
    }
  }
  function toTypedArray(value, TypedArrayConstructor) {
    const type = kindOfCore(value);
    switch (type) {
      case "arraybuffer":
        return new TypedArrayConstructor(value);
      case "array": {
        const arr = value;
        const buffer = new ArrayBuffer(arr.length * 4);
        const view = new TypedArrayConstructor(buffer);
        for (let i = 0; i < arr.length; i++) {
          view[i] = arr[i];
        }
        return view;
      }
      default:
        if (type.includes("array") && value instanceof ArrayBuffer) {
          return new TypedArrayConstructor(value);
        }
        return null;
    }
  }

  function coerceType(value, targetType) {
    const currentType = kindOfCore(value);
    if (currentType === targetType) {
      return value;
    }
    switch (targetType) {
      case "string":
        return toString(value);
      case "number":
        return toNumber(value);
      case "boolean":
        return toBoolean(value);
      case "bigint":
        return toBigInt(value);
      case "symbol":
        return toSymbol(value);
      case "undefined":
        return void 0;
      case "null":
        return null;
      case "array":
        if (currentType === "object" && value !== null) {
          const arr = Array.from(value);
          return arr.length > 0 ? arr : null;
        }
        return null;
      case "object":
        if (currentType === "array") {
          const obj = {};
          value.forEach((item, index) => {
            obj[index] = item;
          });
          return obj;
        }
        return null;
      case "date":
        if (currentType === "string") {
          const date = new Date(value);
          return isNaN(date.getTime()) ? null : date;
        }
        return null;
      default:
        return null;
    }
  }

  class PerformanceMonitor {
    constructor() {
      this.metrics = /* @__PURE__ */ new Map();
      this.enabled = false;
    }
    enable() {
      this.enabled = true;
    }
    disable() {
      this.enabled = false;
    }
    isEnabled() {
      return this.enabled;
    }
    startTimer(operation) {
      if (!this.enabled) {
        return () => {
        };
      }
      const start = performance.now();
      return () => {
        const duration = performance.now() - start;
        this.recordMetric(operation, duration);
      };
    }
    recordCacheHit(operation) {
      if (!this.enabled) return;
      const metric = this.getOrCreateMetric(operation);
      metric.cacheHits++;
    }
    recordCacheMiss(operation) {
      if (!this.enabled) return;
      const metric = this.getOrCreateMetric(operation);
      metric.cacheMisses++;
    }
    recordMetric(operation, duration) {
      const metric = this.getOrCreateMetric(operation);
      metric.totalCalls++;
      metric.totalTime += duration;
      metric.averageTime = metric.totalTime / metric.totalCalls;
      metric.minTime = Math.min(metric.minTime, duration);
      metric.maxTime = Math.max(metric.maxTime, duration);
    }
    getOrCreateMetric(operation) {
      if (!this.metrics.has(operation)) {
        this.metrics.set(operation, {
          totalCalls: 0,
          totalTime: 0,
          averageTime: 0,
          minTime: Infinity,
          maxTime: 0,
          cacheHits: 0,
          cacheMisses: 0
        });
      }
      const metric = this.metrics.get(operation);
      if (!metric) {
        throw new Error(`Metric '${operation}' should exist after creation`);
      }
      return metric;
    }
    getMetrics(operation) {
      if (operation) {
        return this.metrics.get(operation) || this.getOrCreateMetric(operation);
      }
      return new Map(this.metrics);
    }
    reset(operation) {
      if (operation) {
        this.metrics.delete(operation);
      } else {
        this.metrics.clear();
      }
    }
    getReport() {
      const report = ["Performance Report:", ""];
      for (const [operation, metrics] of this.metrics) {
        report.push(`${operation}:`);
        report.push(`  Total calls: ${metrics.totalCalls}`);
        report.push(`  Total time: ${metrics.totalTime.toFixed(2)}ms`);
        report.push(`  Average time: ${metrics.averageTime.toFixed(2)}ms`);
        report.push(`  Min time: ${metrics.minTime.toFixed(2)}ms`);
        report.push(`  Max time: ${metrics.maxTime.toFixed(2)}ms`);
        report.push(`  Cache hits: ${metrics.cacheHits}`);
        report.push(`  Cache misses: ${metrics.cacheMisses}`);
        if (metrics.cacheHits + metrics.cacheMisses > 0) {
          const hitRate = metrics.cacheHits / (metrics.cacheHits + metrics.cacheMisses) * 100;
          report.push(`  Cache hit rate: ${hitRate.toFixed(1)}%`);
        }
        report.push("");
      }
      return report.join("\n");
    }
  }
  const performanceMonitor = new PerformanceMonitor();

  var __defProp = Object.defineProperty;
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
  var __spreadValues = (a, b) => {
    for (var prop in b || (b = {}))
      if (__hasOwnProp.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    if (__getOwnPropSymbols)
      for (var prop of __getOwnPropSymbols(b)) {
        if (__propIsEnum.call(b, prop))
          __defNormalProp(a, prop, b[prop]);
      }
    return a;
  };
  function inspect(value, options = {}) {
    const opts = __spreadValues({
      depth: 2,
      colors: false,
      showHidden: false,
      showProxy: true,
      maxArrayLength: 100,
      maxStringLength: 200,
      breakLength: 80,
      compact: false,
      sorted: false,
      getters: false
    }, options);
    return inspectValue(value, opts, 0, /* @__PURE__ */ new Set());
  }
  function inspectValue(value, options, depth, seen) {
    if (depth > options.depth) {
      return "[Object]";
    }
    if (value === null) return "null";
    if (value === void 0) return "undefined";
    const type = kindOfCore(value);
    if (type === "string") {
      return inspectString(value, options);
    }
    if (type === "number" || type === "boolean" || type === "symbol" || type === "bigint") {
      return String(value);
    }
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) {
        return "[Circular]";
      }
      seen.add(value);
    }
    try {
      switch (type) {
        case "array":
          return inspectArray(value, options, depth, seen);
        case "object":
          return inspectObject(value, options, depth, seen);
        case "function":
          return inspectFunction(value, options);
        case "date":
          return inspectDate(value, options);
        case "regexp":
          return inspectRegExp(value, options);
        case "error":
          return inspectError(value, options);
        case "map":
          return inspectMap(value, options, depth, seen);
        case "set":
          return inspectSet(value, options, depth, seen);
        case "promise":
          return inspectPromise(value, options);
        default:
          return inspectGeneric(value, type, options);
      }
    } finally {
      if (typeof value === "object" && value !== null) {
        seen.delete(value);
      }
    }
  }
  function inspectString(str, options) {
    if (str.length > options.maxStringLength) {
      return `'${str.slice(0, options.maxStringLength)}...'`;
    }
    return `'${str}'`;
  }
  function inspectArray(arr, options, depth, seen) {
    if (arr.length === 0) return "[]";
    const maxLength = Math.min(arr.length, options.maxArrayLength);
    const items = [];
    for (let i = 0; i < maxLength; i++) {
      items.push(inspectValue(arr[i], options, depth + 1, seen));
    }
    if (arr.length > maxLength) {
      items.push(`... ${arr.length - maxLength} more items`);
    }
    if (options.compact) {
      return `[${items.join(", ")}]`;
    }
    const joined = items.join(", ");
    if (joined.length <= options.breakLength) {
      return `[${joined}]`;
    }
    return `[
${items.map((item) => `  ${item}`).join(",\n")}
]`;
  }
  function inspectObject(obj, options, depth, seen) {
    const keys = options.showHidden ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
    if (keys.length === 0) return "{}";
    if (options.sorted) {
      keys.sort();
    }
    const items = [];
    for (const key of keys) {
      try {
        const value = obj[key];
        const inspected = inspectValue(value, options, depth + 1, seen);
        items.push(`${key}: ${inspected}`);
      } catch (error) {
        items.push(`${key}: [Error: ${error.message}]`);
      }
    }
    if (options.compact) {
      return `{${items.join(", ")}}`;
    }
    const joined = items.join(", ");
    if (joined.length <= options.breakLength) {
      return `{${joined}}`;
    }
    return `{
${items.map((item) => `  ${item}`).join(",\n")}
}`;
  }
  function inspectFunction(fn, _options) {
    const name = fn.name || "anonymous";
    const type = getDetailedType(fn);
    if (type.type === "asyncfunction") {
      return `[AsyncFunction: ${name}]`;
    } else if (type.type === "generatorfunction") {
      return `[GeneratorFunction: ${name}]`;
    } else if (type.type === "asyncgeneratorfunction") {
      return `[AsyncGeneratorFunction: ${name}]`;
    }
    return `[Function: ${name}]`;
  }
  function inspectDate(date, _options) {
    return `${date.toISOString()}`;
  }
  function inspectRegExp(regex, _options) {
    return regex.toString();
  }
  function inspectError(error, _options) {
    return `${error.name}: ${error.message}`;
  }
  function inspectMap(map, options, depth, seen) {
    if (map.size === 0) return "Map(0) {}";
    const items = [];
    let count = 0;
    for (const [key, value] of map) {
      if (count >= options.maxArrayLength) {
        items.push(`... ${map.size - count} more items`);
        break;
      }
      const keyStr = inspectValue(key, options, depth + 1, seen);
      const valueStr = inspectValue(value, options, depth + 1, seen);
      items.push(`${keyStr} => ${valueStr}`);
      count++;
    }
    return `Map(${map.size}) {${items.join(", ")}}`;
  }
  function inspectSet(set, options, depth, seen) {
    if (set.size === 0) return "Set(0) {}";
    const items = [];
    let count = 0;
    for (const value of set) {
      if (count >= options.maxArrayLength) {
        items.push(`... ${set.size - count} more items`);
        break;
      }
      items.push(inspectValue(value, options, depth + 1, seen));
      count++;
    }
    return `Set(${set.size}) {${items.join(", ")}}`;
  }
  function inspectPromise(_promise, _options) {
    return "Promise { <pending> }";
  }
  function inspectGeneric(value, type, _options) {
    if (value && typeof value === "object" && value.constructor) {
      return `${value.constructor.name} {}`;
    }
    return `[${type}]`;
  }
  function inspectType(value) {
    const detailed = getDetailedType(value);
    const parts = [];
    parts.push(`Type: ${detailed.type}`);
    if (detailed.constructor) {
      parts.push(`Constructor: ${detailed.constructor}`);
    }
    if (detailed.customType) {
      parts.push(`Custom Type: ${detailed.customType}`);
    }
    const flags = [];
    if (detailed.isPrimitive) flags.push("primitive");
    if (detailed.isBuiltIn) flags.push("built-in");
    if (detailed.isNullish) flags.push("nullish");
    if (detailed.isIterable) flags.push("iterable");
    if (detailed.isAsync) flags.push("async");
    if (flags.length > 0) {
      parts.push(`Flags: ${flags.join(", ")}`);
    }
    if (detailed.metadata) {
      const metadata = Object.entries(detailed.metadata).map(([key, value2]) => `${key}: ${value2}`).join(", ");
      parts.push(`Metadata: {${metadata}}`);
    }
    return parts.join("\n");
  }

  function isValidType(type) {
    const validTypes = /* @__PURE__ */ new Set([
      "undefined",
      "null",
      "boolean",
      "number",
      "string",
      "symbol",
      "bigint",
      "object",
      "array",
      "function",
      "date",
      "regexp",
      "error",
      "map",
      "set",
      "weakmap",
      "weakset",
      "int8array",
      "uint8array",
      "uint8clampedarray",
      "int16array",
      "uint16array",
      "int32array",
      "uint32array",
      "float32array",
      "float64array",
      "bigint64array",
      "biguint64array",
      "promise",
      "generatorfunction",
      "asyncfunction",
      "asyncgeneratorfunction",
      "proxy",
      "dataview",
      "arraybuffer",
      "sharedarraybuffer",
      "arguments",
      "buffer",
      "stream",
      "eventemitter",
      "element",
      "node",
      "window",
      "document",
      "global"
    ]);
    return validTypes.has(type);
  }
  function getTypeCategory(type) {
    if (["undefined", "null", "boolean", "number", "string", "symbol", "bigint"].includes(type)) {
      return "primitive";
    }
    if (["object", "array", "function", "date", "regexp", "error"].includes(type)) {
      return "object";
    }
    if (["map", "set", "weakmap", "weakset"].includes(type)) {
      return "collection";
    }
    if (type.includes("array") && type !== "array") {
      return "typedarray";
    }
    if (["promise", "generatorfunction", "asyncfunction", "asyncgeneratorfunction"].includes(type)) {
      return "modern";
    }
    if (["buffer", "stream", "eventemitter"].includes(type)) {
      return "node";
    }
    if (["element", "node", "window", "document"].includes(type)) {
      return "dom";
    }
    return "special";
  }
  function compareTypes(a, b) {
    return kindOfCore(a) === kindOfCore(b);
  }
  function isTypeOfAny(value, types) {
    const type = kindOfCore(value);
    return types.includes(type);
  }
  function isTypeOfAll(values, expectedType) {
    return values.every((value) => kindOfCore(value) === expectedType);
  }
  function groupByType(values) {
    const groups = /* @__PURE__ */ new Map();
    for (const value of values) {
      const type = kindOfCore(value);
      if (!groups.has(type)) {
        groups.set(type, []);
      }
      const group = groups.get(type);
      if (group) {
        group.push(value);
      }
    }
    return groups;
  }
  function getTypeStats(values) {
    const stats = {};
    for (const value of values) {
      const type = kindOfCore(value);
      stats[type] = (stats[type] || 0) + 1;
    }
    return stats;
  }
  function filterByType(values, type) {
    return values.filter((value) => kindOfCore(value) === type);
  }
  function findByType(values, type) {
    return values.find((value) => kindOfCore(value) === type);
  }
  function someOfType(values, type) {
    return values.some((value) => kindOfCore(value) === type);
  }
  function everyOfType(values, type) {
    return values.every((value) => kindOfCore(value) === type);
  }
  function noneOfType(values, type) {
    return !values.some((value) => kindOfCore(value) === type);
  }
  function countByType(values, type) {
    return values.filter((value) => kindOfCore(value) === type).length;
  }
  function getUniqueTypes(values) {
    const types = /* @__PURE__ */ new Set();
    for (const value of values) {
      types.add(kindOfCore(value));
    }
    return Array.from(types);
  }
  function createTypeMap(values) {
    return groupByType(values);
  }
  function getMostCommonType(values) {
    if (values.length === 0) return null;
    const stats = getTypeStats(values);
    let maxCount = 0;
    let mostCommon = null;
    for (const [type, count] of Object.entries(stats)) {
      if (count > maxCount) {
        maxCount = count;
        mostCommon = type;
      }
    }
    return mostCommon;
  }
  function getLeastCommonType(values) {
    if (values.length === 0) return null;
    const stats = getTypeStats(values);
    let minCount = Infinity;
    let leastCommon = null;
    for (const [type, count] of Object.entries(stats)) {
      if (count < minCount) {
        minCount = count;
        leastCommon = type;
      }
    }
    return leastCommon;
  }
  function isHomogeneous(values) {
    if (values.length === 0) return true;
    const firstType = kindOfCore(values[0]);
    return values.every((value) => kindOfCore(value) === firstType);
  }
  function isHeterogeneous(values) {
    return !isHomogeneous(values);
  }
  function partition(values, predicate) {
    const truthy = [];
    const falsy = [];
    for (const value of values) {
      if (predicate(value)) {
        truthy.push(value);
      } else {
        falsy.push(value);
      }
    }
    return [truthy, falsy];
  }
  function partitionByType(values, type) {
    return partition(values, (value) => kindOfCore(value) === type);
  }

  class KindOfExtended {
    constructor() {
      this.plugins = /* @__PURE__ */ new Map();
      this.customTypes = /* @__PURE__ */ new Map();
      this.typeOrder = [];
      const boundFunction = this.detect.bind(this);
      Object.setPrototypeOf(boundFunction, KindOfExtended.prototype);
      Object.assign(boundFunction, this);
      return boundFunction;
    }
    detect(value) {
      for (let i = this.typeOrder.length - 1; i >= 0; i--) {
        const typeName = this.typeOrder[i];
        if (!typeName) continue;
        const checker = this.customTypes.get(typeName);
        if (checker && checker(value)) {
          return typeName;
        }
      }
      return kindOfCore(value);
    }
    use(plugin, options = {}) {
      if (this.plugins.has(plugin.name)) {
        throw new Error(`Plugin "${plugin.name}" is already registered`);
      }
      this.plugins.set(plugin.name, plugin);
      const prefix = options.prefix || "";
      for (const [typeName, checker] of Object.entries(plugin.types)) {
        const fullTypeName = prefix + typeName;
        if (this.customTypes.has(fullTypeName) && !options.override) {
          throw new Error(`Type "${fullTypeName}" is already defined`);
        }
        this.customTypes.set(fullTypeName, checker);
        this.typeOrder.push(fullTypeName);
      }
      if (plugin.setup) {
        plugin.setup(this);
      }
      return this;
    }
    unuse(pluginName) {
      const plugin = this.plugins.get(pluginName);
      if (!plugin) {
        throw new Error(`Plugin "${pluginName}" is not registered`);
      }
      if (plugin.teardown) {
        plugin.teardown();
      }
      for (const typeName of Object.keys(plugin.types)) {
        this.customTypes.delete(typeName);
        const index = this.typeOrder.indexOf(typeName);
        if (index !== -1) {
          this.typeOrder.splice(index, 1);
        }
      }
      this.plugins.delete(pluginName);
      return this;
    }
    defineType(name, checker) {
      if (this.customTypes.has(name)) {
        throw new Error(`Type "${name}" is already defined`);
      }
      this.customTypes.set(name, checker);
      this.typeOrder.push(name);
      return this;
    }
    removeType(name) {
      if (!this.customTypes.has(name)) {
        throw new Error(`Type "${name}" is not defined`);
      }
      this.customTypes.delete(name);
      const index = this.typeOrder.indexOf(name);
      if (index !== -1) {
        this.typeOrder.splice(index, 1);
      }
      return this;
    }
    getCustomTypes() {
      return Object.fromEntries(this.customTypes);
    }
    hasType(name) {
      return this.customTypes.has(name);
    }
  }
  function createKindOfInstance() {
    return new KindOfExtended();
  }
  function createPlugin(config) {
    const plugin = {
      name: config.name,
      version: config.version,
      types: config.types
    };
    if (config.setup) {
      plugin.setup = config.setup;
    }
    if (config.teardown) {
      plugin.teardown = config.teardown;
    }
    return plugin;
  }

  const isReactElement = (value) => {
    return value !== null && typeof value === "object" && "$$typeof" in value && "type" in value && "props" in value;
  };
  const isReactComponent = (value) => {
    if (typeof value !== "function") return false;
    const fn = value;
    const prototype = fn.prototype;
    if (prototype && prototype.isReactComponent) {
      return true;
    }
    if (fn.name && /^[A-Z]/.test(fn.name)) {
      return true;
    }
    return false;
  };
  const isReactMemo = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "type" in value && ((_b = (_a = value.$$typeof) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.memo)";
  };
  const isReactForwardRef = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "render" in value && ((_b = (_a = value.$$typeof) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.forward_ref)";
  };
  const isReactLazy = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "_payload" in value && "_init" in value && ((_b = (_a = value.$$typeof) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.lazy)";
  };
  const isReactContext = (value) => {
    return value !== null && typeof value === "object" && "$$typeof" in value && "_currentValue" in value && "Provider" in value && "Consumer" in value;
  };
  const isReactProvider = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "_context" in value && ((_b = (_a = value.$$typeof) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.provider)";
  };
  const isReactConsumer = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "_context" in value && ((_b = (_a = value.$$typeof) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.consumer)";
  };
  const isReactFragment = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "type" in value && ((_b = (_a = value.type) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.fragment)";
  };
  const isReactPortal = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "children" in value && "containerInfo" in value && ((_b = (_a = value.$$typeof) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.portal)";
  };
  const isReactSuspense = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "type" in value && ((_b = (_a = value.type) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.suspense)";
  };
  const isReactProfiler = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "type" in value && ((_b = (_a = value.type) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.profiler)";
  };
  const isReactStrictMode = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "$$typeof" in value && "type" in value && ((_b = (_a = value.type) == null ? void 0 : _a.toString) == null ? void 0 : _b.call(_a)) === "Symbol(react.strict_mode)";
  };
  const reactPlugin = createPlugin({
    name: "react",
    version: "1.0.0",
    types: {
      "react.element": isReactElement,
      "react.component": isReactComponent,
      "react.memo": isReactMemo,
      "react.forwardref": isReactForwardRef,
      "react.lazy": isReactLazy,
      "react.context": isReactContext,
      "react.provider": isReactProvider,
      "react.consumer": isReactConsumer,
      "react.fragment": isReactFragment,
      "react.portal": isReactPortal,
      "react.suspense": isReactSuspense,
      "react.profiler": isReactProfiler,
      "react.strictmode": isReactStrictMode
    }
  });

  const isReadableStream = (value) => {
    return value !== null && typeof value === "object" && "readable" in value && "read" in value && typeof value.read === "function" && "_readableState" in value;
  };
  const isWritableStream = (value) => {
    return value !== null && typeof value === "object" && "writable" in value && "write" in value && typeof value.write === "function" && "_writableState" in value;
  };
  const isDuplexStream = (value) => {
    return isReadableStream(value) && isWritableStream(value);
  };
  const isTransformStream = (value) => {
    return isDuplexStream(value) && value !== null && typeof value === "object" && "_transform" in value && typeof value._transform === "function";
  };
  const isServer = (value) => {
    return value !== null && typeof value === "object" && "listen" in value && "close" in value && "address" in value && typeof value.listen === "function";
  };
  const isIncomingMessage = (value) => {
    return value !== null && typeof value === "object" && "headers" in value && "method" in value && "url" in value && isReadableStream(value);
  };
  const isServerResponse = (value) => {
    return value !== null && typeof value === "object" && "statusCode" in value && "setHeader" in value && "writeHead" in value && isWritableStream(value);
  };
  const isChildProcess = (value) => {
    return value !== null && typeof value === "object" && "pid" in value && "kill" in value && "stdin" in value && "stdout" in value && "stderr" in value && typeof value.kill === "function";
  };
  const isWorker = (value) => {
    return value !== null && typeof value === "object" && "threadId" in value && "postMessage" in value && "terminate" in value && typeof value.postMessage === "function";
  };
  const isMessagePort = (value) => {
    return value !== null && typeof value === "object" && "postMessage" in value && "start" in value && "close" in value && typeof value.postMessage === "function";
  };
  const isURL = (value) => {
    var _a;
    return value !== null && typeof value === "object" && "href" in value && "protocol" in value && "hostname" in value && "pathname" in value && "search" in value && "hash" in value && ((_a = value.constructor) == null ? void 0 : _a.name) === "URL";
  };
  const isURLSearchParams = (value) => {
    var _a;
    return value !== null && typeof value === "object" && "append" in value && "get" in value && "set" in value && "delete" in value && typeof value.append === "function" && ((_a = value.constructor) == null ? void 0 : _a.name) === "URLSearchParams";
  };
  const isTextEncoder = (value) => {
    var _a;
    return value !== null && typeof value === "object" && "encode" in value && typeof value.encode === "function" && ((_a = value.constructor) == null ? void 0 : _a.name) === "TextEncoder";
  };
  const isTextDecoder = (value) => {
    var _a;
    return value !== null && typeof value === "object" && "decode" in value && typeof value.decode === "function" && ((_a = value.constructor) == null ? void 0 : _a.name) === "TextDecoder";
  };
  const isAbortController = (value) => {
    var _a;
    return value !== null && typeof value === "object" && "signal" in value && "abort" in value && typeof value.abort === "function" && ((_a = value.constructor) == null ? void 0 : _a.name) === "AbortController";
  };
  const isAbortSignal = (value) => {
    var _a;
    return value !== null && typeof value === "object" && "aborted" in value && typeof value.aborted === "boolean" && ((_a = value.constructor) == null ? void 0 : _a.name) === "AbortSignal";
  };
  const isPerformanceObserver = (value) => {
    var _a;
    return value !== null && typeof value === "object" && "observe" in value && "disconnect" in value && typeof value.observe === "function" && ((_a = value.constructor) == null ? void 0 : _a.name) === "PerformanceObserver";
  };
  const isPerformanceEntry = (value) => {
    var _a, _b;
    return value !== null && typeof value === "object" && "name" in value && "entryType" in value && "startTime" in value && "duration" in value && ((_b = (_a = value.constructor) == null ? void 0 : _a.name) == null ? void 0 : _b.includes("Performance"));
  };
  const nodePlugin = createPlugin({
    name: "node",
    version: "1.0.0",
    types: {
      "node.readablestream": isReadableStream,
      "node.writablestream": isWritableStream,
      "node.duplexstream": isDuplexStream,
      "node.transformstream": isTransformStream,
      "node.server": isServer,
      "node.incomingmessage": isIncomingMessage,
      "node.serverresponse": isServerResponse,
      "node.childprocess": isChildProcess,
      "node.worker": isWorker,
      "node.messageport": isMessagePort,
      "node.url": isURL,
      "node.urlsearchparams": isURLSearchParams,
      "node.textencoder": isTextEncoder,
      "node.textdecoder": isTextDecoder,
      "node.abortcontroller": isAbortController,
      "node.abortsignal": isAbortSignal,
      "node.performanceobserver": isPerformanceObserver,
      "node.performanceentry": isPerformanceEntry
    }
  });

  function kindOf(value) {
    return kindOfCore(value);
  }
  const typeOf = kindOf;
  const getType = kindOf;

  exports.PerformanceMonitor = PerformanceMonitor;
  exports.assertType = assertType;
  exports.clearCache = clearCache;
  exports.coerceType = coerceType;
  exports.compareTypes = compareTypes;
  exports.countByType = countByType;
  exports.createKindOfInstance = createKindOfInstance;
  exports.createPlugin = createPlugin;
  exports.createTypeMap = createTypeMap;
  exports.createValidator = createValidator;
  exports.default = kindOf;
  exports.disableCache = disableCache;
  exports.enableCache = enableCache;
  exports.ensureType = ensureType;
  exports.everyOfType = everyOfType;
  exports.fastKindOf = fastKindOf;
  exports.filterByType = filterByType;
  exports.findByType = findByType;
  exports.getDetailedType = getDetailedType;
  exports.getLeastCommonType = getLeastCommonType;
  exports.getMostCommonType = getMostCommonType;
  exports.getType = getType;
  exports.getTypeCategory = getTypeCategory;
  exports.getTypeStats = getTypeStats;
  exports.getUniqueTypes = getUniqueTypes;
  exports.groupByType = groupByType;
  exports.hasLength = hasLength;
  exports.hasSize = hasSize;
  exports.inspect = inspect;
  exports.inspectType = inspectType;
  exports.isArguments = isArguments;
  exports.isArray = isArray;
  exports.isArrayBuffer = isArrayBuffer;
  exports.isArrayLike = isArrayLike;
  exports.isAsyncFunction = isAsyncFunction;
  exports.isAsyncGenerator = isAsyncGenerator;
  exports.isAsyncGeneratorFunction = isAsyncGeneratorFunction;
  exports.isAsyncIterable = isAsyncIterable;
  exports.isBigInt = isBigInt;
  exports.isBigInt64Array = isBigInt64Array;
  exports.isBigUint64Array = isBigUint64Array;
  exports.isBoolean = isBoolean;
  exports.isBuffer = isBuffer;
  exports.isConstructor = isConstructor;
  exports.isDataView = isDataView;
  exports.isDate = isDate;
  exports.isDocument = isDocument;
  exports.isElement = isElement;
  exports.isEmpty = isEmpty;
  exports.isEmptyArray = isEmptyArray;
  exports.isEmptyObject = isEmptyObject;
  exports.isEmptyString = isEmptyString;
  exports.isError = isError;
  exports.isEvalError = isEvalError;
  exports.isEventEmitter = isEventEmitter;
  exports.isFalsy = isFalsy;
  exports.isFinite = isFinite;
  exports.isFloat32Array = isFloat32Array;
  exports.isFloat64Array = isFloat64Array;
  exports.isFunction = isFunction;
  exports.isGenerator = isGenerator;
  exports.isGeneratorFunction = isGeneratorFunction;
  exports.isGlobal = isGlobal;
  exports.isHeterogeneous = isHeterogeneous;
  exports.isHomogeneous = isHomogeneous;
  exports.isInfinity = isInfinity;
  exports.isInt16Array = isInt16Array;
  exports.isInt32Array = isInt32Array;
  exports.isInt8Array = isInt8Array;
  exports.isInteger = isInteger;
  exports.isIterable = isIterable;
  exports.isJsonString = isJsonString;
  exports.isMap = isMap;
  exports.isNaN = isNaN$1;
  exports.isNode = isNode;
  exports.isNull = isNull;
  exports.isNullish = isNullish;
  exports.isNumber = isNumber;
  exports.isNumericString = isNumericString;
  exports.isObject = isObject;
  exports.isObservable = isObservable;
  exports.isPlainObject = isPlainObject;
  exports.isPrimitive = isPrimitive;
  exports.isPromise = isPromise;
  exports.isProxy = isProxy;
  exports.isRangeError = isRangeError;
  exports.isReferenceError = isReferenceError;
  exports.isRegExp = isRegExp;
  exports.isSafeInteger = isSafeInteger;
  exports.isSet = isSet;
  exports.isSharedArrayBuffer = isSharedArrayBuffer;
  exports.isStream = isStream;
  exports.isString = isString;
  exports.isSymbol = isSymbol;
  exports.isSyntaxError = isSyntaxError;
  exports.isThenable = isThenable;
  exports.isTruthy = isTruthy;
  exports.isType = isType;
  exports.isTypeError = isTypeError;
  exports.isTypeOfAll = isTypeOfAll;
  exports.isTypeOfAny = isTypeOfAny;
  exports.isTypedArray = isTypedArray;
  exports.isURIError = isURIError;
  exports.isUint16Array = isUint16Array;
  exports.isUint32Array = isUint32Array;
  exports.isUint8Array = isUint8Array;
  exports.isUint8ClampedArray = isUint8ClampedArray;
  exports.isUndefined = isUndefined;
  exports.isValidType = isValidType;
  exports.isWeakMap = isWeakMap;
  exports.isWeakSet = isWeakSet;
  exports.isWindow = isWindow;
  exports.kindOf = kindOf;
  exports.kindOfMany = kindOfMany;
  exports.nodePlugin = nodePlugin;
  exports.noneOfType = noneOfType;
  exports.partition = partition;
  exports.partitionByType = partitionByType;
  exports.performanceMonitor = performanceMonitor;
  exports.reactPlugin = reactPlugin;
  exports.someOfType = someOfType;
  exports.toArray = toArray;
  exports.toBigInt = toBigInt;
  exports.toBoolean = toBoolean;
  exports.toBuffer = toBuffer;
  exports.toDate = toDate;
  exports.toError = toError;
  exports.toFunction = toFunction;
  exports.toMap = toMap;
  exports.toNumber = toNumber;
  exports.toObject = toObject;
  exports.toPromise = toPromise;
  exports.toRegExp = toRegExp;
  exports.toSet = toSet;
  exports.toString = toString;
  exports.toSymbol = toSymbol;
  exports.toTypedArray = toTypedArray;
  exports.typeOf = typeOf;
  exports.validateSchema = validateSchema;

  Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=kindof.umd.js.map