@ecosy/core 0.3.4 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +163 -0
- package/README.md +7 -0
- package/agents/skills/ecosy-core-serialize/SKILL.md +93 -0
- package/agents/skills/ecosy-core-subscriber/SKILL.md +66 -0
- package/dist/cache/disk.d.ts +32 -0
- package/dist/cache/disk.js +1 -0
- package/dist/cache/disk.mjs +1 -0
- package/dist/cache/index.d.ts +17 -0
- package/dist/cache/index.js +1 -0
- package/dist/cache/index.mjs +1 -0
- package/dist/cache/memory.d.ts +19 -0
- package/dist/cache/memory.js +1 -0
- package/dist/cache/memory.mjs +1 -0
- package/dist/cache/redis.d.ts +63 -0
- package/dist/cache/redis.js +1 -0
- package/dist/cache/redis.mjs +1 -0
- package/dist/cache/types.d.ts +35 -0
- package/dist/cache/types.js +1 -0
- package/dist/cache/types.mjs +1 -0
- package/dist/ecosy-core.umd.js +2 -0
- package/dist/ecosy-core.umd.js.map +1 -0
- package/dist/index.d.ts +0 -9
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/serialize/index.d.ts +62 -0
- package/dist/serialize/index.js +1 -0
- package/dist/serialize/index.mjs +1 -0
- package/dist/serialize/interpolate.d.ts +10 -0
- package/dist/serialize/interpolate.js +1 -0
- package/dist/serialize/interpolate.mjs +1 -0
- package/dist/serialize/json.d.ts +3 -0
- package/dist/serialize/json.js +1 -0
- package/dist/serialize/json.mjs +1 -0
- package/dist/serialize/primitive.d.ts +3 -0
- package/dist/serialize/primitive.js +1 -0
- package/dist/serialize/primitive.mjs +1 -0
- package/dist/serialize/query-string.d.ts +3 -0
- package/dist/serialize/query-string.js +1 -0
- package/dist/serialize/query-string.mjs +1 -0
- package/dist/serialize/types.d.ts +42 -0
- package/dist/serialize/types.js +1 -0
- package/dist/serialize/types.mjs +1 -0
- package/dist/serialize/url.d.ts +3 -0
- package/dist/serialize/url.js +1 -0
- package/dist/serialize/url.mjs +1 -0
- package/dist/syhemo/collectors.d.ts +25 -0
- package/dist/syhemo/collectors.js +1 -0
- package/dist/syhemo/collectors.mjs +1 -0
- package/dist/syhemo/exposition.d.ts +15 -0
- package/dist/syhemo/exposition.js +1 -0
- package/dist/syhemo/exposition.mjs +1 -0
- package/dist/syhemo/index.d.ts +50 -0
- package/dist/syhemo/index.js +1 -0
- package/dist/syhemo/index.mjs +1 -0
- package/dist/{logger.d.ts → syhemo/logger.d.ts} +23 -11
- package/dist/syhemo/logger.js +1 -0
- package/dist/{logger.mjs → syhemo/logger.mjs} +1 -1
- package/dist/syhemo/types.d.ts +114 -0
- package/dist/syhemo/types.js +1 -0
- package/dist/syhemo/types.mjs +1 -0
- package/dist/utilities/index.d.ts +2 -0
- package/dist/utilities/index.js +1 -1
- package/dist/utilities/index.mjs +1 -1
- package/dist/{searchify.d.ts → utilities/searchify.d.ts} +1 -1
- package/dist/utilities/searchify.js +1 -0
- package/dist/utilities/searchify.mjs +1 -0
- package/package.json +52 -39
- package/dist/env.d.ts +0 -26
- package/dist/env.js +0 -1
- package/dist/env.mjs +0 -1
- package/dist/http.d.ts +0 -294
- package/dist/http.js +0 -1
- package/dist/http.mjs +0 -1
- package/dist/logger.js +0 -1
- package/dist/searchify.js +0 -1
- package/dist/searchify.mjs +0 -1
- package/dist/serialize.d.ts +0 -80
- package/dist/serialize.js +0 -1
- package/dist/serialize.mjs +0 -1
- package/dist/syhemo.d.ts +0 -102
- package/dist/syhemo.js +0 -1
- package/dist/syhemo.mjs +0 -1
- /package/dist/{slugify.d.ts → utilities/slugify.d.ts} +0 -0
- /package/dist/{slugify.js → utilities/slugify.js} +0 -0
- /package/dist/{slugify.mjs → utilities/slugify.mjs} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecosy-core.umd.js","sources":["../src/utilities/get.ts","../src/serialize/interpolate.ts","../src/utilities/string.ts","../src/utilities/is-function.ts","../src/utilities/object.ts","../src/utilities/clone.ts","../src/utilities/freeze.ts","../src/serialize/primitive.ts","../src/serialize/json.ts","../src/serialize/url.ts","../src/serialize/query-string.ts","../src/serialize/index.ts","../src/utilities/is-equal.ts","../src/utilities/merge.ts","../src/subscriber.ts","../src/utilities/defer.ts","../src/utilities/filelist.ts","../src/utilities/sanitize-mime.ts","../src/utilities/slugify.ts","../src/utilities/searchify.ts","../src/utilities/flatten.ts","../src/utilities/formdata.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Safely retrieves a nested value from an object using a dot/bracket path.\n * Returns `defaultValue` only when the resolved value is `undefined` —\n * falsy values like `null`, `0`, `false`, and `\"\"` are returned as-is.\n *\n * @param data - The source object to traverse.\n * @param path - Dot-notation string (`\"a.b.c\"`), bracket-notation (`\"a[0].b\"`), or an array of keys.\n * @param defaultValue - Value returned when the path resolves to `undefined`.\n * @returns The resolved value, or `defaultValue` if not found.\n *\n * @example\n * ```ts\n * const obj = { users: [{ name: \"Alice\" }] };\n *\n * get(obj, \"users[0].name\"); // \"Alice\"\n * get(obj, \"users.0.name\"); // \"Alice\"\n * get(obj, \"users[1].name\", \"N/A\"); // \"N/A\"\n * get(obj, \"count\", 0); // 0\n * ```\n */\nexport function get(data, path, defaultValue) {\n // 1. Short-circuit if data is nullish\n if (data === null || data === undefined) {\n return defaultValue;\n }\n // 2. Normalize path into an array of keys\n // Handles both dot notation (\"a.b\") and bracket notation (\"a[0]\")\n const keys = Array.isArray(path)\n ? path\n : path\n .replace(/\\[(\\d+)]/g, \".$1\") // Convert \"users[0]\" to \"users.0\"\n .split(\".\")\n .filter(Boolean); // Remove empty segments from leading/trailing dots\n if (keys.length === 0) {\n return data;\n }\n // 3. Traverse the object tree\n let result = data;\n for (const key of keys) {\n // Stop early if we hit null/undefined mid-path\n if (result === null || result === undefined) {\n return defaultValue;\n }\n result = result[key];\n }\n // 4. Return defaultValue only for undefined; null, 0, false, \"\" are valid results\n return result === undefined ? defaultValue : result;\n}\n","import { get } from \"../utilities/get\";\n/**\n * Interpolates `{key}` placeholders in a string using deep path resolution via {@link get}.\n * Objects are silently replaced with empty strings to avoid `[object Object]`.\n *\n * @param pattern - Template string with `{key}` or `{path.to.key}` placeholders.\n * @param params - Data object or array to resolve values from.\n * @returns The interpolated string.\n */\nexport function interpolate(pattern, params = {}) {\n // Fast-path: skip processing if no placeholders\n if (!pattern ||\n typeof pattern !== \"string\" ||\n !pattern.trim().length ||\n !pattern.includes(\"{\") ||\n !pattern.includes(\"}\")) {\n return pattern;\n }\n // Scan for placeholders and resolve lazily via `get`\n return pattern.replace(/\\{([a-zA-Z0-9_.-]+)\\}/g, (match, variable) => {\n const value = get(params, variable);\n // Unresolved placeholders become empty strings\n if (value === null || value === undefined) {\n return \"\";\n }\n // Prevent \"[object Object]\" — only render primitives\n if (typeof value === \"object\") {\n return \"\";\n }\n return String(value);\n });\n}\n/** Type guards and deep normalization utilities. */\n","/**\n * Returns the internal `[[Class]]` tag of a value using `Object.prototype.toString`.\n *\n * @example\n * ```ts\n * toString([]); // \"[object Array]\"\n * toString(null); // \"[object Null]\"\n * ```\n */\nexport function toString(value) {\n return Object.prototype.toString.call(value);\n}\n/**\n * Capitalizes the first character of a string.\n *\n * @example\n * ```ts\n * ucfirst(\"hello\"); // \"Hello\"\n * ```\n */\nexport function ucfirst(str) {\n return (str.charAt(0).toUpperCase() + str.slice(1));\n}\n/**\n * Converts a PascalCase or camelCase string to kebab-case.\n * Handles consecutive uppercase characters (e.g. acronyms) gracefully.\n *\n * @example\n * ```ts\n * pascalToKebab(\"MyComponent\"); // \"my-component\"\n * pascalToKebab(\"HTMLParser\"); // \"html-parser\"\n * pascalToKebab(\"camelCase\"); // \"camel-case\"\n * ```\n */\nexport function pascalToKebab(str) {\n if (!str)\n return str;\n return str\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/([A-Z])([A-Z][a-z])/g, \"$1-$2\")\n .toLowerCase();\n}\n","import { toString } from \"./string\";\n/**\n * Checks whether a value is a function (including async and generator functions).\n *\n * @param value - The value to check.\n * @returns `true` if the value is a function.\n *\n * @example\n * ```ts\n * isFunction(() => {}); // true\n * isFunction(async () => {}); // true\n * isFunction(42); // false\n * ```\n */\nexport function isFunction(value) {\n return (typeof value === \"function\" ||\n [\"[object Function]\", \"[object AsyncFunction]\", \"[object GeneratorFunction]\"].includes(toString(value)));\n}\n","import { isFunction } from \"./is-function\";\n/**\n * Checks whether a value is a non-null object.\n *\n * @param value - The value to check.\n * @returns `true` if the value is of type `object` and is not `null`.\n */\nexport function isObject(value) {\n return typeof value === \"object\" && value !== null;\n}\n/**\n * Checks whether a value is a plain object (created by `{}` or `Object.create(null)`).\n *\n * @param value - The value to check.\n * @returns `true` if the value is a plain literal object.\n */\nexport function isLiteralObject(value) {\n if (!isObject(value) || Array.isArray(value)) {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n return proto === null || proto === Object.prototype;\n}\n/**\n * Checks whether a value is a complex (non-array) object, such as a class instance.\n *\n * @param value - The value to check.\n * @returns `true` if the value is a non-array object.\n */\nexport function isComplexObject(value) {\n return isObject(value) && !Array.isArray(value);\n}\n/**\n * Checks whether a value is an object, array, or function.\n *\n * @param value - The value to check.\n * @returns `true` if the value is \"objectable\" (object, array, or function).\n */\nexport function isObjectable(value) {\n return isObject(value) || isFunction(value);\n}\n/**\n * Type-safe check for own property existence on an object.\n *\n * @param obj - The object to check.\n * @param key - The property key to look for.\n * @returns `true` if the object has the specified own property.\n *\n * @example\n * ```ts\n * hasOwnProperty({ a: 1 }, \"a\"); // true\n * hasOwnProperty({ a: 1 }, \"b\"); // false\n * ```\n */\nexport function hasOwnProperty(obj, key) {\n if (!obj) {\n return false;\n }\n if (!isObjectable(obj)) {\n return Object.prototype.hasOwnProperty.call(obj, key);\n }\n return (Object.prototype.hasOwnProperty.call(obj, key) || key in obj);\n}\n","import { isFunction } from \"./is-function\";\nimport { hasOwnProperty, isObjectable } from \"./object\";\nconst cloneStrateries = {\n [Date.toString()]: (data) => new Date(data.getTime()),\n [RegExp.toString()]: (data) => new RegExp(data.source, data.flags),\n [Map.toString()]: (data, cache) => {\n const result = new Map();\n cache.set(data, result);\n data.forEach((val, key) => {\n result.set(clone(key, cache), clone(val, cache));\n });\n return result;\n },\n [Set.toString()]: (data, cache) => {\n const result = new Set();\n cache.set(data, result);\n data.forEach((val) => {\n result.add(clone(val, cache));\n });\n return result;\n },\n [ArrayBuffer.toString()]: (data) => {\n return data.slice(0);\n },\n};\nconst Strateries = [Date, RegExp, Map, Set, ArrayBuffer];\nconst NumberTypedArray = [\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n Float32Array,\n Float64Array,\n BigInt64Array,\n BigUint64Array,\n DataView,\n];\nconst DoNotClone = (() => {\n return Array.from(new Set([\n // Built-in\n Error,\n Promise,\n Blob,\n // Split by environment\n typeof WeakMap !== \"undefined\" && WeakMap,\n typeof WeakSet !== \"undefined\" && WeakSet,\n typeof Symbol !== \"undefined\" && Symbol,\n typeof Window !== \"undefined\" && Window,\n typeof File !== \"undefined\" && File,\n typeof FormData !== \"undefined\" && FormData,\n typeof Headers !== \"undefined\" && Headers,\n typeof Request !== \"undefined\" && Request,\n typeof Response !== \"undefined\" && Response,\n typeof Worker !== \"undefined\" && Worker,\n typeof AbortController !== \"undefined\" && AbortController,\n typeof Node !== \"undefined\" && Node,\n typeof FileList !== \"undefined\" && FileList,\n ]));\n})();\nfunction isConstructor(constructor, targets) {\n return targets.includes(constructor);\n}\n/**\n * Deep clones a value, handling circular references, built-in types (Date, RegExp, Map, Set,\n * ArrayBuffer, TypedArrays), arrays, and plain objects. Skips non-cloneable types like\n * Error, Promise, WeakMap, DOM nodes, etc.\n *\n * @param data - The value to clone.\n * @param cache - Internal WeakMap used to track circular references.\n * @returns A deep copy of the input value.\n *\n * @example\n * ```ts\n * const original = { a: 1, b: { c: 2 } };\n * const cloned = clone(original);\n * cloned.b.c = 3;\n * original.b.c; // still 2\n * ```\n */\nexport function clone(data, cache = new WeakMap()) {\n var _a;\n if (!isObjectable(data) ||\n isFunction(data) ||\n hasOwnProperty(data, \"$$typeof\") ||\n (data.constructor && isConstructor(data.constructor, DoNotClone))) {\n return data;\n }\n // Prevent circular references\n if (cache.has(data)) {\n return cache.get(data);\n }\n if (data.constructor && isConstructor(data.constructor, NumberTypedArray)) {\n const itemData = data;\n const ItemClass = data.constructor;\n const result = new ItemClass(itemData.buffer.slice(0), itemData.byteOffset, itemData.byteLength);\n cache.set(data, result);\n return result;\n }\n const ItemConstructor = data.constructor;\n if (Strateries.includes(ItemConstructor)) {\n const handleName = ItemConstructor.toString();\n const handler = cloneStrateries[handleName];\n const result = handler(data, cache);\n cache.set(data, result);\n return result;\n }\n // Is Object | Array | Class | Instance | Function\n const result = Array.isArray(data)\n ? new (((_a = Object.getPrototypeOf(data)) === null || _a === void 0 ? void 0 : _a.constructor) || Array)()\n : Object.create(Object.getPrototypeOf(data));\n cache.set(data, result);\n const keys = Reflect.ownKeys(data);\n for (const key of keys) {\n const descriptor = Object.getOwnPropertyDescriptor(data, key);\n if (descriptor) {\n if (\"value\" in descriptor) {\n descriptor.value = clone(descriptor.value, cache);\n }\n Object.defineProperty(result, key, descriptor);\n }\n }\n return result;\n}\n","import { clone } from \"./clone\";\nimport { isObject } from \"./object\";\nfunction deepFreezeInternal(obj) {\n const propNames = Reflect.ownKeys(obj);\n for (const name of propNames) {\n const value = obj[name];\n if (isObject(value)) {\n deepFreezeInternal(value);\n }\n }\n return Object.freeze(obj);\n}\n/**\n * Deep freezes a value by first cloning it, then recursively calling `Object.freeze`.\n * Primitives are returned as-is.\n *\n * @param data - The value to freeze.\n * @param cloneDeep - Custom clone function (defaults to `clone`).\n * @returns A deeply frozen copy of the input.\n *\n * @example\n * ```ts\n * const frozen = freeze({ a: { b: 1 } });\n * frozen.a.b = 2; // throws in strict mode\n * ```\n */\nexport function freeze(data, cloneDeep = clone) {\n if (!isObject(data)) {\n return data;\n }\n const cloned = cloneDeep(data);\n return deepFreezeInternal(cloned);\n}\n","import { freeze } from \"../utilities/freeze\";\nimport { hasOwnProperty, isLiteralObject, isObjectable } from \"../utilities/object\";\nimport { isFunction } from \"../utilities/is-function\";\n/** Type guards and deep normalization utilities. */\nexport const Primitive = freeze({\n isString: (value) => {\n return typeof value === \"string\";\n },\n isNumber(value) {\n return typeof value === \"number\" && Number.isFinite(value);\n },\n isBoolean(value) {\n return typeof value === \"boolean\";\n },\n isPrimitive(value) {\n return !isObjectable(value);\n },\n isDate(value) {\n return value instanceof Date && !Number.isNaN(value.getTime());\n },\n isPlainObject: isLiteralObject,\n normalize(data) {\n const prim = Primitive;\n if (prim.isPrimitive(data)) {\n if (typeof data === \"bigint\")\n return data.toString();\n return data;\n }\n if (prim.isDate(data)) {\n return data.toISOString();\n }\n if (Array.isArray(data)) {\n return data.map((item) => prim.normalize(item));\n }\n // Use isLiteralObject for consistent plain-object detection\n if (isLiteralObject(data)) {\n const result = {};\n for (const key in data) {\n if (hasOwnProperty(data, key)) {\n const val = data[key];\n if (val !== undefined) {\n result[key] = prim.normalize(val);\n }\n }\n }\n return result;\n }\n if (data && hasOwnProperty(data, \"toJSON\") && isFunction(data.toJSON)) {\n return data.toJSON();\n }\n return {};\n },\n});\n","import { freeze } from \"../utilities/freeze\";\nimport { Primitive } from \"./primitive\";\n/** Safe JSON stringify/parse that never throws. */\nexport const Json = freeze({\n stringify: (value, space) => {\n var _a;\n try {\n const normalized = Primitive.normalize(value);\n return (_a = JSON.stringify(normalized, null, space)) !== null && _a !== void 0 ? _a : \"\";\n }\n catch (_b) {\n // Catch edge cases (e.g. circular references not handled by normalize)\n return \"\";\n }\n },\n parse: (text, reviver) => {\n if (!text) {\n return null;\n }\n try {\n return JSON.parse(text, reviver);\n }\n catch (_a) {\n return null; // Return null instead of throwing to keep the flow alive\n }\n },\n});\n","import { freeze } from \"../utilities/freeze\";\n/** URL encoding/decoding with malformed-character recovery. */\nexport const Url = freeze({\n encode(value, component = true) {\n if (!value)\n return \"\";\n if (typeof component === \"function\")\n return component(value);\n try {\n return component ? encodeURIComponent(value) : encodeURI(value);\n }\n catch (_a) {\n // Strip broken surrogate chars and retry instead of crashing\n const sanitized = value.replace(/[\\uD800-\\uDFFF]/g, \"\");\n return component ? encodeURIComponent(sanitized) : encodeURI(sanitized);\n }\n },\n decode: (value, component = true) => {\n if (!value)\n return \"\";\n if (typeof component === \"function\")\n return component(value);\n const decoder = component ? decodeURIComponent : decodeURI;\n const normalized = component ? value.replace(/\\+/g, \"%20\") : value;\n return normalized.replace(/(%[0-9A-F]{2})+/gi, (match) => {\n try {\n return decoder(match);\n }\n catch (_a) {\n console.warn(`[Serialize.URL] Cannot decode part: ${match}`);\n return match; // Keep broken parts intact, recover what we can\n }\n });\n },\n build: (uri, params) => {\n if (!uri)\n return \"\";\n if (!params || typeof params !== \"object\")\n return uri;\n // Single-pass regex replace for maximum speed\n return uri.replace(/:([a-zA-Z\\d_]+)/g, (fullMatch, key) => {\n const value = params[key];\n // If param is not provided, keep the \":key\" placeholder\n if (value === null || value === undefined) {\n return fullMatch;\n }\n // Auto-encode the value using the same URL encoder\n return Url.encode(String(value), true);\n });\n },\n});\n","import { freeze } from \"../utilities/freeze\";\nimport { Primitive } from \"./primitive\";\nimport { Url } from \"./url\";\n/** Query string parse/stringify with configurable array formats. */\nexport const queryString = freeze({\n parse(query) {\n if (!query)\n return {};\n const cleanQuery = query.startsWith(\"?\") ? query.slice(1) : query;\n const result = {};\n cleanQuery.split(\"&\").forEach((part) => {\n if (!part)\n return;\n const [key, value] = part.split(\"=\");\n if (key) {\n result[Url.decode(key)] = value ? Url.decode(value) : \"\";\n }\n });\n return result;\n },\n stringify(params, options = {}) {\n if (params === null || typeof params !== \"object\")\n return \"\";\n const { arrayFormat = \"none\", arrayFormatSeparator = \",\", skipNull = false, skipEmptyString = false, encode = true, strict = true, sort = false, } = options;\n const isValidKey = (k) => k.length > 0 && /^[a-zA-Z0-9_\\-.[\\]]+$/.test(k);\n // Internal encode wrapper\n const encoder = (val) => {\n if (!encode)\n return val;\n return Url.encode(val, encode);\n };\n const resultPairs = [];\n // Flat recursion — traverse arrays and nested objects\n const traverse = (prefix, obj) => {\n if (Array.isArray(obj)) {\n if (arrayFormat === \"comma\" || arrayFormat === \"separator\") {\n const validVals = obj.filter((v) => v !== null && v !== undefined && v !== \"\");\n if (validVals.length > 0) {\n resultPairs.push(`${encoder(prefix)}=${encoder(validVals.map(String).join(arrayFormatSeparator))}`);\n }\n return;\n }\n obj.forEach((val, idx) => {\n let arrayKey = prefix;\n if (arrayFormat === \"bracket\")\n arrayKey = `${prefix}[]`;\n else if (arrayFormat === \"index\")\n arrayKey = `${prefix}[${idx}]`;\n traverse(arrayKey, val);\n });\n return;\n }\n if (Primitive.isPlainObject(obj)) {\n for (const subKey in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, subKey)) {\n traverse(`${prefix}[${subKey}]`, obj[subKey]);\n }\n }\n return;\n }\n // Primitive formatting\n if (obj === null || obj === undefined) {\n if (!skipNull)\n resultPairs.push(`${encoder(prefix)}=`);\n return;\n }\n if (obj === \"\") {\n if (!skipEmptyString)\n resultPairs.push(`${encoder(prefix)}=`);\n return;\n }\n if (typeof obj === \"boolean\") {\n resultPairs.push(`${encoder(prefix)}=${obj ? \"true\" : \"false\"}`);\n return;\n }\n if (Primitive.isDate(obj)) {\n resultPairs.push(`${encoder(prefix)}=${encoder(obj.toISOString())}`);\n return;\n }\n resultPairs.push(`${encoder(prefix)}=${encoder(String(obj))}`);\n };\n // Run the top-level iteration\n let keys = Object.keys(params);\n if (sort)\n keys = typeof sort === \"function\" ? keys.sort(sort) : keys.sort();\n for (const key of keys) {\n if (strict && !isValidKey(key))\n continue;\n traverse(key, params[key]);\n }\n return resultPairs.join(\"&\");\n },\n});\n","import { interpolate } from \"./interpolate\";\nimport { Json } from \"./json\";\nimport { Primitive } from \"./primitive\";\nimport { queryString } from \"./query-string\";\nimport { Url } from \"./url\";\nexport * from \"./types\";\nexport { interpolate } from \"./interpolate\";\nexport { Json } from \"./json\";\nexport { Primitive } from \"./primitive\";\nexport { queryString } from \"./query-string\";\nexport { Url } from \"./url\";\n/**\n * Centralized serialization engine and type-guard toolkit.\n * Addresses common pitfalls of `JSON.stringify`/`JSON.parse` — BigInt safety,\n * Date preservation, undefined stripping, and safe URL encoding/decoding.\n *\n * This is the convenience surface: it gathers every part under one name.\n * Referencing it keeps all of them, because a class is a single binding and a\n * bundler cannot drop half of one. Code that cares about what it ships should\n * import the part it uses instead — each lives in its own module, so nothing\n * else comes with it:\n *\n * ```ts\n * import { Primitive } from \"@ecosy/core/serialize/primitive\";\n * import { queryString } from \"@ecosy/core/serialize/query-string\";\n * ```\n *\n * The two are the same objects, so mixing them is free.\n *\n * @example\n * ```ts\n * Serialize.JSON.stringify({ date: new Date(), big: 123n });\n * Serialize.JSON.parse<User>(jsonText);\n * Serialize.URL.encode(\"hello world\");\n * Serialize.queryString.stringify({ page: 1, tags: [\"a\", \"b\"] });\n * ```\n */\nexport class Serialize {\n}\nSerialize.interpolate = interpolate;\n/** Type guards and deep normalization utilities. */\nSerialize.Primitive = Primitive;\n/** Safe JSON stringify/parse that never throws. */\nSerialize.JSON = Json;\n/** URL encoding/decoding with malformed-character recovery. */\nSerialize.URL = Url;\n/** Query string parse/stringify with configurable array formats. */\nSerialize.queryString = queryString;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { hasOwnProperty, isLiteralObject, isObject } from \"./object\";\nfunction isEqualArrayBuffer(value1, value2) {\n if (value1.byteLength !== value2.byteLength) {\n return false;\n }\n const buffer1 = ArrayBuffer.isView(value1) ? value1.buffer : value1;\n const offset1 = ArrayBuffer.isView(value1) ? value1.byteOffset : 0;\n const buffer2 = ArrayBuffer.isView(value2) ? value2.buffer : value2;\n const offset2 = ArrayBuffer.isView(value2) ? value2.byteOffset : 0;\n const view1 = new Uint8Array(buffer1, offset1, value1.byteLength);\n const view2 = new Uint8Array(buffer2, offset2, value2.byteLength);\n for (let i = 0; i < view1.length; i++) {\n if (view1[i] !== view2[i]) {\n return false;\n }\n }\n return true;\n}\nconst isEqualStrategies = new Map([\n [Date, (value1, value2) => Object.is(value1.getTime(), value2.getTime())],\n [\n RegExp,\n (value1, value2) => Object.is(value1.source, value2.source) && Object.is(value1.flags, value2.flags),\n ],\n [ArrayBuffer, isEqualArrayBuffer],\n [\n Map,\n (value1, value2) => {\n if (value1.size !== value2.size) {\n return false;\n }\n for (const [key, val] of value1) {\n if (!value2.has(key) || !isEqual(val, value2.get(key))) {\n return false;\n }\n }\n return true;\n },\n ],\n [\n Set,\n (value1, value2) => {\n if (value1.size !== value2.size) {\n return false;\n }\n for (const item1 of value1) {\n let hasMatch = false;\n for (const item2 of value2) {\n if (isEqual(item1, item2)) {\n hasMatch = true;\n break;\n }\n }\n if (!hasMatch) {\n return false;\n }\n }\n return true;\n },\n ],\n]);\n/**\n * Performs a deep structural equality check between two values.\n * Supports primitives, arrays, plain objects, Date, RegExp, Map, Set,\n * ArrayBuffer, and TypedArrays.\n *\n * @param value1 - The first value to compare.\n * @param value2 - The second value to compare.\n * @returns `true` if both values are deeply equal.\n *\n * @example\n * ```ts\n * isEqual({ a: 1 }, { a: 1 }); // true\n * isEqual([1, 2], [1, 3]); // false\n * isEqual(new Date(0), new Date(0)); // true\n * ```\n */\nexport function isEqual(value1, value2) {\n // primitive, null, function, avoid NaN === NaN is false\n if (!isObject(value1) || !isObject(value2)) {\n return Object.is(value1, value2);\n }\n // If complex object, check constructor\n if (value1.constructor !== value2.constructor) {\n return false;\n }\n if (Array.isArray(value1)) {\n if (!Array.isArray(value2) || value1.length !== value2.length) {\n return false;\n }\n for (let i = 0; i < value1.length; i++) {\n if (!isEqual(value1[i], value2[i])) {\n return false;\n }\n }\n return true;\n }\n // TypedArray, same logic array because constructor match above\n if (ArrayBuffer.isView(value1) && ArrayBuffer.isView(value2)) {\n return isEqualArrayBuffer(value1, value2);\n }\n if (value1.constructor && isEqualStrategies.has(value1.constructor)) {\n return isEqualStrategies.get(value1.constructor)(value1, value2);\n }\n if (!isLiteralObject(value1) || !isLiteralObject(value2)) {\n return value1 === value2;\n }\n const keys1 = Object.keys(value1);\n const keys2 = Object.keys(value2);\n if (keys1.length !== keys2.length) {\n return false;\n }\n for (const key of keys1) {\n if (!hasOwnProperty(value2, key) ||\n !isEqual(value1[key], value2[key])) {\n return false;\n }\n }\n return true;\n}\n","import { clone } from \"./clone\";\nimport { isLiteralObject } from \"./object\";\nfunction isValidKey(key) {\n return key !== \"__proto__\" && key !== \"constructor\" && key !== \"prototype\";\n}\n/**\n * Deep merges `target` into `source`. If both are plain objects, properties are merged\n * recursively. Otherwise, `target` replaces `source`. Prototype-polluting keys\n * (`__proto__`, `constructor`, `prototype`) are rejected.\n *\n * @param source - The base object.\n * @param target - The object whose values are merged into `source`.\n * @param cloneDeep - Custom deep clone function (defaults to `clone`).\n * @returns The merged result.\n *\n * @example\n * ```ts\n * merge({ a: 1, b: { c: 2 } }, { b: { d: 3 } });\n * // { a: 1, b: { c: 2, d: 3 } }\n * ```\n */\nexport function merge(source, target, cloneDeep = clone) {\n if (target === undefined) {\n return cloneDeep(source);\n }\n if (isLiteralObject(source) && isLiteralObject(target)) {\n const result = Object.assign({}, source);\n Object.keys(target).forEach((key) => {\n if (!isValidKey(key)) {\n return;\n }\n const sourceValue = result[key];\n const targetValue = target[key];\n if (isLiteralObject(sourceValue) && isLiteralObject(targetValue)) {\n result[key] = merge(sourceValue, targetValue, cloneDeep);\n }\n else {\n result[key] = cloneDeep(targetValue);\n }\n });\n return result;\n }\n return cloneDeep(target);\n}\n","import { clone } from \"./utilities/clone\";\nimport { freeze } from \"./utilities/freeze\";\nimport { isEqual } from \"./utilities/is-equal\";\nimport { isLiteralObject } from \"./utilities/object\";\nimport { merge } from \"./utilities/merge\";\nimport { ucfirst } from \"./utilities/string\";\nclass SubscribeListener extends Set {\n}\nclass SubscribeListeners extends Map {\n}\nconst defaultEvents = freeze({\n state: {\n change: \"$state:change\",\n },\n});\n/**\n * Generic pub/sub event emitter with built-in state management.\n * Provides subscribe/dispatch for arbitrary channels and state change notifications.\n *\n * @typeParam State - The shape of the internal state object.\n * @typeParam Events - Extended event definitions to wire onto the instance.\n */\nexport class Subscriber {\n get shallow() {\n return freeze({\n merge: this._shallow.merge,\n clone: this._shallow.clone,\n isEqual: this._shallow.isEqual,\n });\n }\n set shallow(shallow) {\n this._shallow = this._shallow.merge(this._shallow, shallow);\n }\n constructor(initialState, events) {\n this._state = {};\n this.listeners = new SubscribeListeners();\n this._shallow = {\n merge,\n clone,\n isEqual,\n };\n this._events = freeze(defaultEvents);\n this._state = (initialState !== null && initialState !== void 0 ? initialState : {});\n this._events = freeze(Object.assign(Object.assign({}, this._events), events));\n }\n /**\n * Subscribes a handler to a named channel.\n *\n * @param channel - The event channel name.\n * @param handler - Callback invoked when the channel is dispatched.\n * @returns An unsubscribe function.\n */\n subscribe(channel, handler) {\n if (!this.listeners.has(channel)) {\n this.listeners.set(channel, new SubscribeListener());\n }\n this.listeners.get(channel).add(handler);\n return () => {\n var _a;\n (_a = this.listeners.get(channel)) === null || _a === void 0 ? void 0 : _a.delete(handler);\n };\n }\n /**\n * Dispatches a payload to all handlers subscribed to the given channel.\n *\n * @param channel - The event channel name.\n * @param payload - Optional data to pass to each handler.\n */\n dispatch(channel, payload) {\n if (!this.listeners.has(channel)) {\n return;\n }\n this.listeners.get(channel).forEach((handler) => {\n const params = payload === undefined ? [] : [payload];\n handler(...params);\n });\n }\n /** Returns the current state. */\n getState() {\n return this._state;\n }\n /**\n * Merges new state and dispatches a state change event if the state has changed.\n *\n * @param state - Full or partial state to merge.\n */\n setState(state) {\n const nextState = this._shallow.merge(this._state, state);\n if (!this._shallow.isEqual(this._state, nextState)) {\n this._state = nextState;\n this.dispatch(this._events.state.change, this._shallow.clone(nextState));\n }\n }\n /**\n * Shorthand to subscribe to state change events.\n *\n * @param handler - Callback receiving the new state.\n * @returns An unsubscribe function.\n */\n onStateChange(handler) {\n return this.subscribe(this._events.state.change, handler);\n }\n /**\n * Subscribes to a channel, resolving a Promise with the first dispatched payload.\n * Supports cancellation via an `AbortSignal`.\n *\n * @warning If the channel is never dispatched and no `AbortSignal` is provided,\n * the returned Promise will never resolve, causing a memory leak. Always pass an\n * `AbortSignal` or ensure the channel will eventually be dispatched.\n *\n * @param channel - The event channel name.\n * @param handler - Optional callback invoked on payload.\n * @param signal - Optional AbortSignal to cancel the subscription.\n * @returns A promise that resolves with the first payload dispatched to the channel.\n */\n async subscribeAsyncOnce(channel, handler, signal) {\n let unsub;\n let onAbort;\n try {\n return await new Promise((resolve, reject) => {\n if (signal === null || signal === void 0 ? void 0 : signal.aborted) {\n return reject(new Error(\"Operation cancelled\"));\n }\n const handle = ((payload) => {\n handler === null || handler === void 0 ? void 0 : handler(payload);\n resolve(payload);\n });\n unsub = this.subscribe(channel, handle);\n if (signal) {\n onAbort = () => reject(new Error(\"Operation cancelled\"));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n }\n finally {\n unsub === null || unsub === void 0 ? void 0 : unsub();\n if (signal && onAbort) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n }\n }\n /**\n * Wires event domains onto a `Subscriber` instance, creating typed dispatch and\n * listener methods (e.g. `instance.domainName.eventName()` and\n * `instance.domainName.onEventName()`).\n *\n * @param $instance - The subscriber instance to extend.\n * @param events - Event definitions mapping domain → channel names.\n * @returns The instance with wired event methods.\n */\n static wire($instance, events) {\n for (const channel in events) {\n if (channel in $instance) {\n throw new Error(`[Subscriber.wire] \"${channel}\" is invalid.`);\n }\n const domains = events[channel];\n if (!isLiteralObject(domains)) {\n continue;\n }\n const methods = Object.keys(domains).reduce((acc, domain) => {\n const channelName = domains[domain];\n acc[domain] = (payload) => {\n $instance.dispatch(channelName, payload);\n };\n acc[`on${ucfirst(domain)}`] = (listener) => $instance.subscribe(channelName, listener);\n return acc;\n }, {});\n Object.defineProperty($instance, channel, {\n value: freeze(methods),\n writable: false,\n enumerable: true,\n configurable: false,\n });\n }\n return $instance;\n }\n}\n","/**\n * Schedules a callback using `requestAnimationFrame` + `setTimeout` for optimal\n * browser execution timing. Falls back to plain `setTimeout` in non-browser environments.\n *\n * @param callback - Function to execute after the defer.\n * @param delay - Additional delay in milliseconds after the animation frame. Defaults to `0`.\n * @returns An object with `ids` (internal timer IDs) and a `cancel` function.\n *\n * @example\n * ```ts\n * const { cancel } = defer(() => console.log(\"done\"), 100);\n * // Later:\n * cancel(); // Cancels if not yet executed\n * ```\n */\nexport function defer(callback, delay) {\n const ids = { r: null, s: null };\n const timeout = Math.max(0, delay || 0);\n function cancel() {\n ids.r && typeof cancelAnimationFrame === \"function\" && cancelAnimationFrame(ids.r);\n ids.s && clearTimeout(ids.s);\n ids.r = null;\n ids.s = null;\n }\n if (typeof requestAnimationFrame === \"function\") {\n ids.r = requestAnimationFrame(() => {\n ids.s = setTimeout(() => {\n callback();\n cancel();\n }, timeout);\n });\n }\n else {\n ids.s = setTimeout(() => {\n callback();\n cancel();\n }, timeout);\n }\n return { ids, cancel };\n}\n/**\n * Promise-based wrapper around {@link defer}.\n * Resolves after the specified delay, and can be cancelled before resolution.\n *\n * @param delay - Delay in milliseconds. Defaults to `0`.\n * @returns A {@link CancelablePromise} that resolves when the defer completes.\n *\n * @example\n * ```ts\n * const wait = deferAsync(500);\n * await wait; // Resolves after ~500ms\n *\n * // Or cancel early:\n * const wait2 = deferAsync(5000);\n * wait2.cancel();\n * ```\n */\nexport function deferAsync(delay) {\n let cancelRef;\n const promise = new Promise((resolve) => {\n // Leverage the core defer function above\n const { cancel } = defer(() => resolve(), delay);\n cancelRef = cancel;\n });\n // Attach the cancel method directly onto the Promise object\n promise.cancel = () => {\n cancelRef();\n };\n return promise;\n}\n","import { isFunction } from \"./is-function\";\nimport { toString } from \"./string\";\n/**\n * Checks whether a value is a `FileList` or a `FileList`-like object.\n * Uses `instanceof FileList` in browser environments and falls back to\n * `Object.prototype.toString` tag detection for isomorphic compatibility.\n *\n * @param data - The value to check.\n * @returns `true` if the value is a `FileList` or has the `[object FileList]` tag.\n *\n * @example\n * ```ts\n * const input = document.querySelector(\"input[type=file]\");\n * isFileList(input.files); // true\n * isFileList([]); // false\n * ```\n */\nexport function isFileList(data) {\n return ((typeof FileList !== \"undefined\" && data instanceof FileList) ||\n (typeof data === \"object\" &&\n data !== null &&\n toString(data) === \"[object FileList]\" &&\n \"length\" in data &&\n \"item\" in data &&\n isFunction(data.item)));\n}\n","/** RFC 2045 MIME type pattern: `type/subtype` with optional `;parameter=value`. */\nexport const MIME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_.+]*\\/[a-zA-Z0-9][a-zA-Z0-9!#$&\\-^_.+]*(;\\s*[\\w.-]+=[\\w.-]+)*$/;\n/**\n * Validate and sanitize a MIME type string.\n *\n * Returns the input unchanged if valid, empty string if malformed.\n * This prevents attackers from smuggling values like `application/php/jpeg`\n * through to the upstream API — the empty Content-Type lets the API\n * server reject the payload on its own terms instead of crashing ours.\n */\nexport function sanitizeMime(value) {\n return MIME_REGEX.test(value) ? value : \"\";\n}\n","/**\n * Default character transformer map for common non-ASCII characters.\n * Can be extended or overridden via {@link SlugifyOptions.transformer}.\n */\nexport const DEFAULT_TRANSFORMER = {\n đ: \"d\",\n æ: \"ae\",\n ø: \"o\",\n å: \"a\",\n œ: \"oe\",\n ß: \"ss\",\n þ: \"th\",\n ð: \"d\",\n};\n/**\n * Converts a string into a URL-friendly slug.\n * Handles Unicode normalization, custom character transformations,\n * and separator deduplication.\n *\n * @param str - The input string to slugify.\n * @param options - Configuration options.\n * @returns A lowercase, URL-safe slug string.\n *\n * @example\n * ```ts\n * slugify(\"Hello World\"); // \"hello-world\"\n * slugify(\"Xin Chào Đất Nước\"); // \"xin-chao-dat-nuoc\" (Vietnamese)\n * slugify(\"Straße nach München\"); // \"strasse-nach-munchen\" (German)\n * slugify(\"Ærlig talt, det er sjovt\"); // \"aerlig-talt-det-er-sjovt\" (Danish)\n * slugify(\"C'est la crème brûlée\"); // \"cest-la-creme-brulee\" (French)\n * slugify(\"Foo Bar\", { separator: \"_\" }); // \"foo_bar\"\n * ```\n */\nexport function slugify(str, options = {}) {\n const { separator = \"-\", silent = false } = options;\n if (!str) {\n return \"\";\n }\n str = str.toLowerCase();\n // 1. Merge default transformer with user overrides (user takes precedence)\n const transformer = Object.assign(Object.assign({}, DEFAULT_TRANSFORMER), options.transformer);\n const keys = Object.keys(transformer);\n if (keys.length > 0) {\n // Sort keys by length (descending) so longer matches take priority\n keys.sort((a, b) => b.length - a.length);\n const escapedKeys = keys.map((k) => k.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\"));\n const regex = new RegExp(escapedKeys.join(\"|\"), \"g\");\n str = str.replace(regex, (match) => {\n const replaceValue = transformer[match];\n // Silent mode: discard replacements longer than 1 character\n if (silent && replaceValue.length > 1) {\n return \"\";\n }\n return replaceValue;\n });\n }\n // 2. Decompose Unicode (NFD) and strip diacritics + special characters\n str = str\n .normalize(\"NFD\")\n .replace(/[\\u0300-\\u036f]/g, \"\")\n .replace(/[^\\w]|_|-/g, separator);\n // 3. Clean up separator duplicates and trim edges\n if (!separator) {\n return str.trim();\n }\n const escapedSeparator = separator.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return str\n .replace(new RegExp(`${escapedSeparator}+`, \"g\"), separator)\n .replace(new RegExp(`^${escapedSeparator}|${escapedSeparator}$`, \"g\"), \"\")\n .trim();\n}\n","import { DEFAULT_TRANSFORMER, slugify } from \"./slugify\";\n/** Slugify options tuned for search: no separator, silent multi-char replacements. */\nconst HIGHLIGHT_SEARCH_OPTIONS = {\n separator: \"\",\n silent: true,\n transformer: Object.assign({}, DEFAULT_TRANSFORMER),\n};\n/**\n * Performs a diacritic-insensitive fuzzy search by comparing slugified characters.\n * Returns all matching substrings and their positions in the original string.\n *\n * Uses a **sliding window** algorithm with per-character slugification cache\n * for optimal performance on repeated characters.\n *\n * @param original - The original string to search within.\n * @param searchStr - The search term (will be slugified for comparison).\n * @returns A {@link SearchResult} with matched substrings and their positions.\n *\n * @example\n * ```ts\n * searchify(\"Xin Chào Việt Nam\", \"viet\");\n * // { matches: [\"Việt\"], positions: [{ start: 9, length: 4 }] }\n *\n * searchify(\"Crème Brûlée\", \"brulee\");\n * // { matches: [\"Brûlée\"], positions: [{ start: 6, length: 6 }] }\n * ```\n */\nexport function searchify(original, searchStr) {\n const slugified = slugify(searchStr, HIGHLIGHT_SEARCH_OPTIONS);\n const searchLength = slugified.length;\n const result = { matches: [], positions: [] };\n if (!searchLength) {\n return result;\n }\n const charCache = new Map();\n // Pre-process: map each original character to its slugified form (cached)\n const originalChars = [...original.split(\"\")].map((char, index) => {\n let slug = charCache.get(char);\n if (slug === undefined) {\n slug = slugify(char, HIGHLIGHT_SEARCH_OPTIONS);\n charCache.set(char, slug);\n }\n return {\n originIndex: index,\n slugified: slug,\n char,\n };\n });\n // Filter consecutive whitespace for performance\n const originalFiltered = originalChars.filter((obj, index, chars) => {\n if (index === 0)\n return true;\n if (obj.char === \" \" && chars[index - 1].char === \" \")\n return false;\n return true;\n });\n if (originalFiltered.length < searchLength) {\n return result;\n }\n // Core algorithm: sliding window match\n for (let i = 0; i < originalFiltered.length;) {\n const firstChar = originalFiltered[i];\n if (firstChar.slugified === \"\") {\n i++;\n continue;\n }\n let currentSlugified = \"\";\n let endPosition = i;\n let isMatch = true;\n while (currentSlugified.length < searchLength && endPosition < originalFiltered.length) {\n const currentChar = originalFiltered[endPosition];\n if (currentChar.slugified !== \"\") {\n currentSlugified += currentChar.slugified;\n if (!slugified.startsWith(currentSlugified)) {\n isMatch = false;\n break;\n }\n }\n endPosition++;\n }\n if (isMatch && currentSlugified === slugified) {\n const lastChar = originalFiltered[endPosition - 1];\n const matchText = original.substring(firstChar.originIndex, lastChar.originIndex + 1);\n result.matches.push(matchText);\n result.positions.push({\n start: firstChar.originIndex,\n length: matchText.length,\n });\n i = endPosition;\n }\n else {\n i++;\n }\n }\n return result;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Recursively flattens a nested object or array into a single-level object\n * with dot-separated keys.\n *\n * Array indices use dot notation (`users.0.name` instead of `users[0].name`).\n *\n * @param data - The value to flatten.\n * @param prefix - Internal prefix for recursive key building.\n * @param acc - Internal accumulator for the result.\n * @returns A flat `Record<string, unknown>` with dot-separated keys.\n *\n * @example\n * ```ts\n * flatten({ users: [{ name: \"Alice\" }] });\n * // { \"users.0.name\": \"Alice\" }\n *\n * flatten({ a: { b: { c: 1 } } });\n * // { \"a.b.c\": 1 }\n * ```\n */\nexport function flatten(data, prefix = \"\", acc = {}) {\n if (typeof data !== \"object\" || data === null) {\n if (prefix)\n acc[prefix] = data;\n return acc;\n }\n if (Array.isArray(data)) {\n for (let i = 0; i < data.length; i++) {\n const newPrefix = prefix ? `${prefix}.${i}` : `${i}`;\n flatten(data[i], newPrefix, acc);\n }\n }\n else {\n for (const [key, value] of Object.entries(data)) {\n const newPrefix = prefix ? `${prefix}.${key}` : key;\n flatten(value, newPrefix, acc);\n }\n }\n return acc;\n}\n/**\n * Extracts entries from a flattened object under a given path and reconstructs\n * them as an array of objects (if the keys are numeric indices) or a list of\n * `{ key, value }` pairs (if the keys are non-numeric).\n *\n * @param data - A flattened `Record<string, unknown>` (output of {@link flatten}).\n * @param path - The dot-separated path prefix to extract.\n * @returns An array of reconstructed objects, primitive values, or `{ key, value }` pairs.\n *\n * @example\n * ```ts\n * const flat = flatten({ users: [{ name: \"Alice\" }, { name: \"Bob\" }] });\n * flattenToArray(flat, \"users\");\n * // [{ name: \"Alice\" }, { name: \"Bob\" }]\n *\n * const flat2 = flatten({ config: { host: \"localhost\", port: 3000 } });\n * flattenToArray(flat2, \"config\");\n * // [{ key: \"host\", value: \"localhost\" }, { key: \"port\", value: 3000 }]\n * ```\n */\nexport function flattenToArray(data, path) {\n const prefix = `${path}.`;\n const dataOfPath = Object.entries(data).filter(([key]) => key.startsWith(prefix));\n if (!dataOfPath.length)\n return [];\n // Get the first key, strip the prefix. e.g. \"0.name\"\n const firstKeyRemain = dataOfPath[0][0].replace(prefix, \"\");\n // Determine if it's an array by checking whether the first node is a numeric index\n const firstNode = firstKeyRemain.split(\".\")[0];\n const isArrayType = !isNaN(Number(firstNode));\n // Return as { key, value } list if not an array\n if (!isArrayType) {\n return dataOfPath.map(([key, value]) => ({\n key: key.replace(prefix, \"\"),\n value,\n }));\n }\n // Reconstruct array from \"0.name\" format\n const resultObj = dataOfPath.reduce((acc, [key, value]) => {\n const cleanedKey = key.replace(prefix, \"\"); // \"0.contact.email\"\n const parts = cleanedKey.split(\".\");\n const index = parts[0]; // \"0\"\n const remain = parts.slice(1).join(\".\"); // \"contact.email\"\n if (!acc[index])\n acc[index] = {};\n if (remain) {\n acc[index][remain] = value;\n }\n else {\n acc[index] = value; // Handle primitive arrays\n }\n return acc;\n }, {});\n return Object.values(resultObj);\n}\n/**\n * Escapes special regex characters in a key string so it can be safely\n * used inside a `RegExp` constructor.\n *\n * @param key - The string to escape.\n * @returns The escaped string with special characters prefixed by `\\\\`.\n *\n * @example\n * ```ts\n * escapeRegexKey(\"users[0].name\"); // \"users\\\\[0\\\\]\\\\.name\"\n * ```\n */\nexport function escapeRegexKey(key) {\n return key.replace(/([.[\\]{}])/g, \"\\\\$1\");\n}\n","import { isFileList } from \"./filelist\";\n/** Type guard that checks whether a value is a `FormData` instance. */\nexport function isFormData(body) {\n return body instanceof FormData;\n}\n/**\n * Recursively converts a value into a `FormData` instance.\n * Handles Date, File, Blob, FileList, arrays, nested objects, and primitives.\n *\n * @param data - The value to convert.\n * @param formData - The `FormData` instance to append to (created automatically if omitted).\n * @param parentKey - Internal key prefix for recursive nesting.\n * @returns The populated `FormData` instance.\n *\n * @example\n * ```ts\n * const fd = objectToFormData({\n * name: \"Alice\",\n * avatar: someFile,\n * tags: [\"a\", \"b\"],\n * meta: { role: \"admin\" },\n * });\n * // FormData entries:\n * // name → \"Alice\"\n * // avatar → File\n * // tags[0] → \"a\"\n * // tags[1] → \"b\"\n * // meta[role] → \"admin\"\n * ```\n */\nexport function objectToFormData(data, formData = new FormData(), parentKey = \"\") {\n // Skip null or undefined values\n if (data === null || data === undefined) {\n return formData;\n }\n // 1. Handle Date\n if (data instanceof Date) {\n formData.append(parentKey, data.toISOString());\n }\n // 2. Handle single File or Blob\n else if (data instanceof File || data instanceof Blob) {\n formData.append(parentKey, data);\n }\n // 3. Handle FileList (isomorphic-safe for Node.js)\n else if (isFileList(data)) {\n Array.from(data).forEach((file, index) => {\n // Backend typically expects array files as: files[0], files[1]\n const arrayKey = parentKey ? `${parentKey}[${index}]` : String(index);\n formData.append(arrayKey, file, file.name);\n });\n }\n // 4. Handle regular arrays\n else if (Array.isArray(data)) {\n data.forEach((item, index) => {\n const arrayKey = parentKey ? `${parentKey}[${index}]` : String(index);\n objectToFormData(item, formData, arrayKey);\n });\n }\n // 5. Handle nested objects\n else if (typeof data === \"object\") {\n Object.entries(data).forEach(([key, value]) => {\n const propKey = parentKey ? `${parentKey}[${key}]` : key;\n objectToFormData(value, formData, propKey);\n });\n }\n // 6. Handle primitives (string, number, boolean)\n else {\n formData.append(parentKey, String(data));\n }\n return formData;\n}\n"],"names":["get","data","path","defaultValue","keys","Array","isArray","replace","split","filter","Boolean","length","result","key","undefined","interpolate","pattern","params","trim","includes","match","variable","value","String","toString","Object","prototype","call","ucfirst","str","charAt","toUpperCase","slice","isFunction","isObject","isLiteralObject","proto","getPrototypeOf","isObjectable","hasOwnProperty","obj","cloneStrateries","Date","getTime","RegExp","source","flags","Map","cache","set","forEach","val","clone","Set","add","ArrayBuffer","Strateries","NumberTypedArray","Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array","DataView","DoNotClone","from","Error","Promise","Blob","WeakMap","WeakSet","Symbol","Window","File","FormData","Headers","Request","Response","Worker","AbortController","Node","FileList","isConstructor","constructor","targets","_a","has","itemData","ItemClass","buffer","byteOffset","byteLength","ItemConstructor","handleName","handler","create","Reflect","ownKeys","descriptor","getOwnPropertyDescriptor","defineProperty","deepFreezeInternal","propNames","name","freeze","cloneDeep","Primitive","isString","isNumber","Number","isFinite","isBoolean","isPrimitive","isDate","isNaN","isPlainObject","normalize","prim","toISOString","map","item","toJSON","Json","stringify","space","normalized","JSON","_b","parse","text","reviver","Url","encode","component","encodeURIComponent","encodeURI","sanitized","decode","decoder","decodeURIComponent","decodeURI","build","uri","fullMatch","queryString","query","cleanQuery","startsWith","part","options","arrayFormat","arrayFormatSeparator","skipNull","skipEmptyString","strict","sort","isValidKey","k","test","encoder","resultPairs","traverse","prefix","validVals","v","push","join","idx","arrayKey","subKey","Serialize","isEqualArrayBuffer","value1","value2","buffer1","isView","offset1","buffer2","offset2","view1","view2","i","URL","isEqualStrategies","is","size","isEqual","item1","hasMatch","item2","keys1","keys2","merge","target","assign","sourceValue","targetValue","SubscribeListener","SubscribeListeners","defaultEvents","state","change","defer","callback","delay","ids","r","s","timeout","Math","max","cancel","cancelAnimationFrame","clearTimeout","requestAnimationFrame","setTimeout","isFileList","MIME_REGEX","DEFAULT_TRANSFORMER","slugify","separator","silent","toLowerCase","transformer","a","b","escapedKeys","regex","replaceValue","escapedSeparator","HIGHLIGHT_SEARCH_OPTIONS","shallow","this","_shallow","initialState","events","_state","listeners","_events","subscribe","channel","delete","dispatch","payload","getState","setState","nextState","onStateChange","subscribeAsyncOnce","signal","unsub","onAbort","resolve","reject","aborted","addEventListener","once","removeEventListener","wire","$instance","domains","methods","reduce","acc","domain","channelName","listener","writable","enumerable","configurable","cancelRef","promise","flatten","newPrefix","entries","dataOfPath","firstNode","resultObj","parts","index","remain","values","body","objectToFormData","formData","parentKey","append","file","original","searchStr","slugified","searchLength","matches","positions","charCache","originalFiltered","char","slug","originIndex","chars","firstChar","currentSlugified","endPosition","isMatch","currentChar","lastChar","matchText","substring","start"],"mappings":"gPAqBO,SAASA,EAAIC,EAAMC,EAAMC,GAE5B,GAAIF,QACA,OAAOE,EAIX,MAAMC,EAAOC,MAAMC,QAAQJ,GACrBA,EACAA,EACGK,QAAQ,YAAa,OACrBC,MAAM,KACNC,OAAOC,SAChB,GAAoB,IAAhBN,EAAKO,OACL,OAAOV,EAGX,IAAIW,EAASX,EACb,IAAK,MAAMY,KAAOT,EAAM,CAEpB,GAAIQ,QACA,OAAOT,EAEXS,EAASA,EAAOC,EACpB,CAEA,YAAkBC,IAAXF,EAAuBT,EAAeS,CACjD,CCvCO,SAASG,EAAYC,EAASC,EAAS,IAE1C,OAAKD,GACkB,iBAAZA,GACNA,EAAQE,OAAOP,QACfK,EAAQG,SAAS,MACjBH,EAAQG,SAAS,KAIfH,EAAQT,QAAQ,yBAA0B,CAACa,EAAOC,KACrD,MAAMC,EAAQtB,EAAIiB,EAAQI,GAE1B,OAAIC,SAIiB,iBAAVA,EAHA,GAMJC,OAAOD,KAbPN,CAef,CCtBO,SAASQ,EAASF,GACrB,OAAOG,OAAOC,UAAUF,SAASG,KAAKL,EAC1C,CASO,SAASM,EAAQC,GACpB,OAAQA,EAAIC,OAAO,GAAGC,cAAgBF,EAAIG,MAAM,EACpD,CCRO,SAASC,EAAWX,GACvB,MAAyB,mBAAVA,GACX,CAAC,oBAAqB,yBAA0B,8BAA8BH,SAASK,EAASF,GACxG,CCVO,SAASY,EAASZ,GACrB,MAAwB,iBAAVA,GAAgC,OAAVA,CACxC,CAOO,SAASa,EAAgBb,GAC5B,IAAKY,EAASZ,IAAUjB,MAAMC,QAAQgB,GAClC,OAAO,EAEX,MAAMc,EAAQX,OAAOY,eAAef,GACpC,OAAiB,OAAVc,GAAkBA,IAAUX,OAAOC,SAC9C,CAgBO,SAASY,EAAahB,GACzB,OAAOY,EAASZ,IAAUW,EAAWX,EACzC,CAcO,SAASiB,EAAeC,EAAK3B,GAChC,QAAK2B,IAGAF,EAAaE,GAGVf,OAAOC,UAAUa,eAAeZ,KAAKa,EAAK3B,IAAQA,KAAO2B,EAFtDf,OAAOC,UAAUa,eAAeZ,KAAKa,EAAK3B,GAGzD,CC5DA,MAAM4B,EAAkB,CACpB,CAACC,KAAKlB,YAAcvB,GAAS,IAAIyC,KAAKzC,EAAK0C,WAC3C,CAACC,OAAOpB,YAAcvB,GAAS,IAAI2C,OAAO3C,EAAK4C,OAAQ5C,EAAK6C,OAC5D,CAACC,IAAIvB,YAAa,CAACvB,EAAM+C,KACrB,MAAMpC,EAAS,IAAImC,IAKnB,OAJAC,EAAMC,IAAIhD,EAAMW,GAChBX,EAAKiD,QAAQ,CAACC,EAAKtC,KACfD,EAAOqC,IAAIG,EAAMvC,EAAKmC,GAAQI,EAAMD,EAAKH,MAEtCpC,GAEX,CAACyC,IAAI7B,YAAa,CAACvB,EAAM+C,KACrB,MAAMpC,EAAS,IAAIyC,IAKnB,OAJAL,EAAMC,IAAIhD,EAAMW,GAChBX,EAAKiD,QAASC,IACVvC,EAAO0C,IAAIF,EAAMD,EAAKH,MAEnBpC,GAEX,CAAC2C,YAAY/B,YAAcvB,GAChBA,EAAK+B,MAAM,IAGpBwB,EAAa,CAACd,KAAME,OAAQG,IAAKM,IAAKE,aACtCE,EAAmB,CACrBC,UACAC,WACAC,kBACAC,WACAC,YACAC,WACAC,YACAC,aACAC,aACAC,cACAC,eACAC,UAEEC,EACKjE,MAAMkE,KAAK,IAAIlB,IAAI,CAEtBmB,MACAC,QACAC,KAEmB,oBAAZC,SAA2BA,QACf,oBAAZC,SAA2BA,QAChB,oBAAXC,QAA0BA,OACf,oBAAXC,QAA0BA,OACjB,oBAATC,MAAwBA,KACX,oBAAbC,UAA4BA,SAChB,oBAAZC,SAA2BA,QACf,oBAAZC,SAA2BA,QACd,oBAAbC,UAA4BA,SACjB,oBAAXC,QAA0BA,OACN,oBAApBC,iBAAmCA,gBAC1B,oBAATC,MAAwBA,KACX,oBAAbC,UAA4BA,YAG3C,SAASC,EAAcC,EAAaC,GAChC,OAAOA,EAAQvE,SAASsE,EAC5B,CAkBO,SAASrC,EAAMnD,EAAM+C,EAAQ,IAAI2B,SACpC,IAAIgB,EACJ,IAAKrD,EAAarC,IACdgC,EAAWhC,IACXsC,EAAetC,EAAM,aACpBA,EAAKwF,aAAeD,EAAcvF,EAAKwF,YAAanB,GACrD,OAAOrE,EAGX,GAAI+C,EAAM4C,IAAI3F,GACV,OAAO+C,EAAMhD,IAAIC,GAErB,GAAIA,EAAKwF,aAAeD,EAAcvF,EAAKwF,YAAahC,GAAmB,CACvE,MAAMoC,EAAW5F,EAEXW,EAAS,IAAIkF,EADD7F,EAAKwF,aACMI,EAASE,OAAO/D,MAAM,GAAI6D,EAASG,WAAYH,EAASI,YAErF,OADAjD,EAAMC,IAAIhD,EAAMW,GACTA,CACX,CACA,MAAMsF,EAAkBjG,EAAKwF,YAC7B,GAAIjC,EAAWrC,SAAS+E,GAAkB,CACtC,MAAMC,EAAaD,EAAgB1E,WAE7BZ,GAASwF,EADC3D,EAAgB0D,IACTlG,EAAM+C,GAE7B,OADAA,EAAMC,IAAIhD,EAAMW,GACTA,CACX,CAEA,MAAMA,EAASP,MAAMC,QAAQL,GACvB,KAA6C,QAAtC0F,EAAKlE,OAAOY,eAAepC,UAA0B,IAAP0F,OAAgB,EAASA,EAAGF,cAAgBpF,OACjGoB,OAAO4E,OAAO5E,OAAOY,eAAepC,IAC1C+C,EAAMC,IAAIhD,EAAMW,GAChB,MAAMR,EAAOkG,QAAQC,QAAQtG,GAC7B,IAAK,MAAMY,KAAOT,EAAM,CACpB,MAAMoG,EAAa/E,OAAOgF,yBAAyBxG,EAAMY,GACrD2F,IACI,UAAWA,IACXA,EAAWlF,MAAQ8B,EAAMoD,EAAWlF,MAAO0B,IAE/CvB,OAAOiF,eAAe9F,EAAQC,EAAK2F,GAE3C,CACA,OAAO5F,CACX,CC3HA,SAAS+F,EAAmBnE,GACxB,MAAMoE,EAAYN,QAAQC,QAAQ/D,GAClC,IAAK,MAAMqE,KAAQD,EAAW,CAC1B,MAAMtF,EAAQkB,EAAIqE,GACd3E,EAASZ,IACTqF,EAAmBrF,EAE3B,CACA,OAAOG,OAAOqF,OAAOtE,EACzB,CAeO,SAASsE,EAAO7G,EAAM8G,EAAY3D,GACrC,IAAKlB,EAASjC,GACV,OAAOA,EAGX,OAAO0G,EADQI,EAAU9G,GAE7B,CC5BY,MAAC+G,EAAYF,EAAO,CAC5BG,SAAW3F,GACiB,iBAAVA,EAElB4F,SAAS5F,GACmB,iBAAVA,GAAsB6F,OAAOC,SAAS9F,GAExD+F,UAAU/F,GACkB,kBAAVA,EAElBgG,YAAYhG,IACAgB,EAAahB,GAEzBiG,OAAOjG,GACIA,aAAiBoB,OAASyE,OAAOK,MAAMlG,EAAMqB,WAExD8E,cAAetF,EACf,SAAAuF,CAAUzH,GACN,MAAM0H,EAAOX,EACb,GAAIW,EAAKL,YAAYrH,GACjB,MAAoB,iBAATA,EACAA,EAAKuB,WACTvB,EAEX,GAAI0H,EAAKJ,OAAOtH,GACZ,OAAOA,EAAK2H,cAEhB,GAAIvH,MAAMC,QAAQL,GACd,OAAOA,EAAK4H,IAAKC,GAASH,EAAKD,UAAUI,IAG7C,GAAI3F,EAAgBlC,GAAO,CACvB,MAAMW,EAAS,CAAA,EACf,IAAK,MAAMC,KAAOZ,EACd,GAAIsC,EAAetC,EAAMY,GAAM,CAC3B,MAAMsC,EAAMlD,EAAKY,QACLC,IAARqC,IACAvC,EAAOC,GAAO8G,EAAKD,UAAUvE,GAErC,CAEJ,OAAOvC,CACX,CACA,OAAIX,GAAQsC,EAAetC,EAAM,WAAagC,EAAWhC,EAAK8H,QACnD9H,EAAK8H,SAET,CAAA,CACX,IChDSC,EAAOlB,EAAO,CACvBmB,UAAW,CAAC3G,EAAO4G,KACf,IAAIvC,EACJ,IACI,MAAMwC,EAAanB,EAAUU,UAAUpG,GACvC,OAA0D,QAAlDqE,EAAKyC,KAAKH,UAAUE,EAAY,KAAMD,UAAgC,IAAZvC,EAAgBA,EAAK,EAC3F,CACA,MAAO0C,GAEH,MAAO,EACX,GAEJC,MAAO,CAACC,EAAMC,KACV,IAAKD,EACD,OAAO,KAEX,IACI,OAAOH,KAAKE,MAAMC,EAAMC,EAC5B,CACA,MAAO7C,GACH,OAAO,IACX,KCtBK8C,EAAM3B,EAAO,CACtB,MAAA4B,CAAOpH,EAAOqH,GAAY,GACtB,IAAKrH,EACD,MAAO,GACX,GAAyB,mBAAdqH,EACP,OAAOA,EAAUrH,GACrB,IACI,OAAOqH,EAAYC,mBAAmBtH,GAASuH,UAAUvH,EAC7D,CACA,MAAOqE,GAEH,MAAMmD,EAAYxH,EAAMf,QAAQ,mBAAoB,IACpD,OAAOoI,EAAYC,mBAAmBE,GAAaD,UAAUC,EACjE,CACJ,EACAC,OAAQ,CAACzH,EAAOqH,GAAY,KACxB,IAAKrH,EACD,MAAO,GACX,GAAyB,mBAAdqH,EACP,OAAOA,EAAUrH,GACrB,MAAM0H,EAAUL,EAAYM,mBAAqBC,UAEjD,OADmBP,EAAYrH,EAAMf,QAAQ,MAAO,OAASe,GAC3Cf,QAAQ,oBAAsBa,IAC5C,IACI,OAAO4H,EAAQ5H,EACnB,CACA,MAAOuE,GAEH,OAAOvE,CACX,KAGR+H,MAAO,CAACC,EAAKnI,IACJmI,EAEAnI,GAA4B,iBAAXA,EAGfmI,EAAI7I,QAAQ,mBAAoB,CAAC8I,EAAWxI,KAC/C,MAAMS,EAAQL,EAAOJ,GAErB,OAAIS,QACO+H,EAGJZ,EAAIC,OAAOnH,OAAOD,IAAQ,KAT1B8H,EAFA,KChCNE,EAAcxC,EAAO,CAC9B,KAAAwB,CAAMiB,GACF,IAAKA,EACD,MAAO,CAAA,EACX,MAAMC,EAAaD,EAAME,WAAW,KAAOF,EAAMvH,MAAM,GAAKuH,EACtD3I,EAAS,CAAA,EASf,OARA4I,EAAWhJ,MAAM,KAAK0C,QAASwG,IAC3B,IAAKA,EACD,OACJ,MAAO7I,EAAKS,GAASoI,EAAKlJ,MAAM,KAC5BK,IACAD,EAAO6H,EAAIM,OAAOlI,IAAQS,EAAQmH,EAAIM,OAAOzH,GAAS,MAGvDV,CACX,EACA,SAAAqH,CAAUhH,EAAQ0I,EAAU,IACxB,GAAe,OAAX1I,GAAqC,iBAAXA,EAC1B,MAAO,GACX,MAAM2I,YAAEA,EAAc,OAAMC,qBAAEA,EAAuB,IAAGC,SAAEA,GAAW,EAAKC,gBAAEA,GAAkB,EAAKrB,OAAEA,GAAS,EAAIsB,OAAEA,GAAS,EAAIC,KAAEA,GAAO,GAAWN,EAC/IO,EAAcC,GAAMA,EAAExJ,OAAS,GAAK,wBAAwByJ,KAAKD,GAEjEE,EAAWlH,GACRuF,EAEED,EAAIC,OAAOvF,EAAKuF,GADZvF,EAGTmH,EAAc,GAEdC,EAAW,CAACC,EAAQhI,KACtB,GAAInC,MAAMC,QAAQkC,GAAlB,CACI,GAAoB,UAAhBoH,GAA2C,cAAhBA,EAA6B,CACxD,MAAMa,EAAYjI,EAAI/B,OAAQiK,GAAMA,SAAuC,KAANA,GAIrE,YAHID,EAAU9J,OAAS,GACnB2J,EAAYK,KAAK,GAAGN,EAAQG,MAAWH,EAAQI,EAAU5C,IAAItG,QAAQqJ,KAAKf,OAGlF,CACArH,EAAIU,QAAQ,CAACC,EAAK0H,KACd,IAAIC,EAAWN,EACK,YAAhBZ,EACAkB,EAAW,GAAGN,MACO,UAAhBZ,IACLkB,EAAW,GAAGN,KAAUK,MAC5BN,EAASO,EAAU3H,IAG3B,MACA,GAAI6D,EAAUS,cAAcjF,GACxB,IAAK,MAAMuI,KAAUvI,EACbf,OAAOC,UAAUa,eAAeZ,KAAKa,EAAKuI,IAC1CR,EAAS,GAAGC,KAAUO,KAAWvI,EAAIuI,SAM7CvI,QAKQ,KAARA,EAKe,kBAARA,EAIPwE,EAAUO,OAAO/E,GACjB8H,EAAYK,KAAK,GAAGN,EAAQG,MAAWH,EAAQ7H,EAAIoF,kBAGvD0C,EAAYK,KAAK,GAAGN,EAAQG,MAAWH,EAAQ9I,OAAOiB,OAPlD8H,EAAYK,KAAK,GAAGN,EAAQG,MAAWhI,EAAM,OAAS,WALjDuH,GACDO,EAAYK,KAAK,GAAGN,EAAQG,OAN3BV,GACDQ,EAAYK,KAAK,GAAGN,EAAQG,QAmBxC,IAAIpK,EAAOqB,OAAOrB,KAAKa,GACnBgJ,IACA7J,EAAuB,mBAAT6J,EAAsB7J,EAAK6J,KAAKA,GAAQ7J,EAAK6J,QAC/D,IAAK,MAAMpJ,KAAOT,EACV4J,IAAWE,EAAWrJ,IAE1B0J,EAAS1J,EAAKI,EAAOJ,IAEzB,OAAOyJ,EAAYM,KAAK,IAC5B,ICtDG,MAAMI,GCnCb,SAASC,EAAmBC,EAAQC,GAChC,GAAID,EAAOjF,aAAekF,EAAOlF,WAC7B,OAAO,EAEX,MAAMmF,EAAU7H,YAAY8H,OAAOH,GAAUA,EAAOnF,OAASmF,EACvDI,EAAU/H,YAAY8H,OAAOH,GAAUA,EAAOlF,WAAa,EAC3DuF,EAAUhI,YAAY8H,OAAOF,GAAUA,EAAOpF,OAASoF,EACvDK,EAAUjI,YAAY8H,OAAOF,GAAUA,EAAOnF,WAAa,EAC3DyF,EAAQ,IAAI9H,WAAWyH,EAASE,EAASJ,EAAOjF,YAChDyF,EAAQ,IAAI/H,WAAW4H,EAASC,EAASL,EAAOlF,YACtD,IAAK,IAAI0F,EAAI,EAAGA,EAAIF,EAAM9K,OAAQgL,IAC9B,GAAIF,EAAME,KAAOD,EAAMC,GACnB,OAAO,EAGf,OAAO,CACX,CDqBAX,EAAUjK,YAAcA,EAExBiK,EAAUhE,UAAYA,EAEtBgE,EAAU5C,KAAOJ,EAEjBgD,EAAUY,IAAMnD,EAEhBuC,EAAU1B,YAAcA,EC5BxB,MAAMuC,EAAoB,IAAI9I,IAAI,CAC9B,CAACL,KAAM,CAACwI,EAAQC,IAAW1J,OAAOqK,GAAGZ,EAAOvI,UAAWwI,EAAOxI,YAC9D,CACIC,OACA,CAACsI,EAAQC,IAAW1J,OAAOqK,GAAGZ,EAAOrI,OAAQsI,EAAOtI,SAAWpB,OAAOqK,GAAGZ,EAAOpI,MAAOqI,EAAOrI,QAElG,CAACS,YAAa0H,GACd,CACIlI,IACA,CAACmI,EAAQC,KACL,GAAID,EAAOa,OAASZ,EAAOY,KACvB,OAAO,EAEX,IAAK,MAAOlL,EAAKsC,KAAQ+H,EACrB,IAAKC,EAAOvF,IAAI/E,KAASmL,EAAQ7I,EAAKgI,EAAOnL,IAAIa,IAC7C,OAAO,EAGf,OAAO,IAGf,CACIwC,IACA,CAAC6H,EAAQC,KACL,GAAID,EAAOa,OAASZ,EAAOY,KACvB,OAAO,EAEX,IAAK,MAAME,KAASf,EAAQ,CACxB,IAAIgB,GAAW,EACf,IAAK,MAAMC,KAAShB,EAChB,GAAIa,EAAQC,EAAOE,GAAQ,CACvBD,GAAW,EACX,KACJ,CAEJ,IAAKA,EACD,OAAO,CAEf,CACA,OAAO,MAoBZ,SAASF,EAAQd,EAAQC,GAE5B,IAAKjJ,EAASgJ,KAAYhJ,EAASiJ,GAC/B,OAAO1J,OAAOqK,GAAGZ,EAAQC,GAG7B,GAAID,EAAOzF,cAAgB0F,EAAO1F,YAC9B,OAAO,EAEX,GAAIpF,MAAMC,QAAQ4K,GAAS,CACvB,IAAK7K,MAAMC,QAAQ6K,IAAWD,EAAOvK,SAAWwK,EAAOxK,OACnD,OAAO,EAEX,IAAK,IAAIgL,EAAI,EAAGA,EAAIT,EAAOvK,OAAQgL,IAC/B,IAAKK,EAAQd,EAAOS,GAAIR,EAAOQ,IAC3B,OAAO,EAGf,OAAO,CACX,CAEA,GAAIpI,YAAY8H,OAAOH,IAAW3H,YAAY8H,OAAOF,GACjD,OAAOF,EAAmBC,EAAQC,GAEtC,GAAID,EAAOzF,aAAeoG,EAAkBjG,IAAIsF,EAAOzF,aACnD,OAAOoG,EAAkB7L,IAAIkL,EAAOzF,YAA7BoG,CAA0CX,EAAQC,GAE7D,IAAKhJ,EAAgB+I,KAAY/I,EAAgBgJ,GAC7C,OAAOD,IAAWC,EAEtB,MAAMiB,EAAQ3K,OAAOrB,KAAK8K,GACpBmB,EAAQ5K,OAAOrB,KAAK+K,GAC1B,GAAIiB,EAAMzL,SAAW0L,EAAM1L,OACvB,OAAO,EAEX,IAAK,MAAME,KAAOuL,EACd,IAAK7J,EAAe4I,EAAQtK,KACvBmL,EAAQd,EAAOrK,GAAMsK,EAAOtK,IAC7B,OAAO,EAGf,OAAO,CACX,CCnGO,SAASyL,EAAMzJ,EAAQ0J,EAAQxF,EAAY3D,GAC9C,QAAetC,IAAXyL,EACA,OAAOxF,EAAUlE,GAErB,GAAIV,EAAgBU,IAAWV,EAAgBoK,GAAS,CACpD,MAAM3L,EAASa,OAAO+K,OAAO,CAAA,EAAI3J,GAcjC,OAbApB,OAAOrB,KAAKmM,GAAQrJ,QAASrC,IACzB,IA1BZ,SAAoBA,GAChB,MAAe,cAARA,GAA+B,gBAARA,GAAiC,cAARA,CAC3D,CAwBiBqJ,CAAWrJ,GACZ,OAEJ,MAAM4L,EAAc7L,EAAOC,GACrB6L,EAAcH,EAAO1L,GACvBsB,EAAgBsK,IAAgBtK,EAAgBuK,GAChD9L,EAAOC,GAAOyL,EAAMG,EAAaC,EAAa3F,GAG9CnG,EAAOC,GAAOkG,EAAU2F,KAGzB9L,CACX,CACA,OAAOmG,EAAUwF,EACrB,CCrCA,MAAMI,UAA0BtJ,KAEhC,MAAMuJ,UAA2B7J,KAEjC,MAAM8J,EAAgB/F,EAAO,CACzBgG,MAAO,CACHC,OAAQ,mBCGT,SAASC,EAAMC,EAAUC,GAC5B,MAAMC,EAAM,CAAEC,EAAG,KAAMC,EAAG,MACpBC,EAAUC,KAAKC,IAAI,EAAGN,GAAS,GACrC,SAASO,IACLN,EAAIC,GAAqC,mBAAzBM,sBAAuCA,qBAAqBP,EAAIC,GAChFD,EAAIE,GAAKM,aAAaR,EAAIE,GAC1BF,EAAIC,EAAI,KACRD,EAAIE,EAAI,IACZ,CAeA,MAdqC,mBAA1BO,sBACPT,EAAIC,EAAIQ,sBAAsB,KAC1BT,EAAIE,EAAIQ,WAAW,KACfZ,IACAQ,KACDH,KAIPH,EAAIE,EAAIQ,WAAW,KACfZ,IACAQ,KACDH,GAEA,CAAEH,MAAKM,SAClB,CCtBO,SAASK,EAAW7N,GACvB,MAA6B,oBAAbsF,UAA4BtF,aAAgBsF,UACvC,iBAATtF,GACK,OAATA,GACmB,sBAAnBuB,EAASvB,IACT,WAAYA,GACZ,SAAUA,GACVgC,EAAWhC,EAAK6H,KAC5B,CCxBY,MAACiG,EAAa,+FCGd,MAACC,EAAsB,CAC/B,IAAG,IACH,IAAG,KACH,IAAG,IACH,IAAG,IACH,IAAG,KACH,IAAG,KACH,IAAG,KACH,IAAG,KAqBA,SAASC,EAAQpM,EAAK8H,EAAU,IACnC,MAAMuE,UAAEA,EAAY,IAAGC,OAAEA,GAAS,GAAUxE,EAC5C,IAAK9H,EACD,MAAO,GAEXA,EAAMA,EAAIuM,cAEV,MAAMC,EAAc5M,OAAO+K,OAAO/K,OAAO+K,OAAO,CAAA,EAAIwB,GAAsBrE,EAAQ0E,aAC5EjO,EAAOqB,OAAOrB,KAAKiO,GACzB,GAAIjO,EAAKO,OAAS,EAAG,CAEjBP,EAAK6J,KAAK,CAACqE,EAAGC,IAAMA,EAAE5N,OAAS2N,EAAE3N,QACjC,MAAM6N,EAAcpO,EAAKyH,IAAKsC,GAAMA,EAAE5J,QAAQ,sBAAuB,SAC/DkO,EAAQ,IAAI7L,OAAO4L,EAAY5D,KAAK,KAAM,KAChD/I,EAAMA,EAAItB,QAAQkO,EAAQrN,IACtB,MAAMsN,EAAeL,EAAYjN,GAEjC,OAAI+M,GAAUO,EAAa/N,OAAS,EACzB,GAEJ+N,GAEf,CAOA,GALA7M,EAAMA,EACD6F,UAAU,OACVnH,QAAQ,mBAAoB,IAC5BA,QAAQ,aAAc2N,IAEtBA,EACD,OAAOrM,EAAIX,OAEf,MAAMyN,EAAmBT,EAAU3N,QAAQ,sBAAuB,QAClE,OAAOsB,EACFtB,QAAQ,IAAIqC,OAAO,GAAG+L,KAAqB,KAAMT,GACjD3N,QAAQ,IAAIqC,OAAO,IAAI+L,KAAoBA,KAAqB,KAAM,IACtEzN,MACT,CCpEA,MAAM0N,EAA2B,CAC7BV,UAAW,GACXC,QAAQ,EACRE,YAAa5M,OAAO+K,OAAO,CAAA,EAAIwB,6FLiB5B,MACH,WAAIa,GACA,OAAO/H,EAAO,CACVwF,MAAOwC,KAAKC,SAASzC,MACrBlJ,MAAO0L,KAAKC,SAAS3L,MACrB4I,QAAS8C,KAAKC,SAAS/C,SAE/B,CACA,WAAI6C,CAAQA,GACRC,KAAKC,SAAWD,KAAKC,SAASzC,MAAMwC,KAAKC,SAAUF,EACvD,CACA,WAAApJ,CAAYuJ,EAAcC,GACtBH,KAAKI,OAAS,CAAA,EACdJ,KAAKK,UAAY,IAAIvC,EACrBkC,KAAKC,SAAW,CACZzC,QACAlJ,QACA4I,WAEJ8C,KAAKM,QAAUtI,EAAO+F,GACtBiC,KAAKI,OAAUF,QAAmDA,EAAe,GACjFF,KAAKM,QAAUtI,EAAOrF,OAAO+K,OAAO/K,OAAO+K,OAAO,CAAA,EAAIsC,KAAKM,SAAUH,GACzE,CAQA,SAAAI,CAAUC,EAASlJ,GAKf,OAJK0I,KAAKK,UAAUvJ,IAAI0J,IACpBR,KAAKK,UAAUlM,IAAIqM,EAAS,IAAI3C,GAEpCmC,KAAKK,UAAUnP,IAAIsP,GAAShM,IAAI8C,GACzB,KACH,IAAIT,EACmC,QAAtCA,EAAKmJ,KAAKK,UAAUnP,IAAIsP,UAA6B,IAAP3J,GAAyBA,EAAG4J,OAAOnJ,GAE1F,CAOA,QAAAoJ,CAASF,EAASG,GACTX,KAAKK,UAAUvJ,IAAI0J,IAGxBR,KAAKK,UAAUnP,IAAIsP,GAASpM,QAASkD,IAEjCA,UAD2BtF,IAAZ2O,EAAwB,GAAK,CAACA,KAGrD,CAEA,QAAAC,GACI,OAAOZ,KAAKI,MAChB,CAMA,QAAAS,CAAS7C,GACL,MAAM8C,EAAYd,KAAKC,SAASzC,MAAMwC,KAAKI,OAAQpC,GAC9CgC,KAAKC,SAAS/C,QAAQ8C,KAAKI,OAAQU,KACpCd,KAAKI,OAASU,EACdd,KAAKU,SAASV,KAAKM,QAAQtC,MAAMC,OAAQ+B,KAAKC,SAAS3L,MAAMwM,IAErE,CAOA,aAAAC,CAAczJ,GACV,OAAO0I,KAAKO,UAAUP,KAAKM,QAAQtC,MAAMC,OAAQ3G,EACrD,CAcA,wBAAM0J,CAAmBR,EAASlJ,EAAS2J,GACvC,IAAIC,EACAC,EACJ,IACI,aAAa,IAAIxL,QAAQ,CAACyL,EAASC,KAC/B,GAAIJ,aAA4C,EAAIA,EAAOK,QACvD,OAAOD,EAAO,IAAI3L,MAAM,wBAM5BwL,EAAQlB,KAAKO,UAAUC,EAJNG,IACbrJ,SAAkDA,EAAQqJ,GAC1DS,EAAQT,EACX,GAEGM,IACAE,EAAU,IAAME,EAAO,IAAI3L,MAAM,wBACjCuL,EAAOM,iBAAiB,QAASJ,EAAS,CAAEK,MAAM,MAG9D,CACR,QACYN,SAA8CA,IAC1CD,GAAUE,GACVF,EAAOQ,oBAAoB,QAASN,EAE5C,CACJ,CAUA,WAAOO,CAAKC,EAAWxB,GACnB,IAAK,MAAMK,KAAWL,EAAQ,CAC1B,GAAIK,KAAWmB,EACX,MAAM,IAAIjM,MAAM,sBAAsB8K,kBAE1C,MAAMoB,EAAUzB,EAAOK,GACvB,IAAKnN,EAAgBuO,GACjB,SAEJ,MAAMC,EAAUlP,OAAOrB,KAAKsQ,GAASE,OAAO,CAACC,EAAKC,KAC9C,MAAMC,EAAcL,EAAQI,GAK5B,OAJAD,EAAIC,GAAWrB,IACXgB,EAAUjB,SAASuB,EAAatB,IAEpCoB,EAAI,KAAKjP,EAAQkP,MAAcE,GAAaP,EAAUpB,UAAU0B,EAAaC,GACtEH,GACR,CAAA,GACHpP,OAAOiF,eAAe+J,EAAWnB,EAAS,CACtChO,MAAOwF,EAAO6J,GACdM,UAAU,EACVC,YAAY,EACZC,cAAc,GAEtB,CACA,OAAOV,CACX,4CCtHG,SAAoBvD,GACvB,IAAIkE,EACJ,MAAMC,EAAU,IAAI5M,QAASyL,IAEzB,MAAMzC,OAAEA,GAAWT,EAAM,IAAMkD,IAAWhD,GAC1CkE,EAAY3D,IAMhB,OAHA4D,EAAQ5D,OAAS,KACb2D,KAEGC,CACX,mBKuCO,SAAwBxQ,GAC3B,OAAOA,EAAIN,QAAQ,cAAe,OACtC,YAzFO,SAAS+Q,EAAQrR,EAAMuK,EAAS,GAAIqG,EAAM,CAAA,GAC7C,GAAoB,iBAAT5Q,GAA8B,OAATA,EAG5B,OAFIuK,IACAqG,EAAIrG,GAAUvK,GACX4Q,EAEX,GAAIxQ,MAAMC,QAAQL,GACd,IAAK,IAAI0L,EAAI,EAAGA,EAAI1L,EAAKU,OAAQgL,IAAK,CAClC,MAAM4F,EAAY/G,EAAS,GAAGA,KAAUmB,IAAM,GAAGA,IACjD2F,EAAQrR,EAAK0L,GAAI4F,EAAWV,EAChC,MAGA,IAAK,MAAOhQ,EAAKS,KAAUG,OAAO+P,QAAQvR,GAAO,CAE7CqR,EAAQhQ,EADUkJ,EAAS,GAAGA,KAAU3J,IAAQA,EACtBgQ,EAC9B,CAEJ,OAAOA,CACX,mBAqBO,SAAwB5Q,EAAMC,GACjC,MAAMsK,EAAS,GAAGtK,KACZuR,EAAahQ,OAAO+P,QAAQvR,GAAMQ,OAAO,EAAEI,KAASA,EAAI4I,WAAWe,IACzE,IAAKiH,EAAW9Q,OACZ,MAAO,GAEX,MAEM+Q,EAFiBD,EAAW,GAAG,GAAGlR,QAAQiK,EAAQ,IAEvBhK,MAAM,KAAK,GAG5C,KAFqBgH,MAAML,OAAOuK,IAG9B,OAAOD,EAAW5J,IAAI,EAAEhH,EAAKS,MAAM,CAC/BT,IAAKA,EAAIN,QAAQiK,EAAQ,IACzBlJ,WAIR,MAAMqQ,EAAYF,EAAWb,OAAO,CAACC,GAAMhQ,EAAKS,MAC5C,MACMsQ,EADa/Q,EAAIN,QAAQiK,EAAQ,IACdhK,MAAM,KACzBqR,EAAQD,EAAM,GACdE,EAASF,EAAM5P,MAAM,GAAG4I,KAAK,KASnC,OARKiG,EAAIgB,KACLhB,EAAIgB,GAAS,CAAA,GACbC,EACAjB,EAAIgB,GAAOC,GAAUxQ,EAGrBuP,EAAIgB,GAASvQ,EAEVuP,GACR,CAAA,GACH,OAAOpP,OAAOsQ,OAAOJ,EACzB,0EhBlEO,SAAyBrQ,GAC5B,OAAOY,EAASZ,KAAWjB,MAAMC,QAAQgB,EAC7C,0CiB7BO,SAAoB0Q,GACvB,OAAOA,aAAgBhN,QAC3B,gGA0BO,SAASiN,EAAiBhS,EAAMiS,EAAW,IAAIlN,SAAYmN,EAAY,IAE1E,OAAIlS,UAIAA,aAAgByC,KAChBwP,EAASE,OAAOD,EAAWlS,EAAK2H,eAG3B3H,aAAgB8E,MAAQ9E,aAAgByE,KAC7CwN,EAASE,OAAOD,EAAWlS,GAGtB6N,EAAW7N,GAChBI,MAAMkE,KAAKtE,GAAMiD,QAAQ,CAACmP,EAAMR,KAE5B,MAAM/G,EAAWqH,EAAY,GAAGA,KAAaN,KAAWtQ,OAAOsQ,GAC/DK,EAASE,OAAOtH,EAAUuH,EAAMA,EAAKxL,QAIpCxG,MAAMC,QAAQL,GACnBA,EAAKiD,QAAQ,CAAC4E,EAAM+J,KAChB,MAAM/G,EAAWqH,EAAY,GAAGA,KAAaN,KAAWtQ,OAAOsQ,GAC/DI,EAAiBnK,EAAMoK,EAAUpH,KAIhB,iBAAT7K,EACZwB,OAAO+P,QAAQvR,GAAMiD,QAAQ,EAAErC,EAAKS,MAEhC2Q,EAAiB3Q,EAAO4Q,EADRC,EAAY,GAAGA,KAAatR,KAASA,KAMzDqR,EAASE,OAAOD,EAAW5Q,OAAOtB,KAlC3BiS,CAqCf,kBnBpCO,SAAuBrQ,GAC1B,OAAKA,EAEEA,EACFtB,QAAQ,qBAAsB,SAC9BA,QAAQ,uBAAwB,SAChC6N,cAJMvM,CAKf,iCe/BO,SAAsBP,GACzB,OAAOyM,EAAW3D,KAAK9I,GAASA,EAAQ,EAC5C,cEeO,SAAmBgR,EAAUC,GAChC,MAAMC,EAAYvE,EAAQsE,EAAW3D,GAC/B6D,EAAeD,EAAU7R,OACzBC,EAAS,CAAE8R,QAAS,GAAIC,UAAW,IACzC,IAAKF,EACD,OAAO7R,EAEX,MAAMgS,EAAY,IAAI7P,IAehB8P,EAbgB,IAAIP,EAAS9R,MAAM,KAAKqH,IAAI,CAACiL,EAAMjB,KACrD,IAAIkB,EAAOH,EAAU5S,IAAI8S,GAKzB,YAJahS,IAATiS,IACAA,EAAO9E,EAAQ6E,EAAMlE,GACrBgE,EAAU3P,IAAI6P,EAAMC,IAEjB,CACHC,YAAanB,EACbW,UAAWO,EACXD,UAI+BrS,OAAO,CAAC+B,EAAKqP,EAAOoB,IACzC,IAAVpB,IAEa,MAAbrP,EAAIsQ,MAA0C,MAA1BG,EAAMpB,EAAQ,GAAGiB,OAI7C,GAAID,EAAiBlS,OAAS8R,EAC1B,OAAO7R,EAGX,IAAK,IAAI+K,EAAI,EAAGA,EAAIkH,EAAiBlS,QAAS,CAC1C,MAAMuS,EAAYL,EAAiBlH,GACnC,GAA4B,KAAxBuH,EAAUV,UAAkB,CAC5B7G,IACA,QACJ,CACA,IAAIwH,EAAmB,GACnBC,EAAczH,EACd0H,GAAU,EACd,KAAOF,EAAiBxS,OAAS8R,GAAgBW,EAAcP,EAAiBlS,QAAQ,CACpF,MAAM2S,EAAcT,EAAiBO,GACrC,GAA8B,KAA1BE,EAAYd,YACZW,GAAoBG,EAAYd,WAC3BA,EAAU/I,WAAW0J,IAAmB,CACzCE,GAAU,EACV,KACJ,CAEJD,GACJ,CACA,GAAIC,GAAWF,IAAqBX,EAAW,CAC3C,MAAMe,EAAWV,EAAiBO,EAAc,GAC1CI,EAAYlB,EAASmB,UAAUP,EAAUF,YAAaO,EAASP,YAAc,GACnFpS,EAAO8R,QAAQ/H,KAAK6I,GACpB5S,EAAO+R,UAAUhI,KAAK,CAClB+I,MAAOR,EAAUF,YACjBrS,OAAQ6S,EAAU7S,SAEtBgL,EAAIyH,CACR,MAEIzH,GAER,CACA,OAAO/K,CACX"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
export * from "./env";
|
|
2
|
-
export * from "./http";
|
|
3
|
-
export * from "./logger";
|
|
4
|
-
export * from "./searchify";
|
|
5
1
|
export * from "./serialize";
|
|
6
|
-
export * from "./slugify";
|
|
7
2
|
export * from "./subscriber";
|
|
8
3
|
export * from "./utilities";
|
|
9
|
-
export type * from "./http";
|
|
10
|
-
export type * from "./logger";
|
|
11
|
-
export type * from "./searchify";
|
|
12
4
|
export type * from "./serialize";
|
|
13
|
-
export type * from "./slugify";
|
|
14
5
|
export type * from "./subscriber";
|
|
15
6
|
export type * from "./utilities";
|
|
16
7
|
export type * from "./types";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("./
|
|
1
|
+
"use strict";var e=require("./serialize/index.js"),i=require("./subscriber.js"),r=require("./utilities/clone.js"),s=require("./utilities/defer.js"),t=require("./utilities/filelist.js"),o=require("./utilities/flatten.js"),u=require("./utilities/freeze.js"),l=require("./utilities/get.js"),a=require("./utilities/is-equal.js"),p=require("./utilities/is-function.js"),x=require("./utilities/object.js"),j=require("./utilities/merge.js"),n=require("./utilities/formdata.js"),c=require("./utilities/sanitize-mime.js"),q=require("./utilities/searchify.js"),f=require("./utilities/slugify.js"),b=require("./utilities/string.js"),g=require("./serialize/json.js"),m=require("./serialize/primitive.js"),y=require("./serialize/url.js"),z=require("./serialize/interpolate.js"),E=require("./serialize/query-string.js");exports.Serialize=e.Serialize,exports.Subscriber=i.Subscriber,exports.clone=r.clone,exports.defer=s.defer,exports.deferAsync=s.deferAsync,exports.isFileList=t.isFileList,exports.escapeRegexKey=o.escapeRegexKey,exports.flatten=o.flatten,exports.flattenToArray=o.flattenToArray,exports.freeze=u.freeze,exports.get=l.get,exports.isEqual=a.isEqual,exports.isFunction=p.isFunction,exports.hasOwnProperty=x.hasOwnProperty,exports.isComplexObject=x.isComplexObject,exports.isLiteralObject=x.isLiteralObject,exports.isObject=x.isObject,exports.isObjectable=x.isObjectable,exports.merge=j.merge,exports.isFormData=n.isFormData,exports.objectToFormData=n.objectToFormData,exports.MIME_REGEX=c.MIME_REGEX,exports.sanitizeMime=c.sanitizeMime,exports.searchify=q.searchify,exports.DEFAULT_TRANSFORMER=f.DEFAULT_TRANSFORMER,exports.slugify=f.slugify,exports.pascalToKebab=b.pascalToKebab,exports.toString=b.toString,exports.ucfirst=b.ucfirst,exports.Json=g.Json,exports.Primitive=m.Primitive,exports.Url=y.Url,exports.interpolate=z.interpolate,exports.queryString=E.queryString;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{
|
|
1
|
+
export{Serialize}from"./serialize/index.mjs";export{Subscriber}from"./subscriber.mjs";export{clone}from"./utilities/clone.mjs";export{defer,deferAsync}from"./utilities/defer.mjs";export{isFileList}from"./utilities/filelist.mjs";export{escapeRegexKey,flatten,flattenToArray}from"./utilities/flatten.mjs";export{freeze}from"./utilities/freeze.mjs";export{get}from"./utilities/get.mjs";export{isEqual}from"./utilities/is-equal.mjs";export{isFunction}from"./utilities/is-function.mjs";export{hasOwnProperty,isComplexObject,isLiteralObject,isObject,isObjectable}from"./utilities/object.mjs";export{merge}from"./utilities/merge.mjs";export{isFormData,objectToFormData}from"./utilities/formdata.mjs";export{MIME_REGEX,sanitizeMime}from"./utilities/sanitize-mime.mjs";export{searchify}from"./utilities/searchify.mjs";export{DEFAULT_TRANSFORMER,slugify}from"./utilities/slugify.mjs";export{pascalToKebab,toString,ucfirst}from"./utilities/string.mjs";export{Json}from"./serialize/json.mjs";export{Primitive}from"./serialize/primitive.mjs";export{Url}from"./serialize/url.mjs";export{interpolate}from"./serialize/interpolate.mjs";export{queryString}from"./serialize/query-string.mjs";
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { interpolate } from "./interpolate";
|
|
2
|
+
export * from "./types";
|
|
3
|
+
export { interpolate } from "./interpolate";
|
|
4
|
+
export { Json } from "./json";
|
|
5
|
+
export { Primitive } from "./primitive";
|
|
6
|
+
export { queryString } from "./query-string";
|
|
7
|
+
export { Url } from "./url";
|
|
8
|
+
/**
|
|
9
|
+
* Centralized serialization engine and type-guard toolkit.
|
|
10
|
+
* Addresses common pitfalls of `JSON.stringify`/`JSON.parse` — BigInt safety,
|
|
11
|
+
* Date preservation, undefined stripping, and safe URL encoding/decoding.
|
|
12
|
+
*
|
|
13
|
+
* This is the convenience surface: it gathers every part under one name.
|
|
14
|
+
* Referencing it keeps all of them, because a class is a single binding and a
|
|
15
|
+
* bundler cannot drop half of one. Code that cares about what it ships should
|
|
16
|
+
* import the part it uses instead — each lives in its own module, so nothing
|
|
17
|
+
* else comes with it:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { Primitive } from "@ecosy/core/serialize/primitive";
|
|
21
|
+
* import { queryString } from "@ecosy/core/serialize/query-string";
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* The two are the same objects, so mixing them is free.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* Serialize.JSON.stringify({ date: new Date(), big: 123n });
|
|
29
|
+
* Serialize.JSON.parse<User>(jsonText);
|
|
30
|
+
* Serialize.URL.encode("hello world");
|
|
31
|
+
* Serialize.queryString.stringify({ page: 1, tags: ["a", "b"] });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class Serialize {
|
|
35
|
+
static readonly interpolate: typeof interpolate;
|
|
36
|
+
/** Type guards and deep normalization utilities. */
|
|
37
|
+
static readonly Primitive: {
|
|
38
|
+
readonly isString: (value: unknown) => value is string;
|
|
39
|
+
readonly isNumber: (value: unknown) => value is number;
|
|
40
|
+
readonly isBoolean: (value: unknown) => value is boolean;
|
|
41
|
+
readonly isPrimitive: (value: unknown) => value is import("./types").PrimitiveValue;
|
|
42
|
+
readonly isDate: (value: unknown) => value is Date;
|
|
43
|
+
readonly isPlainObject: (value: unknown) => value is import("..").LiteralObject;
|
|
44
|
+
readonly normalize: <T, R = unknown>(data: T) => R;
|
|
45
|
+
};
|
|
46
|
+
/** Safe JSON stringify/parse that never throws. */
|
|
47
|
+
static readonly JSON: {
|
|
48
|
+
readonly stringify: (value: unknown, space?: number) => string;
|
|
49
|
+
readonly parse: <T = unknown>(text: string, reviver?: ((this: any, key: string, value: any) => any) | undefined) => T | null;
|
|
50
|
+
};
|
|
51
|
+
/** URL encoding/decoding with malformed-character recovery. */
|
|
52
|
+
static readonly URL: {
|
|
53
|
+
readonly encode: (value: string, component?: boolean | ((value: string) => string)) => string;
|
|
54
|
+
readonly decode: (value: string, component?: boolean | ((value: string) => string)) => string;
|
|
55
|
+
readonly build: (uri: string, params?: Record<string, import("./types").PrimitiveValue> | null) => string;
|
|
56
|
+
};
|
|
57
|
+
/** Query string parse/stringify with configurable array formats. */
|
|
58
|
+
static readonly queryString: {
|
|
59
|
+
readonly parse: (query: string) => Record<string, string>;
|
|
60
|
+
readonly stringify: (params: Record<string, unknown>, options?: import("./types").SerializeQueryOptions) => string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var r=require("./interpolate.js"),e=require("./json.js"),i=require("./primitive.js"),t=require("./query-string.js"),s=require("./url.js");class o{}o.interpolate=r.interpolate,o.Primitive=i.Primitive,o.JSON=e.Json,o.URL=s.Url,o.queryString=t.queryString,exports.interpolate=r.interpolate,exports.Json=e.Json,exports.Primitive=i.Primitive,exports.queryString=t.queryString,exports.Url=s.Url,exports.Serialize=o;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{interpolate as r}from"./interpolate.mjs";import{Json as m}from"./json.mjs";import{Primitive as i}from"./primitive.mjs";import{queryString as o}from"./query-string.mjs";import{Url as t}from"./url.mjs";class e{}e.interpolate=r,e.Primitive=i,e.JSON=m,e.URL=t,e.queryString=o;export{m as Json,i as Primitive,e as Serialize,t as Url,r as interpolate,o as queryString};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interpolates `{key}` placeholders in a string using deep path resolution via {@link get}.
|
|
3
|
+
* Objects are silently replaced with empty strings to avoid `[object Object]`.
|
|
4
|
+
*
|
|
5
|
+
* @param pattern - Template string with `{key}` or `{path.to.key}` placeholders.
|
|
6
|
+
* @param params - Data object or array to resolve values from.
|
|
7
|
+
* @returns The interpolated string.
|
|
8
|
+
*/
|
|
9
|
+
export declare function interpolate(pattern: string, params?: Record<string, unknown> | Array<unknown>): string;
|
|
10
|
+
/** Type guards and deep normalization utilities. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var t=require("../utilities/get.js");exports.interpolate=function(e,r={}){return e&&"string"==typeof e&&e.trim().length&&e.includes("{")&&e.includes("}")?e.replace(/\{([a-zA-Z0-9_.-]+)\}/g,(e,i)=>{const n=t.get(r,i);return null==n||"object"==typeof n?"":String(n)}):e};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{get as t}from"../utilities/get.mjs";function e(e,n={}){return e&&"string"==typeof e&&e.trim().length&&e.includes("{")&&e.includes("}")?e.replace(/\{([a-zA-Z0-9_.-]+)\}/g,(e,r)=>{const i=t(n,r);return null==i||"object"==typeof i?"":String(i)}):e}export{e as interpolate};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var r=require("../utilities/freeze.js"),e=require("./primitive.js");const t=r.freeze({stringify:(r,t)=>{var i;try{const n=e.Primitive.normalize(r);return null!==(i=JSON.stringify(n,null,t))&&void 0!==i?i:""}catch(r){return""}},parse:(r,e)=>{if(!r)return null;try{return JSON.parse(r,e)}catch(r){return null}}});exports.Json=t;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{freeze as r}from"../utilities/freeze.mjs";import{Primitive as t}from"./primitive.mjs";const i=r({stringify:(r,i)=>{var e;try{const n=t.normalize(r);return null!==(e=JSON.stringify(n,null,i))&&void 0!==e?e:""}catch(r){return""}},parse:(r,t)=>{if(!r)return null;try{return JSON.parse(r,t)}catch(r){return null}}});export{i as Json};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var i=require("../utilities/freeze.js"),e=require("../utilities/object.js"),t=require("../utilities/is-function.js");const r=i.freeze({isString:i=>"string"==typeof i,isNumber:i=>"number"==typeof i&&Number.isFinite(i),isBoolean:i=>"boolean"==typeof i,isPrimitive:i=>!e.isObjectable(i),isDate:i=>i instanceof Date&&!Number.isNaN(i.getTime()),isPlainObject:e.isLiteralObject,normalize(i){const s=r;if(s.isPrimitive(i))return"bigint"==typeof i?i.toString():i;if(s.isDate(i))return i.toISOString();if(Array.isArray(i))return i.map(i=>s.normalize(i));if(e.isLiteralObject(i)){const t={};for(const r in i)if(e.hasOwnProperty(i,r)){const e=i[r];void 0!==e&&(t[r]=s.normalize(e))}return t}return i&&e.hasOwnProperty(i,"toJSON")&&t.isFunction(i.toJSON)?i.toJSON():{}}});exports.Primitive=r;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{freeze as i}from"../utilities/freeze.mjs";import{isLiteralObject as t,hasOwnProperty as e,isObjectable as r}from"../utilities/object.mjs";import{isFunction as o}from"../utilities/is-function.mjs";const n=i({isString:i=>"string"==typeof i,isNumber:i=>"number"==typeof i&&Number.isFinite(i),isBoolean:i=>"boolean"==typeof i,isPrimitive:i=>!r(i),isDate:i=>i instanceof Date&&!Number.isNaN(i.getTime()),isPlainObject:t,normalize(i){const r=n;if(r.isPrimitive(i))return"bigint"==typeof i?i.toString():i;if(r.isDate(i))return i.toISOString();if(Array.isArray(i))return i.map(i=>r.normalize(i));if(t(i)){const t={};for(const o in i)if(e(i,o)){const e=i[o];void 0!==e&&(t[o]=r.normalize(e))}return t}return i&&e(i,"toJSON")&&o(i.toJSON)?i.toJSON():{}}});export{n as Primitive};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var r=require("../utilities/freeze.js"),e=require("./primitive.js"),t=require("./url.js");const i=r.freeze({parse(r){if(!r)return{};const e=r.startsWith("?")?r.slice(1):r,i={};return e.split("&").forEach(r=>{if(!r)return;const[e,s]=r.split("=");e&&(i[t.Url.decode(e)]=s?t.Url.decode(s):"")}),i},stringify(r,i={}){if(null===r||"object"!=typeof r)return"";const{arrayFormat:s="none",arrayFormatSeparator:o=",",skipNull:n=!1,skipEmptyString:l=!1,encode:a=!0,strict:u=!0,sort:c=!1}=i,p=r=>r.length>0&&/^[a-zA-Z0-9_\-.[\]]+$/.test(r),f=r=>a?t.Url.encode(r,a):r,$=[],y=(r,t)=>{if(Array.isArray(t)){if("comma"===s||"separator"===s){const e=t.filter(r=>null!=r&&""!==r);return void(e.length>0&&$.push(`${f(r)}=${f(e.map(String).join(o))}`))}t.forEach((e,t)=>{let i=r;"bracket"===s?i=`${r}[]`:"index"===s&&(i=`${r}[${t}]`),y(i,e)})}else if(e.Primitive.isPlainObject(t))for(const e in t)Object.prototype.hasOwnProperty.call(t,e)&&y(`${r}[${e}]`,t[e]);else null!=t?""!==t?"boolean"!=typeof t?e.Primitive.isDate(t)?$.push(`${f(r)}=${f(t.toISOString())}`):$.push(`${f(r)}=${f(String(t))}`):$.push(`${f(r)}=${t?"true":"false"}`):l||$.push(`${f(r)}=`):n||$.push(`${f(r)}=`)};let h=Object.keys(r);c&&(h="function"==typeof c?h.sort(c):h.sort());for(const e of h)u&&!p(e)||y(e,r[e]);return $.join("&")}});exports.queryString=i;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{freeze as t}from"../utilities/freeze.mjs";import{Primitive as r}from"./primitive.mjs";import{Url as e}from"./url.mjs";const o=t({parse(t){if(!t)return{};const r=t.startsWith("?")?t.slice(1):t,o={};return r.split("&").forEach(t=>{if(!t)return;const[r,s]=t.split("=");r&&(o[e.decode(r)]=s?e.decode(s):"")}),o},stringify(t,o={}){if(null===t||"object"!=typeof t)return"";const{arrayFormat:s="none",arrayFormatSeparator:i=",",skipNull:n=!1,skipEmptyString:a=!1,encode:p=!0,strict:l=!0,sort:c=!1}=o,f=t=>t.length>0&&/^[a-zA-Z0-9_\-.[\]]+$/.test(t),u=t=>p?e.encode(t,p):t,m=[],$=(t,e)=>{if(Array.isArray(e)){if("comma"===s||"separator"===s){const r=e.filter(t=>null!=t&&""!==t);return void(r.length>0&&m.push(`${u(t)}=${u(r.map(String).join(i))}`))}e.forEach((r,e)=>{let o=t;"bracket"===s?o=`${t}[]`:"index"===s&&(o=`${t}[${e}]`),$(o,r)})}else if(r.isPlainObject(e))for(const r in e)Object.prototype.hasOwnProperty.call(e,r)&&$(`${t}[${r}]`,e[r]);else null!=e?""!==e?"boolean"!=typeof e?r.isDate(e)?m.push(`${u(t)}=${u(e.toISOString())}`):m.push(`${u(t)}=${u(String(e))}`):m.push(`${u(t)}=${e?"true":"false"}`):a||m.push(`${u(t)}=`):n||m.push(`${u(t)}=`)};let h=Object.keys(t);c&&(h="function"==typeof c?h.sort(c):h.sort());for(const r of h)l&&!f(r)||$(r,t[r]);return m.join("&")}});export{o as queryString};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Freezable, LiteralObject } from "../types/built-in";
|
|
2
|
+
/** Anything JSON can hold as a leaf, plus the JS primitives that need special care. */
|
|
3
|
+
export type PrimitiveValue = string | number | boolean | null | undefined | symbol | bigint;
|
|
4
|
+
/** Options for {@link queryString.stringify}. */
|
|
5
|
+
export interface SerializeQueryOptions {
|
|
6
|
+
/** Array serialization format. Defaults to `"none"`. */
|
|
7
|
+
arrayFormat?: "bracket" | "index" | "comma" | "separator" | "none";
|
|
8
|
+
/** Separator character when `arrayFormat` is `"separator"`. Defaults to `","`. */
|
|
9
|
+
arrayFormatSeparator?: string;
|
|
10
|
+
/** Skip keys whose value is `null` or `undefined`. */
|
|
11
|
+
skipNull?: boolean;
|
|
12
|
+
/** Skip keys whose value is an empty string. */
|
|
13
|
+
skipEmptyString?: boolean;
|
|
14
|
+
/** Whether to URL-encode keys and values, or a custom encoder function. Defaults to `true`. */
|
|
15
|
+
encode?: boolean | ((value: string) => string);
|
|
16
|
+
/** Reject keys with non-standard characters when `true`. Defaults to `true`. */
|
|
17
|
+
strict?: boolean;
|
|
18
|
+
/** Sort keys alphabetically, or provide a custom comparator. */
|
|
19
|
+
sort?: boolean | ((a: string, b: string) => number);
|
|
20
|
+
}
|
|
21
|
+
export type SerializePrimitive = Freezable<{
|
|
22
|
+
isString(value: unknown): value is string;
|
|
23
|
+
isNumber(value: unknown): value is number;
|
|
24
|
+
isBoolean(value: unknown): value is boolean;
|
|
25
|
+
isPrimitive(value: unknown): value is PrimitiveValue;
|
|
26
|
+
isDate(value: unknown): value is Date;
|
|
27
|
+
isPlainObject(value: unknown): value is LiteralObject;
|
|
28
|
+
normalize<T, R = unknown>(data: T): R;
|
|
29
|
+
}>;
|
|
30
|
+
export type SerializeJSON = Freezable<{
|
|
31
|
+
stringify: (value: unknown, space?: number) => string;
|
|
32
|
+
parse: <T = unknown>(text: string, reviver?: ((this: any, key: string, value: any) => any) | undefined) => T | null;
|
|
33
|
+
}>;
|
|
34
|
+
export type SerializeURL = Freezable<{
|
|
35
|
+
encode(value: string, component?: boolean | ((value: string) => string)): string;
|
|
36
|
+
decode(value: string, component?: boolean | ((value: string) => string)): string;
|
|
37
|
+
build(uri: string, params?: Record<string, PrimitiveValue> | null): string;
|
|
38
|
+
}>;
|
|
39
|
+
export type SerializeQueryString = Freezable<{
|
|
40
|
+
parse(query: string): Record<string, string>;
|
|
41
|
+
stringify(params: Record<string, unknown>, options?: SerializeQueryOptions): string;
|
|
42
|
+
}>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const e=require("../utilities/freeze.js").freeze({encode(e,r=!0){if(!e)return"";if("function"==typeof r)return r(e);try{return r?encodeURIComponent(e):encodeURI(e)}catch(t){const n=e.replace(/[\uD800-\uDFFF]/g,"");return r?encodeURIComponent(n):encodeURI(n)}},decode:(e,r=!0)=>{if(!e)return"";if("function"==typeof r)return r(e);const t=r?decodeURIComponent:decodeURI;return(r?e.replace(/\+/g,"%20"):e).replace(/(%[0-9A-F]{2})+/gi,e=>{try{return t(e)}catch(r){return e}})},build:(r,t)=>r?t&&"object"==typeof t?r.replace(/:([a-zA-Z\d_]+)/g,(r,n)=>{const o=t[n];return null==o?r:e.encode(String(o),!0)}):r:""});exports.Url=e;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{freeze as e}from"../utilities/freeze.mjs";const n=e({encode(e,n=!0){if(!e)return"";if("function"==typeof n)return n(e);try{return n?encodeURIComponent(e):encodeURI(e)}catch(t){const r=e.replace(/[\uD800-\uDFFF]/g,"");return n?encodeURIComponent(r):encodeURI(r)}},decode:(e,n=!0)=>{if(!e)return"";if("function"==typeof n)return n(e);const t=n?decodeURIComponent:decodeURI;return(n?e.replace(/\+/g,"%20"):e).replace(/(%[0-9A-F]{2})+/gi,e=>{try{return t(e)}catch(n){return e}})},build:(e,t)=>e?t&&"object"==typeof t?e.replace(/:([a-zA-Z\d_]+)/g,(e,r)=>{const o=t[r];return null==o?e:n.encode(String(o),!0)}):e:""});export{n as Url};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where every number comes from.
|
|
3
|
+
*
|
|
4
|
+
* All of it is Node stdlib — perf_hooks, v8, os, process — plus two things the
|
|
5
|
+
* host feeds in: `recordHttpRequest` for traffic, and the `db` callback given
|
|
6
|
+
* to `Syhemo.start()`. Nothing here knows what framework is running above it.
|
|
7
|
+
*
|
|
8
|
+
* Two rules hold throughout, both from the Prometheus model:
|
|
9
|
+
*
|
|
10
|
+
* - Values are in base units and are not rounded.
|
|
11
|
+
* - Anything typed `counter` only ever grows. Collection runs on Syhemo's own
|
|
12
|
+
* interval, so a scrape never mutates state and two scrapers never steal
|
|
13
|
+
* each other's numbers.
|
|
14
|
+
*/
|
|
15
|
+
import type { Metric, SyhemoLogSource } from "./types";
|
|
16
|
+
/**
|
|
17
|
+
* Records one finished request.
|
|
18
|
+
*
|
|
19
|
+
* @param latencyMs Duration in milliseconds — converted to seconds here, since
|
|
20
|
+
* callers time requests in ms and Prometheus wants seconds.
|
|
21
|
+
*/
|
|
22
|
+
export declare function recordHttpRequest(latencyMs: number): void;
|
|
23
|
+
/** Registers the connectivity probe `Syhemo.start({ db })` was given. */
|
|
24
|
+
export declare function setDbChecker(fn: (() => boolean) | null): void;
|
|
25
|
+
export declare function collectMetrics(source: SyhemoLogSource): Metric[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var node_perf_hooks=require("node:perf_hooks"),v8=require("v8"),os=require("os");function _interopNamespace(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(o){if("default"!==o){var a=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,a.get?a:{enumerable:!0,get:function(){return e[o]}})}}),t.default=e,Object.freeze(t)}var v8__namespace=_interopNamespace(v8),os__namespace=_interopNamespace(os);const NS_PER_SECOND=1e9,MS_PER_SECOND=1e3;function collectMemory(){const e=process.memoryUsage();return[{name:"process_resident_memory_bytes",type:"gauge",help:"Resident set size in bytes.",value:e.rss},{name:"nodejs_external_memory_bytes",type:"gauge",help:"Memory used by C++ objects bound to JavaScript, in bytes.",value:e.external},{name:"nodejs_array_buffers_bytes",type:"gauge",help:"Memory allocated for ArrayBuffers and SharedArrayBuffers, in bytes.",value:e.arrayBuffers}]}let prevCpuUsage=null;function collectCpu(){var e,t;const o=os__namespace.cpus();let a=0;if(prevCpuUsage&&prevCpuUsage.length===o.length){let e=0,t=0;for(let a=0;a<o.length;a++){const l=prevCpuUsage[a].times,s=o[a].times,n=l.user+l.nice+l.sys+l.idle+l.irq;e+=s.user+s.nice+s.sys+s.idle+s.irq-n,t+=s.idle-l.idle}a=e>0?1-t/e:0}return prevCpuUsage=o,[{name:"process_cpu_usage_ratio",type:"gauge",help:"Share of CPU time spent non-idle since the previous collection, 0 to 1.",value:a},{name:"nodejs_cpu_count",type:"gauge",help:"Number of logical CPUs.",value:o.length},{name:"nodejs_cpu_info",type:"gauge",help:"CPU model, always 1.",labels:{model:null!==(t=null===(e=o[0])||void 0===e?void 0:e.model)&&void 0!==t?t:"unknown"},value:1}]}function collectHeap(){const e=v8__namespace.getHeapStatistics();return[{name:"nodejs_heap_size_total_bytes",type:"gauge",help:"Total V8 heap size in bytes.",value:e.total_heap_size},{name:"nodejs_heap_size_used_bytes",type:"gauge",help:"Used V8 heap size in bytes.",value:e.used_heap_size},{name:"nodejs_heap_size_limit_bytes",type:"gauge",help:"Ceiling V8 will grow the heap to, in bytes.",value:e.heap_size_limit},{name:"nodejs_malloced_memory_bytes",type:"gauge",help:"Memory malloc'd by V8, in bytes.",value:e.malloced_memory},{name:"nodejs_native_contexts",type:"gauge",help:"Live top-level contexts. A number that only grows indicates a leak.",value:e.number_of_native_contexts},{name:"nodejs_detached_contexts",type:"gauge",help:"Contexts detached but not yet garbage collected.",value:e.number_of_detached_contexts}]}function collectHandles(){var e,t,o,a,l,s;const n=null!==(t=null===(e=process._getActiveHandles)||void 0===e?void 0:e.call(process))&&void 0!==t?t:[],r=null!==(a=null===(o=process._getActiveRequests)||void 0===o?void 0:o.call(process))&&void 0!==a?a:[];let c=0,u=0;for(const e of n){const t=null!==(s=null===(l=null==e?void 0:e.constructor)||void 0===l?void 0:l.name)&&void 0!==s?s:"";"Timeout"===t||"Timer"===t||"Immediate"===t?c++:"Socket"!==t&&"TCP"!==t&&"TLSSocket"!==t||u++}return[{name:"nodejs_active_handles",type:"gauge",help:"Active libuv handles by kind.",labels:{kind:"timer"},value:c},{name:"nodejs_active_handles",type:"gauge",help:"Active libuv handles by kind.",labels:{kind:"socket"},value:u},{name:"nodejs_active_handles",type:"gauge",help:"Active libuv handles by kind.",labels:{kind:"other"},value:n.length-c-u},{name:"nodejs_active_requests_total",type:"gauge",help:"Active libuv requests.",value:r.length}]}const TOP_MODULE_GROUPS=20;function collectModules(){var _a;try{const cache=eval("typeof require !== 'undefined' && require.cache")||{},keys=Object.keys(cache),groups=new Map;for(const e of keys){const t=e.match(/node_modules\/([^/]+)/),o=t?`node_modules/${t[1]}`:e.replace(process.cwd(),".");groups.set(o,(null!==(_a=groups.get(o))&&void 0!==_a?_a:0)+1)}const top=Array.from(groups.entries()).sort((e,t)=>t[1]-e[1]).slice(0,TOP_MODULE_GROUPS);return[{name:"nodejs_module_cache_entries",type:"gauge",help:"Entries in the CommonJS module cache.",value:keys.length},...top.map(([e,t])=>({name:"nodejs_module_cache_entries_by_group",type:"gauge",help:`Module cache entries per group, top ${TOP_MODULE_GROUPS}.`,labels:{group:e},value:t}))]}catch(e){return[{name:"nodejs_module_cache_entries",type:"gauge",help:"Entries in the CommonJS module cache.",value:0}]}}const histogram=node_perf_hooks.monitorEventLoopDelay({resolution:10});function collectEventLoop(){const e=0===histogram.count,t=t=>e||!Number.isFinite(t)?0:t/NS_PER_SECOND,o=[{name:"nodejs_eventloop_lag_mean_seconds",type:"gauge",help:"Mean event loop lag over the last interval.",value:t(histogram.mean)},{name:"nodejs_eventloop_lag_min_seconds",type:"gauge",help:"Minimum event loop lag over the last interval.",value:t(histogram.min)},{name:"nodejs_eventloop_lag_max_seconds",type:"gauge",help:"Maximum event loop lag over the last interval.",value:t(histogram.max)},{name:"nodejs_eventloop_lag_p99_seconds",type:"gauge",help:"99th percentile event loop lag over the last interval.",value:t(histogram.percentile(99))}];return histogram.reset(),o}histogram.enable();const LATENCY_BUCKETS=[.005,.01,.025,.05,.1,.25,.5,1,2.5,5,10];let httpTotal=0,httpDurationSum=0;const httpBuckets=new Array(LATENCY_BUCKETS.length+1).fill(0);function recordHttpRequest(e){const t=e/MS_PER_SECOND;httpTotal++,httpDurationSum+=t;for(let e=0;e<LATENCY_BUCKETS.length;e++)t<=LATENCY_BUCKETS[e]&&httpBuckets[e]++;httpBuckets[LATENCY_BUCKETS.length]++}function collectHttp(){const e=LATENCY_BUCKETS.map((e,t)=>({le:e,count:httpBuckets[t]}));return e.push({le:1/0,count:httpBuckets[LATENCY_BUCKETS.length]}),[{name:"http_requests_total",type:"counter",help:"Requests recorded since the process started.",value:httpTotal},{name:"http_request_duration_seconds",type:"histogram",help:"Request duration in seconds.",buckets:e,sum:httpDurationSum,count:httpTotal}]}let dbChecker=null;function setDbChecker(e){dbChecker=e}function collectDbPool(){return[{name:"db_pool_connected",type:"gauge",help:"1 when the database pool reports a connection, 0 otherwise.",value:dbChecker&&dbChecker()?1:0}]}function collectLogs(e){const t=e.counts(),o="Log entries written since the process started, by level.";return[{name:"nodejs_log_entries_total",type:"counter",help:o,labels:{level:"error"},value:t.errors},{name:"nodejs_log_entries_total",type:"counter",help:o,labels:{level:"warn"},value:t.warns},{name:"nodejs_log_entries_total",type:"counter",help:o,labels:{level:"other"},value:Math.max(0,t.total-t.errors-t.warns)}]}function collectSystem(){const[e,t,o]=os__namespace.loadavg(),a="System load average.";return[{name:"nodejs_version_info",type:"gauge",help:"Node.js version and platform, always 1.",labels:{version:process.version,platform:os__namespace.platform(),arch:os__namespace.arch()},value:1},{name:"system_memory_total_bytes",type:"gauge",help:"Total system memory in bytes.",value:os__namespace.totalmem()},{name:"system_memory_free_bytes",type:"gauge",help:"Free system memory in bytes.",value:os__namespace.freemem()},{name:"process_uptime_seconds",type:"gauge",help:"Seconds since the process started.",value:process.uptime()},{name:"system_load_average",type:"gauge",help:a,labels:{period:"1m"},value:e},{name:"system_load_average",type:"gauge",help:a,labels:{period:"5m"},value:t},{name:"system_load_average",type:"gauge",help:a,labels:{period:"15m"},value:o}]}function collectMetrics(e){return[...collectMemory(),...collectCpu(),...collectHeap(),...collectHandles(),...collectModules(),...collectEventLoop(),...collectHttp(),...collectDbPool(),...collectLogs(e),...collectSystem()]}exports.collectMetrics=collectMetrics,exports.recordHttpRequest=recordHttpRequest,exports.setDbChecker=setDbChecker;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{monitorEventLoopDelay}from"node:perf_hooks";import*as v8 from"v8";import*as os from"os";const NS_PER_SECOND=1e9,MS_PER_SECOND=1e3;function collectMemory(){const e=process.memoryUsage();return[{name:"process_resident_memory_bytes",type:"gauge",help:"Resident set size in bytes.",value:e.rss},{name:"nodejs_external_memory_bytes",type:"gauge",help:"Memory used by C++ objects bound to JavaScript, in bytes.",value:e.external},{name:"nodejs_array_buffers_bytes",type:"gauge",help:"Memory allocated for ArrayBuffers and SharedArrayBuffers, in bytes.",value:e.arrayBuffers}]}let prevCpuUsage=null;function collectCpu(){var e,t;const o=os.cpus();let l=0;if(prevCpuUsage&&prevCpuUsage.length===o.length){let e=0,t=0;for(let l=0;l<o.length;l++){const s=prevCpuUsage[l].times,a=o[l].times,n=s.user+s.nice+s.sys+s.idle+s.irq;e+=a.user+a.nice+a.sys+a.idle+a.irq-n,t+=a.idle-s.idle}l=e>0?1-t/e:0}return prevCpuUsage=o,[{name:"process_cpu_usage_ratio",type:"gauge",help:"Share of CPU time spent non-idle since the previous collection, 0 to 1.",value:l},{name:"nodejs_cpu_count",type:"gauge",help:"Number of logical CPUs.",value:o.length},{name:"nodejs_cpu_info",type:"gauge",help:"CPU model, always 1.",labels:{model:null!==(t=null===(e=o[0])||void 0===e?void 0:e.model)&&void 0!==t?t:"unknown"},value:1}]}function collectHeap(){const e=v8.getHeapStatistics();return[{name:"nodejs_heap_size_total_bytes",type:"gauge",help:"Total V8 heap size in bytes.",value:e.total_heap_size},{name:"nodejs_heap_size_used_bytes",type:"gauge",help:"Used V8 heap size in bytes.",value:e.used_heap_size},{name:"nodejs_heap_size_limit_bytes",type:"gauge",help:"Ceiling V8 will grow the heap to, in bytes.",value:e.heap_size_limit},{name:"nodejs_malloced_memory_bytes",type:"gauge",help:"Memory malloc'd by V8, in bytes.",value:e.malloced_memory},{name:"nodejs_native_contexts",type:"gauge",help:"Live top-level contexts. A number that only grows indicates a leak.",value:e.number_of_native_contexts},{name:"nodejs_detached_contexts",type:"gauge",help:"Contexts detached but not yet garbage collected.",value:e.number_of_detached_contexts}]}function collectHandles(){var e,t,o,l,s,a;const n=null!==(t=null===(e=process._getActiveHandles)||void 0===e?void 0:e.call(process))&&void 0!==t?t:[],r=null!==(l=null===(o=process._getActiveRequests)||void 0===o?void 0:o.call(process))&&void 0!==l?l:[];let c=0,u=0;for(const e of n){const t=null!==(a=null===(s=null==e?void 0:e.constructor)||void 0===s?void 0:s.name)&&void 0!==a?a:"";"Timeout"===t||"Timer"===t||"Immediate"===t?c++:"Socket"!==t&&"TCP"!==t&&"TLSSocket"!==t||u++}return[{name:"nodejs_active_handles",type:"gauge",help:"Active libuv handles by kind.",labels:{kind:"timer"},value:c},{name:"nodejs_active_handles",type:"gauge",help:"Active libuv handles by kind.",labels:{kind:"socket"},value:u},{name:"nodejs_active_handles",type:"gauge",help:"Active libuv handles by kind.",labels:{kind:"other"},value:n.length-c-u},{name:"nodejs_active_requests_total",type:"gauge",help:"Active libuv requests.",value:r.length}]}const TOP_MODULE_GROUPS=20;function collectModules(){var _a;try{const cache=eval("typeof require !== 'undefined' && require.cache")||{},keys=Object.keys(cache),groups=new Map;for(const e of keys){const t=e.match(/node_modules\/([^/]+)/),o=t?`node_modules/${t[1]}`:e.replace(process.cwd(),".");groups.set(o,(null!==(_a=groups.get(o))&&void 0!==_a?_a:0)+1)}const top=Array.from(groups.entries()).sort((e,t)=>t[1]-e[1]).slice(0,TOP_MODULE_GROUPS);return[{name:"nodejs_module_cache_entries",type:"gauge",help:"Entries in the CommonJS module cache.",value:keys.length},...top.map(([e,t])=>({name:"nodejs_module_cache_entries_by_group",type:"gauge",help:`Module cache entries per group, top ${TOP_MODULE_GROUPS}.`,labels:{group:e},value:t}))]}catch(e){return[{name:"nodejs_module_cache_entries",type:"gauge",help:"Entries in the CommonJS module cache.",value:0}]}}const histogram=monitorEventLoopDelay({resolution:10});function collectEventLoop(){const e=0===histogram.count,t=t=>e||!Number.isFinite(t)?0:t/NS_PER_SECOND,o=[{name:"nodejs_eventloop_lag_mean_seconds",type:"gauge",help:"Mean event loop lag over the last interval.",value:t(histogram.mean)},{name:"nodejs_eventloop_lag_min_seconds",type:"gauge",help:"Minimum event loop lag over the last interval.",value:t(histogram.min)},{name:"nodejs_eventloop_lag_max_seconds",type:"gauge",help:"Maximum event loop lag over the last interval.",value:t(histogram.max)},{name:"nodejs_eventloop_lag_p99_seconds",type:"gauge",help:"99th percentile event loop lag over the last interval.",value:t(histogram.percentile(99))}];return histogram.reset(),o}histogram.enable();const LATENCY_BUCKETS=[.005,.01,.025,.05,.1,.25,.5,1,2.5,5,10];let httpTotal=0,httpDurationSum=0;const httpBuckets=new Array(LATENCY_BUCKETS.length+1).fill(0);function recordHttpRequest(e){const t=e/MS_PER_SECOND;httpTotal++,httpDurationSum+=t;for(let e=0;e<LATENCY_BUCKETS.length;e++)t<=LATENCY_BUCKETS[e]&&httpBuckets[e]++;httpBuckets[LATENCY_BUCKETS.length]++}function collectHttp(){const e=LATENCY_BUCKETS.map((e,t)=>({le:e,count:httpBuckets[t]}));return e.push({le:1/0,count:httpBuckets[LATENCY_BUCKETS.length]}),[{name:"http_requests_total",type:"counter",help:"Requests recorded since the process started.",value:httpTotal},{name:"http_request_duration_seconds",type:"histogram",help:"Request duration in seconds.",buckets:e,sum:httpDurationSum,count:httpTotal}]}let dbChecker=null;function setDbChecker(e){dbChecker=e}function collectDbPool(){return[{name:"db_pool_connected",type:"gauge",help:"1 when the database pool reports a connection, 0 otherwise.",value:dbChecker&&dbChecker()?1:0}]}function collectLogs(e){const t=e.counts(),o="Log entries written since the process started, by level.";return[{name:"nodejs_log_entries_total",type:"counter",help:o,labels:{level:"error"},value:t.errors},{name:"nodejs_log_entries_total",type:"counter",help:o,labels:{level:"warn"},value:t.warns},{name:"nodejs_log_entries_total",type:"counter",help:o,labels:{level:"other"},value:Math.max(0,t.total-t.errors-t.warns)}]}function collectSystem(){const[e,t,o]=os.loadavg(),l="System load average.";return[{name:"nodejs_version_info",type:"gauge",help:"Node.js version and platform, always 1.",labels:{version:process.version,platform:os.platform(),arch:os.arch()},value:1},{name:"system_memory_total_bytes",type:"gauge",help:"Total system memory in bytes.",value:os.totalmem()},{name:"system_memory_free_bytes",type:"gauge",help:"Free system memory in bytes.",value:os.freemem()},{name:"process_uptime_seconds",type:"gauge",help:"Seconds since the process started.",value:process.uptime()},{name:"system_load_average",type:"gauge",help:l,labels:{period:"1m"},value:e},{name:"system_load_average",type:"gauge",help:l,labels:{period:"5m"},value:t},{name:"system_load_average",type:"gauge",help:l,labels:{period:"15m"},value:o}]}function collectMetrics(e){return[...collectMemory(),...collectCpu(),...collectHeap(),...collectHandles(),...collectModules(),...collectEventLoop(),...collectHttp(),...collectDbPool(),...collectLogs(e),...collectSystem()]}export{collectMetrics,recordHttpRequest,setDbChecker};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Metric } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Renders metrics as the Prometheus text exposition format.
|
|
4
|
+
*
|
|
5
|
+
* Serve the result verbatim with `CONTENT_TYPE`; nothing else is required to
|
|
6
|
+
* be scrapeable.
|
|
7
|
+
*/
|
|
8
|
+
/** What a `/metrics` response must declare. */
|
|
9
|
+
export declare const CONTENT_TYPE = "text/plain; version=0.0.4; charset=utf-8";
|
|
10
|
+
/**
|
|
11
|
+
* `# HELP` and `# TYPE` are declared once per metric name, even when several
|
|
12
|
+
* series share it under different labels — repeating them makes the scrape
|
|
13
|
+
* fail with a duplicate-metadata error.
|
|
14
|
+
*/
|
|
15
|
+
export declare function render(metrics: Metric[]): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function e(e,n){const t=Object.assign(Object.assign({},e),n),r=Object.keys(t);if(0===r.length)return"";return`{${r.map(e=>{return`${e}="${n=t[e],n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}"`;var n}).join(",")}}`}function n(e){return e===1/0?"+Inf":e===-1/0?"-Inf":Number.isNaN(e)?"NaN":String(e)}function t(t){return[`${t.name}${e(t.labels)} ${n(t.value)}`]}function r(t){const r=t.buckets.map(r=>`${t.name}_bucket${e(t.labels,{le:n(r.le)})} ${n(r.count)}`);return r.push(`${t.name}_sum${e(t.labels)} ${n(t.sum)}`),r.push(`${t.name}_count${e(t.labels)} ${n(t.count)}`),r}exports.CONTENT_TYPE="text/plain; version=0.0.4; charset=utf-8",exports.render=function(e){const n=[],s=new Set;for(const a of e)s.has(a.name)||(s.add(a.name),n.push(`# HELP ${a.name} ${a.help.replace(/\n/g," ")}`),n.push(`# TYPE ${a.name} ${a.type}`)),n.push(..."histogram"===a.type?r(a):t(a));return n.length?`${n.join("\n")}\n`:""};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const n="text/plain; version=0.0.4; charset=utf-8";function e(n,e){const t=Object.assign(Object.assign({},n),e),a=Object.keys(t);if(0===a.length)return"";return`{${a.map(n=>{return`${n}="${e=t[n],e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n")}"`;var e}).join(",")}}`}function t(n){return n===1/0?"+Inf":n===-1/0?"-Inf":Number.isNaN(n)?"NaN":String(n)}function a(n){return[`${n.name}${e(n.labels)} ${t(n.value)}`]}function s(n){const a=n.buckets.map(a=>`${n.name}_bucket${e(n.labels,{le:t(a.le)})} ${t(a.count)}`);return a.push(`${n.name}_sum${e(n.labels)} ${t(n.sum)}`),a.push(`${n.name}_count${e(n.labels)} ${t(n.count)}`),a}function u(n){const e=[],t=new Set;for(const u of n)t.has(u.name)||(t.add(u.name),e.push(`# HELP ${u.name} ${u.help.replace(/\n/g," ")}`),e.push(`# TYPE ${u.name} ${u.type}`)),e.push(..."histogram"===u.type?s(u):a(u));return e.length?`${e.join("\n")}\n`:""}export{n as CONTENT_TYPE,u as render};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Syhemo: in-process runtime monitoring.
|
|
3
|
+
*
|
|
4
|
+
* Node-only, and not re-exported from the package index — reach it by
|
|
5
|
+
* subpath: `import { Syhemo } from "@ecosy/core/syhemo"`.
|
|
6
|
+
*
|
|
7
|
+
* Metrics follow the Prometheus model, so exposing them is a two-line route
|
|
8
|
+
* with no client library involved:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* export function GET() {
|
|
12
|
+
* return new Response(monitor.metrics(), {
|
|
13
|
+
* headers: { "Content-Type": CONTENT_TYPE },
|
|
14
|
+
* });
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* Collection runs on this class's own timer, never on a scrape, which is what
|
|
19
|
+
* makes that route safe to call from more than one scraper: reading never
|
|
20
|
+
* mutates a counter.
|
|
21
|
+
*/
|
|
22
|
+
import { Subscriber } from "../subscriber";
|
|
23
|
+
import type { Metric, SyhemoDeps, SyhemoOptions, SyhemoState } from "./types";
|
|
24
|
+
export * from "./types";
|
|
25
|
+
export { recordHttpRequest } from "./collectors";
|
|
26
|
+
export { render, CONTENT_TYPE } from "./exposition";
|
|
27
|
+
declare const syhemoEvents: {
|
|
28
|
+
readonly metrics: {
|
|
29
|
+
readonly snapshot: "syhemo:metrics:snapshot";
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
type SyhemoEvents = typeof syhemoEvents;
|
|
33
|
+
export declare class Syhemo extends Subscriber<SyhemoState, SyhemoEvents> {
|
|
34
|
+
private timer;
|
|
35
|
+
private readonly logger;
|
|
36
|
+
private readonly source;
|
|
37
|
+
constructor(deps?: SyhemoDeps);
|
|
38
|
+
start(options?: SyhemoOptions): void;
|
|
39
|
+
stop(): void;
|
|
40
|
+
/** The most recent collection, or an empty list before the first one. */
|
|
41
|
+
getMetrics(): Metric[];
|
|
42
|
+
/**
|
|
43
|
+
* The most recent collection in Prometheus text exposition format.
|
|
44
|
+
*
|
|
45
|
+
* Serve it with `CONTENT_TYPE`. Returns an empty string before the first
|
|
46
|
+
* collection, which a scraper reads as "no metrics" rather than an error.
|
|
47
|
+
*/
|
|
48
|
+
metrics(): string;
|
|
49
|
+
private collect;
|
|
50
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("../subscriber.js"),t=require("../utilities/freeze.js"),s=require("./logger.js"),r=require("./collectors.js"),i=require("./exposition.js");const o=t.freeze({metrics:{snapshot:"syhemo:metrics:snapshot"}});class l extends e.Subscriber{constructor(e={}){var t,r;super({current:null,snapshots:[],logs:[],started:!1},o),this.timer=null,this.logger=null!==(t=e.logger)&&void 0!==t?t:new s.BufferedLogger("Syhemo"),this.source=null!==(r=e.source)&&void 0!==r?r:s.BufferedLogger}start(e={}){if(this.getState().started)return;const{interval:t=5e3,db:s}=e;s&&r.setDbChecker(s),this.setState({started:!0}),this.collect(),this.timer=setInterval(()=>this.collect(),t),this.logger.log(`Started (interval: ${t}ms)`)}stop(){this.timer&&(clearInterval(this.timer),this.timer=null),this.setState({started:!1}),this.logger.log("Stopped")}getMetrics(){var e,t;return null!==(t=null===(e=this.getState().current)||void 0===e?void 0:e.metrics)&&void 0!==t?t:[]}metrics(){return i.render(this.getMetrics())}collect(){try{const e={timestamp:Date.now(),metrics:r.collectMetrics(this.source)},t=this.getState().snapshots,s=t.length>=60?[...t.slice(1),e]:[...t,e];this.setState({current:e,snapshots:s,logs:this.source.getLogs()}),this.dispatch(o.metrics.snapshot,e)}catch(e){this.logger.error(`Collection failed: ${e}`)}}}exports.recordHttpRequest=r.recordHttpRequest,exports.CONTENT_TYPE=i.CONTENT_TYPE,exports.render=i.render,exports.Syhemo=l;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Subscriber as t}from"../subscriber.mjs";import{freeze as s}from"../utilities/freeze.mjs";import{BufferedLogger as e}from"./logger.mjs";import{collectMetrics as r,setDbChecker as o}from"./collectors.mjs";export{recordHttpRequest}from"./collectors.mjs";import{render as i}from"./exposition.mjs";export{CONTENT_TYPE}from"./exposition.mjs";const l=s({metrics:{snapshot:"syhemo:metrics:snapshot"}});class c extends t{constructor(t={}){var s,r;super({current:null,snapshots:[],logs:[],started:!1},l),this.timer=null,this.logger=null!==(s=t.logger)&&void 0!==s?s:new e("Syhemo"),this.source=null!==(r=t.source)&&void 0!==r?r:e}start(t={}){if(this.getState().started)return;const{interval:s=5e3,db:e}=t;e&&o(e),this.setState({started:!0}),this.collect(),this.timer=setInterval(()=>this.collect(),s),this.logger.log(`Started (interval: ${s}ms)`)}stop(){this.timer&&(clearInterval(this.timer),this.timer=null),this.setState({started:!1}),this.logger.log("Stopped")}getMetrics(){var t,s;return null!==(s=null===(t=this.getState().current)||void 0===t?void 0:t.metrics)&&void 0!==s?s:[]}metrics(){return i(this.getMetrics())}collect(){try{const t={timestamp:Date.now(),metrics:r(this.source)},s=this.getState().snapshots,e=s.length>=60?[...s.slice(1),t]:[...s,t];this.setState({current:t,snapshots:e,logs:this.source.getLogs()}),this.dispatch(l.metrics.snapshot,t)}catch(t){this.logger.error(`Collection failed: ${t}`)}}}export{c as Syhemo,i as render};
|