@hyperttp/core 1.5.0 → 1.5.2
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/Core/HyperCore.d.ts +63 -109
- package/Core/HyperCore.d.ts.map +1 -1
- package/Core/HyperCore.js +1 -1
- package/Core/HyperCore.js.map +3 -3
- package/Core/RequestBuilder.d.ts +26 -5
- package/Core/RequestBuilder.d.ts.map +1 -1
- package/Core/RequestBuilder.js +1 -1
- package/Core/RequestBuilder.js.map +3 -3
- package/defaultConfig.d.ts +4 -0
- package/defaultConfig.d.ts.map +1 -1
- package/defaultConfig.js.map +2 -2
- package/package.json +5 -4
- package/transports/browser.d.ts.map +1 -1
- package/transports/browser.js.map +1 -1
- package/transports/manager.d.ts.map +1 -1
- package/transports/node.d.ts +1 -0
- package/transports/node.d.ts.map +1 -1
- package/transports/node.js +1 -1
- package/transports/node.js.map +3 -3
- package/utils/errors.d.ts.map +1 -1
- package/utils/errors.js.map +2 -2
- package/utils/normalize.d.ts +19 -41
- package/utils/normalize.d.ts.map +1 -1
- package/utils/normalize.js +1 -1
- package/utils/normalize.js.map +3 -3
- package/utils/response.d.ts +54 -59
- package/utils/response.d.ts.map +1 -1
- package/utils/response.js +1 -1
- package/utils/response.js.map +3 -3
- package/utils/retryUtils.d.ts.map +1 -1
- package/utils/retryUtils.js +1 -1
- package/utils/retryUtils.js.map +2 -2
package/utils/normalize.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/normalize.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Method, RequestBodyData } from \"@hyperttp/types\";\n\ntype NormalizedHeaders = Record<string, string | string[]>;\n\n/**\n * @ru \u041A\u0430\u0440\u0442\u0430 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0434\u043E\u043B\u0436\u043D\u044B \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u043E\u0434\u043D\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 (\u043D\u0435 \u043C\u0430\u0441\u0441\u0438\u0432).\n * \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442 `Object.create(null)` \u0434\u043B\u044F \u0431\u044B\u0441\u0442\u0440\u043E\u0433\u043E \u0434\u043E\u0441\u0442\u0443\u043F\u0430 \u0431\u0435\u0437 \u043F\u0440\u043E\u0442\u043E\u0442\u0438\u043F\u0430.\n * @en Map of headers that should contain only a single value (not an array).\n * Uses `Object.create(null)` for fast prototype-less access.\n */\nconst SINGLE_VALUE_HEADERS: Record<string, 1> = Object.create(null);\nfor (const h of [\n \"content-type\",\n \"content-length\",\n \"content-encoding\",\n \"content-disposition\",\n \"host\",\n \"authorization\",\n \"proxy-authorization\",\n \"user-agent\",\n \"referer\",\n \"origin\",\n \"location\",\n \"etag\",\n \"last-modified\",\n] as const) {\n SINGLE_VALUE_HEADERS[h] = 1;\n}\n\n\n\n/**\n * @ru \u041A\u044D\u0448 \u0434\u043B\u044F \u043D\u043E\u0440\u043C\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 \u043A\u043B\u044E\u0447\u0435\u0439 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432 (lowercase).\n * \u041E\u0433\u0440\u0430\u043D\u0438\u0447\u0435\u043D \u0440\u0430\u0437\u043C\u0435\u0440\u043E\u043C HEADER_CACHE_LIMIT \u0434\u043B\u044F \u043F\u0440\u0435\u0434\u043E\u0442\u0432\u0440\u0430\u0449\u0435\u043D\u0438\u044F \u0443\u0442\u0435\u0447\u0435\u043A \u043F\u0430\u043C\u044F\u0442\u0438.\n * @en Cache for header key normalization (lowercase).\n * Limited by HEADER_CACHE_LIMIT to prevent memory leaks.\n */\nconst HEADER_CACHE_LIMIT = 2048;\nconst HEADER_KEY_CACHE: Record<string, string> = Object.create(null);\n\n/**\n * @ru \u0421\u043F\u0438\u0441\u043E\u043A \u043D\u0430\u0438\u0431\u043E\u043B\u0435\u0435 \u0440\u0430\u0441\u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0445 HTTP-\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432 \u0434\u043B\u044F \u043F\u0440\u0435\u0434\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F \u043A\u044D\u0448\u0430.\n * @en List of most common HTTP headers for cache pre-population.\n */\nconst COMMON_HEADERS = [\n \"accept\",\n \"accept-encoding\",\n \"accept-language\",\n \"authorization\",\n \"cache-control\",\n \"connection\",\n \"content-encoding\",\n \"content-length\",\n \"content-type\",\n \"cookie\",\n \"date\",\n \"etag\",\n \"host\",\n \"if-modified-since\",\n \"if-none-match\",\n \"keep-alive\",\n \"location\",\n \"origin\",\n \"pragma\",\n \"proxy-authorization\",\n \"referer\",\n \"sec-ch-ua\",\n \"server\",\n \"set-cookie\",\n \"transfer-encoding\",\n \"user-agent\",\n \"x-forwarded-for\",\n \"x-requested-with\",\n] as const;\n\nfor (let i = 0; i < COMMON_HEADERS.length; i++) {\n const lower = COMMON_HEADERS[i]!;\n HEADER_KEY_CACHE[lower] = lower;\n}\n\nlet cacheSize = COMMON_HEADERS.length;\n\n/**\n * @ru \u0411\u044B\u0441\u0442\u0440\u0430\u044F \u043D\u043E\u0440\u043C\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u043A\u043B\u044E\u0447\u0430 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430 \u0432 \u043D\u0438\u0436\u043D\u0438\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440 \u0441 \u043A\u044D\u0448\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435\u043C.\n * @en Fast header key normalization to lowercase with caching.\n * @param key - The header key to normalize.\n * @returns The lowercase version of the key.\n */\nfunction fastLowercaseKey(key: string): string {\n const cached = HEADER_KEY_CACHE[key];\n if (cached !== undefined) return cached;\n\n const lower = key.toLowerCase();\n if (cacheSize < HEADER_CACHE_LIMIT) {\n HEADER_KEY_CACHE[key] = lower;\n cacheSize++;\n }\n return lower;\n}\n\n/**\n * @ru \u0418\u0437\u0432\u043B\u0435\u043A\u0430\u0435\u0442 URL \u0438\u0437 \u043E\u0431\u044A\u0435\u043A\u0442\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u0438\u043B\u0438 \u0441\u0442\u0440\u043E\u043A\u0438.\n * \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043B\u0438\u0447\u043D\u044B\u0435 \u0444\u043E\u0440\u043C\u0430\u0442\u044B: \u0441\u0442\u0440\u043E\u043A\u0430, \u043E\u0431\u044A\u0435\u043A\u0442 \u0441 \u043F\u043E\u043B\u0435\u043C `url`, `_url`, \u0438\u043B\u0438 `scheme/host/path`.\n * @en Extracts URL from a request object or string.\n * Supports various formats: string, object with `url`, `_url`, or `scheme/host/path` fields.\n * @param req - The request object or URL string.\n * @returns The extracted URL string.\n * @throws Error if URL is missing in the request.\n */\nexport function normalizeUrl(req: unknown): string {\n if (typeof req === \"string\") return req;\n\n if (req && typeof req === \"object\") {\n const r = req as Record<string, unknown>;\n\n const url = r.url;\n if (typeof url === \"string\") return url;\n if (url != null) return String(url);\n\n const u = r._url;\n if (typeof u === \"string\") return u;\n if (u != null) return String(u);\n\n const scheme = r.scheme;\n const host = r.host;\n const path = r.path;\n\n if (typeof scheme === \"string\" && typeof host === \"string\" && typeof path === \"string\") {\n return `${scheme}://${host}${path}`;\n }\n }\n\n throw new Error(\"URL missing in request\");\n}\n\n/**\n * @ru \u0414\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u0442 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430 \u043A \u043D\u043E\u0440\u043C\u0430\u043B\u0438\u0437\u043E\u0432\u0430\u043D\u043D\u043E\u043C\u0443 \u043E\u0431\u044A\u0435\u043A\u0442\u0443 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432.\n * \u0423\u0447\u0438\u0442\u044B\u0432\u0430\u0435\u0442 \u0441\u043F\u0435\u0446\u0438\u0430\u043B\u044C\u043D\u044B\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430 \u0434\u043B\u044F `set-cookie`, `cookie`, \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432.\n * @en Appends a header value to the normalized headers object.\n * Accounts for special rules for `set-cookie`, `cookie`, and other headers.\n * @param out - The normalized headers object to modify.\n * @param lowerKey - The lowercase header key.\n * @param value - The header value to append.\n */\nfunction appendHeader(out: NormalizedHeaders, lowerKey: string, value: string): void {\n value = value.replace(/[\\r\\n]/g, \"\");\n if (SINGLE_VALUE_HEADERS[lowerKey] === 1) {\n out[lowerKey] = value;\n return;\n }\n\n const existing = out[lowerKey];\n\n if (existing === undefined) {\n out[lowerKey] = lowerKey === \"set-cookie\" ? [value] : value;\n return;\n }\n\n if (lowerKey === \"set-cookie\") {\n if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n out[lowerKey] = [existing, value];\n }\n return;\n }\n\n if (lowerKey === \"cookie\" || lowerKey === \"cookie2\") {\n out[lowerKey] = existing + \"; \" + value;\n return;\n }\n\n out[lowerKey] = existing + \", \" + value;\n}\n\n/**\n * @ru \u0414\u043E\u0431\u0430\u0432\u043B\u044F\u0435\u0442 \u0441\u044B\u0440\u043E\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430 \u043A \u043D\u043E\u0440\u043C\u0430\u043B\u0438\u0437\u043E\u0432\u0430\u043D\u043D\u043E\u043C\u0443 \u043E\u0431\u044A\u0435\u043A\u0442\u0443.\n * \u041E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u0435\u0442 \u043C\u0430\u0441\u0441\u0438\u0432\u044B \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 \u0438 \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043D\u0435\u0441\u0442\u0440\u043E\u043A\u043E\u0432\u044B\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u0432 \u0441\u0442\u0440\u043E\u043A\u0438.\n * @en Appends a raw header value to the normalized headers object.\n * Handles arrays of values and converts non-string values to strings.\n * @param out - The normalized headers object to modify.\n * @param lower - The lowercase header key.\n * @param raw - The raw header value (string, array, or other).\n */\nfunction appendRawValue(out: NormalizedHeaders, lower: string, raw: unknown): void {\n if (raw === undefined || raw === null) return;\n\n if (Array.isArray(raw)) {\n const len = raw.length;\n for (let i = 0; i < len; i++) {\n const item = raw[i];\n if (item !== undefined && item !== null) {\n appendHeader(out, lower, typeof item === \"string\" ? item : String(item));\n }\n }\n return;\n }\n\n appendHeader(out, lower, typeof raw === \"string\" ? raw : String(raw));\n}\n\n/**\n * @ru \u041D\u043E\u0440\u043C\u0430\u043B\u0438\u0437\u0443\u0435\u0442 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0438 \u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u0432 \u0435\u0434\u0438\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 \u0441 \u043A\u043B\u044E\u0447\u0430\u043C\u0438 \u0432 \u043D\u0438\u0436\u043D\u0435\u043C \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435.\n * \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0437\u043B\u0438\u0447\u043D\u044B\u0435 \u0432\u0445\u043E\u0434\u043D\u044B\u0435 \u0444\u043E\u0440\u043C\u0430\u0442\u044B: \u043E\u0431\u044A\u0435\u043A\u0442, \u043C\u0430\u0441\u0441\u0438\u0432 \u043F\u0430\u0440, \u043F\u043B\u043E\u0441\u043A\u0438\u0439 \u043C\u0430\u0441\u0441\u0438\u0432.\n *\n * \u0421\u043F\u0435\u0446\u0438\u0430\u043B\u044C\u043D\u044B\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u0430:\n * - `set-cookie` \u0432\u0441\u0435\u0433\u0434\u0430 \u0445\u0440\u0430\u043D\u0438\u0442\u0441\u044F \u043A\u0430\u043A \u043C\u0430\u0441\u0441\u0438\u0432\n * - `cookie`/`cookie2` \u043E\u0431\u044A\u0435\u0434\u0438\u043D\u044F\u044E\u0442\u0441\u044F \u0447\u0435\u0440\u0435\u0437 `; `\n * - \u041E\u0441\u0442\u0430\u043B\u044C\u043D\u044B\u0435 \u043C\u043D\u043E\u0436\u0435\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0438 \u043E\u0431\u044A\u0435\u0434\u0438\u043D\u044F\u044E\u0442\u0441\u044F \u0447\u0435\u0440\u0435\u0437 `, `\n * - \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0438 \u0438\u0437 SINGLE_VALUE_HEADERS \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0438\u0441\u044B\u0432\u0430\u044E\u0442\u0441\u044F (\u043D\u0435 \u043E\u0431\u044A\u0435\u0434\u0438\u043D\u044F\u044E\u0442\u0441\u044F)\n *\n * @en Normalizes request headers into a unified format with lowercase keys.\n * Supports various input formats: object, array of pairs, flat array.\n *\n * Special rules:\n * - `set-cookie` is always stored as an array\n * - `cookie`/`cookie2` are joined with `; `\n * - Other multiple headers are joined with `, `\n * - Headers from SINGLE_VALUE_HEADERS are overwritten (not merged)\n *\n * @param headers - The headers to normalize (object, array of pairs, or flat array).\n * @returns Normalized headers object with lowercase keys.\n */\nexport function normalizeHeaders(headers: unknown): NormalizedHeaders {\n const out: NormalizedHeaders = Object.create(null);\n if (!headers || typeof headers !== \"object\") return out;\n\n if (!Array.isArray(headers)) {\n for (const key in headers) {\n const val = (headers as Record<string, unknown>)[key];\n if (val !== undefined && val !== null) {\n appendRawValue(out, fastLowercaseKey(key), val);\n }\n }\n return out;\n }\n\n const len = headers.length;\n if (len === 0) return out;\n\n if (Array.isArray(headers[0])) {\n for (let i = 0; i < len; i++) {\n const pair = headers[i];\n if (!Array.isArray(pair)) continue;\n\n const key = pair[0];\n if (typeof key !== \"string\" || key.length === 0) continue;\n\n const rawValue = pair[1];\n if (rawValue === undefined || rawValue === null) continue;\n\n appendHeader(\n out,\n fastLowercaseKey(key),\n typeof rawValue === \"string\" ? rawValue : String(rawValue),\n );\n }\n } else {\n for (let i = 0; i < len; i += 2) {\n const key = headers[i];\n if (typeof key !== \"string\" || key.length === 0) continue;\n\n const rawValue = headers[i + 1];\n if (rawValue === undefined || rawValue === null) continue;\n\n appendHeader(\n out,\n fastLowercaseKey(key),\n typeof rawValue === \"string\" ? rawValue : String(rawValue),\n );\n }\n }\n\n return out;\n}\n\n/**\n * @ru \u041D\u043E\u0440\u043C\u0430\u043B\u0438\u0437\u0443\u0435\u0442 \u0442\u0435\u043B\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0430, \u0443\u0434\u0430\u043B\u044F\u044F \u0435\u0433\u043E \u0434\u043B\u044F \u043C\u0435\u0442\u043E\u0434\u043E\u0432 GET \u0438 HEAD.\n * @en Normalizes request body by removing it for GET and HEAD methods.\n * @param method - The HTTP method.\n * @param body - The request body data.\n * @returns The body for methods that support it, or undefined for GET/HEAD.\n */\nexport function normalizeBody(\n method: Method,\n body: RequestBodyData | undefined,\n): RequestBodyData | undefined {\n return method === \"GET\" || method === \"HEAD\" ? undefined : body;\n}\n\nfunction getContentType(\n headers: Record<string, string | string[]>,\n): string | undefined {\n const ct = headers[\"content-type\"];\n if (typeof ct === \"string\") return ct;\n if (Array.isArray(ct)) return ct[0];\n return undefined;\n}\n\n/**\n * @ru \u0421\u0435\u0440\u0438\u0430\u043B\u0438\u0437\u0443\u0435\u0442 \u0442\u0435\u043B\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u0434\u043B\u044F \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430: plain objects \u2192 JSON,\n * URLSearchParams \u2192 string, pass-through \u0434\u043B\u044F \u043E\u0441\u0442\u0430\u043B\u044C\u043D\u044B\u0445 \u0442\u0438\u043F\u043E\u0432.\n * \u041C\u0443\u0442\u0438\u0440\u0443\u0435\u0442 headers, \u0432\u044B\u0441\u0442\u0430\u0432\u043B\u044F\u044F content-type \u0435\u0441\u043B\u0438 \u043D\u0435 \u0437\u0430\u0434\u0430\u043D.\n * @en Serializes request body for transport: plain objects \u2192 JSON,\n * URLSearchParams \u2192 string, pass-through for other types.\n * Mutates headers, setting content-type if not already set.\n * @param body - The request body to normalize.\n * @param headers - The request headers (mutated in place).\n * @returns The transport-ready body.\n */\nexport function normalizeBodyForTransport(\n body: RequestBodyData,\n headers: Record<string, string | string[]>,\n): RequestBodyData {\n if (body == null) return body;\n\n if (typeof URLSearchParams !== \"undefined\" && body instanceof URLSearchParams) {\n if (!getContentType(headers)) {\n headers[\"content-type\"] = \"application/x-www-form-urlencoded\";\n }\n return body.toString();\n }\n\n const isSerializableObject =\n typeof body === \"object\" &&\n body !== null &&\n !(body instanceof Uint8Array) &&\n !(body instanceof ArrayBuffer) &&\n !(typeof ArrayBuffer !== \"undefined\" && ArrayBuffer.isView?.(body)) &&\n !(typeof URLSearchParams !== \"undefined\" && body instanceof URLSearchParams) &&\n !(typeof FormData !== \"undefined\" && body instanceof FormData) &&\n !(typeof Blob !== \"undefined\" && body instanceof Blob) &&\n !(typeof ReadableStream !== \"undefined\" && body instanceof ReadableStream) &&\n !(\"pipe\" in body && typeof (body as any).pipe === \"function\");\n\n if (isSerializableObject) {\n if (!getContentType(headers)) {\n headers[\"content-type\"] = \"application/json\";\n }\n return JSON.stringify(body);\n }\n\n return body;\n}\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["
|
|
4
|
+
"sourcesContent": ["import type { Method, RequestBodyData } from \"@hyperttp/types\";\nimport { CacheManager } from \"hcacher\";\n\ntype NormalizedHeaders = Record<string, string | string[]>;\n\nconst SINGLE_VALUE_HEADERS: Record<string, 1> = Object.create(null);\nconst singleHeaders = [\n \"content-type\",\n \"content-length\",\n \"content-encoding\",\n \"content-disposition\",\n \"host\",\n \"authorization\",\n \"proxy-authorization\",\n \"user-agent\",\n \"referer\",\n \"origin\",\n \"location\",\n \"etag\",\n \"last-modified\",\n] as const;\n\nfor (let i = 0; i < singleHeaders.length; i++) {\n SINGLE_VALUE_HEADERS[singleHeaders[i]!] = 1;\n}\n\nconst HEADER_KEY_CACHE = new CacheManager<string>({ maxSize: 2048, ttl: 60_000 });\n\nconst COMMON_HEADERS = [\n \"accept\",\n \"accept-encoding\",\n \"accept-language\",\n \"authorization\",\n \"cache-control\",\n \"connection\",\n \"content-encoding\",\n \"content-length\",\n \"content-type\",\n \"cookie\",\n \"date\",\n \"etag\",\n \"host\",\n \"if-modified-since\",\n \"if-none-match\",\n \"keep-alive\",\n \"location\",\n \"origin\",\n \"pragma\",\n \"proxy-authorization\",\n \"referer\",\n \"sec-ch-ua\",\n \"server\",\n \"set-cookie\",\n \"transfer-encoding\",\n \"user-agent\",\n \"x-forwarded-for\",\n \"x-requested-with\",\n] as const;\n\nfor (let i = 0; i < COMMON_HEADERS.length; i++) {\n const lower = COMMON_HEADERS[i]!;\n HEADER_KEY_CACHE.set(lower, lower);\n}\n\nfunction fastLowercaseKey(key: string): string {\n const cached = HEADER_KEY_CACHE.get(key);\n if (cached !== undefined) return cached;\n\n const lower = key.toLowerCase();\n HEADER_KEY_CACHE.set(key, lower);\n return lower;\n}\n\n/**\n * @ru \u0418\u0437\u0432\u043B\u0435\u043A\u0430\u0435\u0442 URL \u0438\u0437 \u0437\u0430\u043F\u0440\u043E\u0441\u0430 (\u0441\u0442\u0440\u043E\u043A\u0430, \u043E\u0431\u044A\u0435\u043A\u0442 \u0441 url/_url \u0438\u043B\u0438 \u0441\u0445\u0435\u043C\u0430+\u0445\u043E\u0441\u0442+\u043F\u0443\u0442\u044C).\n * @en Extracts the URL from a request (string, object with url/_url, or scheme+host+path).\n * @param req - URL string or request-like object.\n * @returns The extracted URL string.\n */\nexport function normalizeUrl(req: unknown): string {\n if (typeof req === \"string\") return req;\n\n if (req && typeof req === \"object\") {\n const r = req as Record<string, unknown>;\n\n const url = r.url;\n if (typeof url === \"string\") return url;\n if (url != null) return String(url);\n\n const u = r._url;\n if (typeof u === \"string\") return u;\n if (u != null) return String(u);\n\n const scheme = r.scheme;\n const host = r.host;\n const path = r.path;\n\n if (typeof scheme === \"string\" && typeof host === \"string\" && typeof path === \"string\") {\n return scheme + \"://\" + host + path;\n }\n }\n\n throw new Error(\"URL missing in request\");\n}\n\nfunction hasNewline(str: string): boolean {\n const len = str.length;\n for (let i = 0; i < len; i++) {\n const code = str.charCodeAt(i);\n if (code === 10 || code === 13) return true;\n }\n return false;\n}\n\nfunction appendHeader(out: NormalizedHeaders, lowerKey: string, value: string): void {\n if (hasNewline(value)) {\n value = value.replace(/[\\r\\n]/g, \"\");\n }\n\n if (SINGLE_VALUE_HEADERS[lowerKey] === 1) {\n out[lowerKey] = value;\n return;\n }\n\n const existing = out[lowerKey];\n\n if (existing === undefined) {\n out[lowerKey] = lowerKey === \"set-cookie\" ? [value] : value;\n return;\n }\n\n if (lowerKey === \"set-cookie\") {\n if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n out[lowerKey] = [existing, value];\n }\n return;\n }\n\n if (lowerKey === \"cookie\" || lowerKey === \"cookie2\") {\n out[lowerKey] = existing + \"; \" + value;\n return;\n }\n\n out[lowerKey] = existing + \", \" + value;\n}\n\nfunction appendRawValue(out: NormalizedHeaders, lower: string, raw: unknown): void {\n if (raw === undefined || raw === null) return;\n\n if (Array.isArray(raw)) {\n const len = raw.length;\n for (let i = 0; i < len; i++) {\n const item = raw[i];\n if (item !== undefined && item !== null) {\n appendHeader(out, lower, typeof item === \"string\" ? item : String(item));\n }\n }\n return;\n }\n\n appendHeader(out, lower, typeof raw === \"string\" ? raw : String(raw));\n}\n\n/**\n * @ru \u041D\u043E\u0440\u043C\u0430\u043B\u0438\u0437\u0443\u0435\u0442 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0438 \u0432 \u043F\u043B\u043E\u0441\u043A\u0438\u0439 \u043E\u0431\u044A\u0435\u043A\u0442 \u0441 \u043D\u0438\u0436\u043D\u0438\u043C \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043E\u043C \u043A\u043B\u044E\u0447\u0435\u0439 \u0438 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u043E\u0439 \u043C\u0430\u0441\u0441\u0438\u0432\u0430/\u043F\u0430\u0440\u043D\u044B\u0445 \u0444\u043E\u0440\u043C\u0430\u0442\u043E\u0432.\n * @en Normalizes headers into a flat object with lowercased keys, handling array/pair formats.\n * @param headers - Headers in any supported format (object, array of pairs, flat array).\n * @param out - Optional output object (reused for pooling).\n * @returns Normalized headers object.\n */\nexport function normalizeHeaders(\n headers: unknown,\n out: NormalizedHeaders = Object.create(null),\n): NormalizedHeaders {\n if (!headers || typeof headers !== \"object\") return out;\n\n if (!Array.isArray(headers)) {\n for (const key in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, key)) {\n const val = (headers as Record<string, unknown>)[key];\n if (val !== undefined && val !== null) {\n appendRawValue(out, fastLowercaseKey(key), val);\n }\n }\n }\n return out;\n }\n\n const len = headers.length;\n if (len === 0) return out;\n\n if (Array.isArray(headers[0])) {\n for (let i = 0; i < len; i++) {\n const pair = headers[i];\n if (!Array.isArray(pair)) continue;\n\n const key = pair[0];\n if (typeof key !== \"string\" || key.length === 0) continue;\n\n const rawValue = pair[1];\n if (rawValue === undefined || rawValue === null) continue;\n\n appendHeader(\n out,\n fastLowercaseKey(key),\n typeof rawValue === \"string\" ? rawValue : String(rawValue),\n );\n }\n } else {\n for (let i = 0; i < len; i += 2) {\n const key = headers[i];\n if (typeof key !== \"string\" || key.length === 0) continue;\n\n const rawValue = headers[i + 1];\n if (rawValue === undefined || rawValue === null) continue;\n\n appendHeader(\n out,\n fastLowercaseKey(key),\n typeof rawValue === \"string\" ? rawValue : String(rawValue),\n );\n }\n }\n\n return out;\n}\n\n/**\n * @ru \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 undefined \u0434\u043B\u044F GET/HEAD (\u0442\u0435\u043B\u043E \u0437\u0430\u043F\u0440\u0435\u0449\u0435\u043D\u043E), \u0438\u043D\u0430\u0447\u0435 \u0442\u0435\u043B\u043E \u043A\u0430\u043A \u0435\u0441\u0442\u044C.\n * @en Returns undefined for GET/HEAD (body disallowed), otherwise the body as-is.\n * @param method - HTTP method.\n * @param body - Request body.\n * @returns Normalized body or undefined.\n */\nexport function normalizeBody(\n method: Method,\n body: RequestBodyData | undefined,\n): RequestBodyData | undefined {\n return method === \"GET\" || method === \"HEAD\" ? undefined : body;\n}\n\nfunction getContentType(headers: Record<string, string | string[]>): string | undefined {\n const ct = headers[\"content-type\"];\n if (typeof ct === \"string\") return ct;\n if (Array.isArray(ct)) return ct[0];\n return undefined;\n}\n\n/**\n * @ru \u041F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0442\u0435\u043B\u043E \u0434\u043B\u044F \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430: \u0441\u0435\u0440\u0438\u0430\u043B\u0438\u0437\u0443\u0435\u0442 \u043E\u0431\u044A\u0435\u043A\u0442\u044B \u0432 JSON, URLSearchParams \u0432 \u0441\u0442\u0440\u043E\u043A\u0443, \u043F\u0440\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u0442 Content-Type.\n * @en Transforms body for transport: serializes objects to JSON, URLSearchParams to string, sets Content-Type.\n * @param body - Request body.\n * @param headers - Headers object (may be mutated to add Content-Type).\n * @returns Body ready for transport.\n */\nexport function normalizeBodyForTransport(\n body: RequestBodyData,\n headers: Record<string, string | string[]>,\n): RequestBodyData {\n if (body == null) return body;\n\n if (typeof URLSearchParams !== \"undefined\" && body instanceof URLSearchParams) {\n if (!getContentType(headers)) {\n headers[\"content-type\"] = \"application/x-www-form-urlencoded\";\n }\n return body.toString();\n }\n\n const isSerializableObject =\n typeof body === \"object\" &&\n body !== null &&\n !(body instanceof Uint8Array) &&\n !(body instanceof ArrayBuffer) &&\n !(typeof ArrayBuffer !== \"undefined\" && ArrayBuffer.isView?.(body)) &&\n !(typeof URLSearchParams !== \"undefined\" && body instanceof URLSearchParams) &&\n !(typeof FormData !== \"undefined\" && body instanceof FormData) &&\n !(typeof Blob !== \"undefined\" && body instanceof Blob) &&\n !(typeof ReadableStream !== \"undefined\" && body instanceof ReadableStream) &&\n !(\"pipe\" in body && typeof (body as any).pipe === \"function\");\n\n if (isSerializableObject) {\n if (!getContentType(headers)) {\n headers[\"content-type\"] = \"application/json\";\n }\n return JSON.stringify(body);\n }\n\n return body;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["CacheManager", "SINGLE_VALUE_HEADERS", "singleHeaders", "i", "HEADER_KEY_CACHE", "COMMON_HEADERS", "lower", "fastLowercaseKey", "key", "cached", "req", "r", "url", "u", "scheme", "host", "path", "hasNewline", "str", "len", "code", "appendHeader", "out", "lowerKey", "value", "existing", "appendRawValue", "raw", "item", "headers", "val", "pair", "rawValue", "method", "body", "getContentType", "ct"]
|
|
7
7
|
}
|
package/utils/response.d.ts
CHANGED
|
@@ -1,102 +1,99 @@
|
|
|
1
1
|
import type { HttpResponse, HyperTransport, HyperBody } from "@hyperttp/types";
|
|
2
2
|
type TransportResponse = Awaited<ReturnType<HyperTransport["execute"]>>;
|
|
3
|
+
declare const RAW_CACHE: unique symbol;
|
|
3
4
|
declare const TEXT_CACHE: unique symbol;
|
|
4
5
|
declare const JSON_CACHE: unique symbol;
|
|
5
|
-
declare const ARRAY_BUFFER_CACHE: unique symbol;
|
|
6
6
|
type CacheHolder = {
|
|
7
|
+
[RAW_CACHE]?: Uint8Array;
|
|
7
8
|
[TEXT_CACHE]?: string;
|
|
8
9
|
[JSON_CACHE]?: unknown;
|
|
9
|
-
[ARRAY_BUFFER_CACHE]?: ArrayBuffer | SharedArrayBuffer;
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
|
-
* @ru
|
|
13
|
-
*
|
|
14
|
-
* @
|
|
15
|
-
*
|
|
16
|
-
* @template T - The type of the body.
|
|
17
|
-
* @param body - The body to clone.
|
|
18
|
-
* @returns The cloned body.
|
|
12
|
+
* @ru Быстрое клонирование тела ответа с поддержкой structuredClone, JSON и ручного копирования.
|
|
13
|
+
* @en Fast response body clone supporting structuredClone, JSON, and manual copy.
|
|
14
|
+
* @param body - The body value to clone.
|
|
15
|
+
* @returns Cloned body.
|
|
19
16
|
*/
|
|
20
17
|
export declare const cloneBodyFast: <T>(body: T) => T;
|
|
21
18
|
/**
|
|
22
|
-
* @ru
|
|
23
|
-
*
|
|
24
|
-
* @en High-performance HTTP response container with lazy parsing and caching.
|
|
25
|
-
* Guarantees identical response body reading API across all runtimes.
|
|
26
|
-
* @template T - Expected type of the parsed response body.
|
|
19
|
+
* @ru Реализация HttpResponse с ленивым потреблением тела, кэшированием raw/text/json и поддержкой пулинга.
|
|
20
|
+
* @en HttpResponse implementation with lazy body consumption, raw/text/json caching, and pooling support.
|
|
27
21
|
*/
|
|
28
22
|
export declare class HyperHttpResponse<T = unknown> implements HttpResponse<T>, CacheHolder {
|
|
29
23
|
status: number;
|
|
30
24
|
headers: Record<string, string | string[]>;
|
|
31
|
-
/**
|
|
32
|
-
* @ru Тело ответа. Может быть распарсенным типом T, потоком HyperBody, буфером Uint8Array или null.
|
|
33
|
-
* @en Response body. Can be the parsed type T, a HyperBody stream, Uint8Array buffer, or null.
|
|
34
|
-
*/
|
|
35
25
|
body: T | HyperBody | Uint8Array | null;
|
|
36
26
|
url: string;
|
|
37
27
|
data: T | null;
|
|
28
|
+
[RAW_CACHE]: Uint8Array | undefined;
|
|
38
29
|
[TEXT_CACHE]: string | undefined;
|
|
39
30
|
[JSON_CACHE]: unknown | undefined;
|
|
40
|
-
[ARRAY_BUFFER_CACHE]: ArrayBuffer | SharedArrayBuffer | undefined;
|
|
41
31
|
private _bodyConsumed;
|
|
42
32
|
private _raw;
|
|
33
|
+
constructor(rawResponse?: TransportResponse);
|
|
43
34
|
/**
|
|
44
|
-
* @ru
|
|
45
|
-
* @en
|
|
46
|
-
* @param rawResponse - The raw
|
|
47
|
-
|
|
48
|
-
constructor(rawResponse: TransportResponse);
|
|
49
|
-
/**
|
|
50
|
-
* @ru Лениво вычитывает и кэширует тело ответа в виде ArrayBuffer и текста.
|
|
51
|
-
* @en Lazily consumes and caches the response body as ArrayBuffer and text.
|
|
35
|
+
* @ru Инициализирует ответ из транспортного ответа. Сбрасывает все кэши.
|
|
36
|
+
* @en Initializes the response from a transport response. Resets all caches.
|
|
37
|
+
* @param rawResponse - The raw transport response.
|
|
38
|
+
* @returns This instance for chaining.
|
|
52
39
|
*/
|
|
40
|
+
init(rawResponse: TransportResponse): this;
|
|
53
41
|
private _consumeBody;
|
|
54
42
|
/**
|
|
55
|
-
* @ru Возвращает тело ответа как ArrayBuffer
|
|
56
|
-
* @en Returns the response body as
|
|
57
|
-
* @returns Promise resolving to
|
|
43
|
+
* @ru Возвращает тело ответа как ArrayBuffer, потребляя его при необходимости.
|
|
44
|
+
* @en Returns the response body as ArrayBuffer, consuming it if necessary.
|
|
45
|
+
* @returns Promise resolving to an ArrayBuffer.
|
|
58
46
|
*/
|
|
59
|
-
arrayBuffer(): Promise<ArrayBuffer
|
|
47
|
+
arrayBuffer(): Promise<ArrayBuffer>;
|
|
60
48
|
/**
|
|
61
|
-
* @ru Возвращает тело ответа как
|
|
62
|
-
* @en Returns the response body as text
|
|
63
|
-
* @returns Promise resolving to the text
|
|
49
|
+
* @ru Возвращает тело ответа как строку с кэшированием.
|
|
50
|
+
* @en Returns the response body as text with caching.
|
|
51
|
+
* @returns Promise resolving to the decoded text.
|
|
64
52
|
*/
|
|
65
53
|
text(): Promise<string>;
|
|
66
54
|
/**
|
|
67
|
-
* @ru
|
|
68
|
-
* @en
|
|
69
|
-
* @
|
|
70
|
-
* @returns Promise resolving to the parsed JSON object.
|
|
55
|
+
* @ru Возвращает тело ответа, разобранное как JSON. Для объектов возвращает их напрямую (без потребления).
|
|
56
|
+
* @en Returns the response body parsed as JSON. Returns objects directly (no consumption).
|
|
57
|
+
* @returns Promise resolving to the parsed JSON value.
|
|
71
58
|
*/
|
|
72
59
|
json<TJson = T>(): Promise<TJson>;
|
|
73
60
|
/**
|
|
74
|
-
* @ru
|
|
75
|
-
* @en
|
|
76
|
-
|
|
61
|
+
* @ru Полный сброс состояния для переиспользования в пуле. Очищает все кэши и приватные поля.
|
|
62
|
+
* @en Full state reset for pool reuse. Clears all caches and private fields.
|
|
63
|
+
*/
|
|
64
|
+
reset(): void;
|
|
65
|
+
/**
|
|
66
|
+
* @ru Сбрасывает тело ответа (для стримов — отменяет/cancel).
|
|
67
|
+
* @en Discards the response body (cancels streams).
|
|
68
|
+
* @returns Promise that resolves when the body is discarded.
|
|
77
69
|
*/
|
|
78
70
|
dump(): Promise<void>;
|
|
79
71
|
/**
|
|
80
|
-
* @ru
|
|
81
|
-
*
|
|
82
|
-
* @
|
|
83
|
-
* Uses tee() for streams to safely duplicate the flow.
|
|
84
|
-
* @returns A new HttpResponse instance with cloned data.
|
|
72
|
+
* @ru Клонирует ответ с разделением стримов через tee().
|
|
73
|
+
* @en Clones the response, splitting streams via tee().
|
|
74
|
+
* @returns A new HttpResponse instance.
|
|
85
75
|
*/
|
|
86
76
|
clone(): HttpResponse<T>;
|
|
87
77
|
}
|
|
78
|
+
export declare const responsePool: HyperHttpResponse<any>[];
|
|
88
79
|
/**
|
|
89
|
-
* @ru
|
|
90
|
-
* @en
|
|
80
|
+
* @ru Создаёт HttpResponse из транспортного ответа с переиспользованием пула.
|
|
81
|
+
* @en Creates an HttpResponse from a transport response reusing the pool.
|
|
91
82
|
* @param rawResponse - The raw transport response.
|
|
92
|
-
* @returns
|
|
83
|
+
* @returns An HttpResponse instance.
|
|
93
84
|
*/
|
|
94
85
|
export declare const mapResponseFast: (rawResponse: TransportResponse) => HttpResponse<unknown>;
|
|
95
86
|
/**
|
|
96
|
-
* @ru
|
|
97
|
-
* @en
|
|
87
|
+
* @ru Возвращает HttpResponse в пул переиспользования.
|
|
88
|
+
* @en Returns an HttpResponse to the reuse pool.
|
|
89
|
+
* @param res - The response to recycle.
|
|
90
|
+
*/
|
|
91
|
+
export declare const recycleResponse: (res: HttpResponse<unknown>) => void;
|
|
92
|
+
/**
|
|
93
|
+
* @ru Создаёт StreamResponse без потребления тела.
|
|
94
|
+
* @en Creates a StreamResponse without consuming the body.
|
|
98
95
|
* @param rawResponse - The raw transport response.
|
|
99
|
-
* @returns A
|
|
96
|
+
* @returns A StreamResponse-like object.
|
|
100
97
|
*/
|
|
101
98
|
export declare const mapStreamFast: (rawResponse: TransportResponse) => {
|
|
102
99
|
status: number;
|
|
@@ -105,13 +102,11 @@ export declare const mapStreamFast: (rawResponse: TransportResponse) => {
|
|
|
105
102
|
url: string;
|
|
106
103
|
};
|
|
107
104
|
/**
|
|
108
|
-
* @ru
|
|
109
|
-
*
|
|
110
|
-
* @
|
|
111
|
-
*
|
|
112
|
-
* @
|
|
113
|
-
* @param override - Headers to override or add.
|
|
114
|
-
* @returns Merged headers object.
|
|
105
|
+
* @ru Быстрое слияние заголовков с мутацией базового объекта.
|
|
106
|
+
* @en Fast header merge mutating the base object.
|
|
107
|
+
* @param base - Base headers object (mutated).
|
|
108
|
+
* @param override - Optional headers to overlay.
|
|
109
|
+
* @returns The mutated base headers object.
|
|
115
110
|
*/
|
|
116
111
|
export declare const mergeHeadersFast: (base: Record<string, string | string[]>, override?: Record<string, string | string[]>) => Record<string, string | string[]>;
|
|
117
112
|
export {};
|
package/utils/response.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG/E,KAAK,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG/E,KAAK,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAaxE,QAAA,MAAM,SAAS,eAA8B,CAAC;AAC9C,QAAA,MAAM,UAAU,eAA+B,CAAC;AAChD,QAAA,MAAM,UAAU,eAA+B,CAAC;AAEhD,KAAK,WAAW,GAAG;IACjB,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC;IACzB,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC;IACtB,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAmBF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,QAAQ,CAAC,KAAG,CAsC1C,CAAC;AAEF;;;GAGG;AACH,qBAAa,iBAAiB,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,YAAY,CAAC,CAAC,CAAC,EAAE,WAAW;IAC1E,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC5C,IAAI,EAAG,CAAC,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI,CAAC;IACzC,GAAG,EAAG,MAAM,CAAC;IACb,IAAI,EAAG,CAAC,GAAG,IAAI,CAAC;IAEhB,CAAC,SAAS,CAAC,EAAG,UAAU,GAAG,SAAS,CAAC;IACrC,CAAC,UAAU,CAAC,EAAG,MAAM,GAAG,SAAS,CAAC;IAClC,CAAC,UAAU,CAAC,EAAG,OAAO,GAAG,SAAS,CAAC;IAE1C,OAAO,CAAC,aAAa,CAAW;IAChC,OAAO,CAAC,IAAI,CAAiC;IAE7C,YAAY,WAAW,CAAC,EAAE,iBAAiB,EAY1C;IAED;;;;;OAKG;IACI,IAAI,CAAC,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAYhD;YAEa,YAAY;IAuD1B;;;;OAIG;IACU,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAM/C;IAED;;;;OAIG;IACU,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAQnC;IAED;;;;OAIG;IACU,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,OAAO,CAAC,KAAK,CAAC,CAuB7C;IAED;;;OAGG;IACI,KAAK,IAAI,IAAI,CAWnB;IAED;;;;OAIG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAUjC;IAED;;;;OAIG;IACI,KAAK,IAAI,YAAY,CAAC,CAAC,CAAC,CA0B9B;CACF;AAED,eAAO,MAAM,YAAY,EAAE,iBAAiB,CAAC,GAAG,CAAC,EAAO,CAAC;AAGzD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,gBAAiB,iBAAiB,KAAG,YAAY,CAAC,OAAO,CAGpF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAS,YAAY,CAAC,OAAO,CAAC,KAAG,IAK5D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,gBAAiB,iBAAiB;IAC1D,MAAM;IACN,OAAO;IACP,IAAI;IACJ,GAAG;CACH,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,SACrB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,aAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,KAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBlC,CAAC"}
|
package/utils/response.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";import{CURRENT_RUNTIME as
|
|
1
|
+
"use strict";import{CURRENT_RUNTIME as c}from"../transports/manager.js";const s=Symbol("hyperttp.rawCache"),i=Symbol("hyperttp.textCache"),a=Symbol("hyperttp.jsonCache"),f=new TextDecoder,y=new TextEncoder,d=Object.freeze({});function u(e){return typeof e=="object"&&e!==null&&"getReader"in e&&typeof e.getReader=="function"}function h(e){return typeof Blob<"u"&&e instanceof Blob}export const cloneBodyFast=e=>{if(typeof e!="object"||e===null)return e;const t=e;if(e instanceof Uint8Array||typeof t.pipe=="function"||typeof t.getReader=="function")return e;const r=Object.getPrototypeOf(e);if(r===Object.prototype||r===null){const n=Object.create(r);for(const o in e)Object.prototype.hasOwnProperty.call(e,o)&&(n[o]=e[o]);return n}try{return structuredClone(e)}catch{try{return JSON.parse(JSON.stringify(e))}catch{const n=Object.create(r);for(const o in e)Object.prototype.hasOwnProperty.call(e,o)&&(n[o]=e[o]);return n}}};export class HyperHttpResponse{status;headers;body;url;data;[s];[i];[a];_bodyConsumed;_raw;constructor(t){this.status=0,this.headers=d,this.body=null,this.url="",this.data=null,this[s]=void 0,this[i]=void 0,this[a]=void 0,this._bodyConsumed=!1,this._raw=void 0,t&&this.init(t)}init(t){return this.status=t.status,this.headers=t.headers||d,this.body=t.body,this.url=t.url??"",this.data=null,this[s]=void 0,this[i]=void 0,this[a]=void 0,this._bodyConsumed=!1,this._raw=t._raw,this}async _consumeBody(){if(this[s]!==void 0)return;const t=this.body;if(t){if(t instanceof Uint8Array){this[s]=t,this._bodyConsumed=!0;return}if(typeof t=="string"){this[s]=y.encode(t),this._bodyConsumed=!0;return}if(t instanceof ArrayBuffer){this[s]=new Uint8Array(t),this._bodyConsumed=!0;return}if(this._raw&&t===this._raw.body&&typeof this._raw.arrayBuffer=="function"){const r=await this._raw.arrayBuffer();this[s]=new Uint8Array(r),this.body=this[s],this._bodyConsumed=!0;return}if(c==="bun"&&t&&typeof t=="object"&&"arrayBuffer"in t){const r=t;if(typeof r.arrayBuffer=="function"){const n=await r.arrayBuffer();this[s]=new Uint8Array(n),this.body=this[s],this._bodyConsumed=!0;return}}if(u(t)||h(t)){if(u(t)&&t.locked)throw new Error("[Hyperttp] Stream is locked.");const n=await new Response(t).arrayBuffer();this[s]=new Uint8Array(n),this.body=this[s],this._bodyConsumed=!0}}}async arrayBuffer(){if(await this._consumeBody(),this[s]===void 0)throw new Error("[Hyperttp] Response body is not available as ArrayBuffer");return this[s].buffer}async text(){if(this[i]!==void 0)return this[i];if(await this._consumeBody(),this[s]===void 0)throw new Error("[Hyperttp] Response body is not available as text");return this[i]=f.decode(this[s]),this[i]}async json(){const t=this.body;if(!this._bodyConsumed&&typeof t=="object"&&t!==null&&!u(t)&&!h(t)&&!(t instanceof Uint8Array)&&!(t instanceof ArrayBuffer))return this._bodyConsumed=!0,t;if(await this._consumeBody(),this[s]===void 0)throw new Error("[Hyperttp] Response body is not available as JSON");return this[i]===void 0&&(this[i]=f.decode(this[s])),JSON.parse(this[i])}reset(){this.status=0,this.headers=d,this.body=null,this.url="",this.data=null,this[s]=void 0,this[i]=void 0,this[a]=void 0,this._bodyConsumed=!1,this._raw=void 0}async dump(){if(this._bodyConsumed)return;this._bodyConsumed=!0;const t=this.body;u(t)?t.locked||await t.cancel().catch(()=>{}):h(t)&&await t.arrayBuffer()}clone(){const t=new HyperHttpResponse;if(t.status=this.status,t.headers=this.headers,t.url=this.url,t.data=this.data?cloneBodyFast(this.data):null,t._bodyConsumed=this._bodyConsumed,t._raw=this._bodyConsumed?void 0:this._raw,t[s]=this[s],t[i]=this[i],t[a]=this[a],u(this.body)&&!this._bodyConsumed)if(this.body.locked)t.body=this.body;else{const[r,n]=this.body.tee();this.body=r,t.body=n}else t.body=this.body;return t}}export const responsePool=[];const l=64;export const mapResponseFast=e=>(responsePool.pop()??new HyperHttpResponse).init(e),recycleResponse=e=>{e instanceof HyperHttpResponse&&responsePool.length<l&&(e.reset(),responsePool.push(e))},mapStreamFast=e=>({status:e.status,headers:e.headers,body:e.body,url:e.url??""}),mergeHeadersFast=(e,t)=>{if(!t)return e;let r=!1;for(const n in t){r=!0;break}if(!r)return e;for(const n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e};
|
|
2
2
|
//# sourceMappingURL=response.js.map
|
package/utils/response.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/response.ts"],
|
|
4
|
-
"sourcesContent": ["import type { HttpResponse, HyperTransport, HyperBody } from \"@hyperttp/types\";\nimport { CURRENT_RUNTIME } from \"../transports/manager.js\";\n\ntype TransportResponse = Awaited<ReturnType<HyperTransport[\"execute\"]>>;\n\n/**\n * @ru \u0418\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u043D\u043E\u0433\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430, \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0441\u043A\u0440\u044B\u0442\u0443\u044E \u0441\u0441\u044B\u043B\u043A\u0443 \u043D\u0430 \u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0439 \u0441\u0435\u0442\u0435\u0432\u043E\u0439 \u0438\u043D\u0441\u0442\u0430\u043D\u0441.\n * @en Interface for extended transport response containing a hidden reference to the native network instance.\n */\ninterface InternalTransportResponse extends TransportResponse {\n _raw?: FetchResponseLike;\n}\n\n/**\n * @ru \u0418\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0443\u0442\u0438\u043D\u043E\u0439 \u0442\u0438\u043F\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043B\u044F \u043D\u0430\u0442\u0438\u0432\u043D\u043E\u0433\u043E \u043E\u0442\u0432\u0435\u0442\u0430 Fetch API \u0438\u043B\u0438 Bun-\u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u043E\u0433\u043E \u0442\u0435\u043B\u0430.\n * @en Duck-typing interface for native Fetch API response or Bun-compatible body.\n */\ninterface FetchResponseLike {\n body: unknown;\n arrayBuffer(): Promise<ArrayBuffer>;\n text(): Promise<string>;\n json(): Promise<unknown>;\n}\n\n\n\nconst TEXT_CACHE = Symbol(\"hyperttp.textCache\");\nconst JSON_CACHE = Symbol(\"hyperttp.jsonCache\");\nconst ARRAY_BUFFER_CACHE = Symbol(\"hyperttp.arrayBufferCache\");\n\ntype CacheHolder = {\n [TEXT_CACHE]?: string;\n [JSON_CACHE]?: unknown;\n [ARRAY_BUFFER_CACHE]?: ArrayBuffer | SharedArrayBuffer;\n};\n\nconst STATIC_DECODER = new TextDecoder();\n\n/**\n * @ru \u0417\u0430\u043C\u043E\u0440\u043E\u0436\u0435\u043D\u043D\u044B\u0439 \u043F\u0443\u0441\u0442\u043E\u0439 \u043E\u0431\u044A\u0435\u043A\u0442 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432 \u0434\u043B\u044F \u0438\u0437\u0431\u0435\u0436\u0430\u043D\u0438\u044F \u043B\u0438\u0448\u043D\u0438\u0445 \u0430\u043B\u043B\u043E\u043A\u0430\u0446\u0438\u0439.\n * @en Frozen empty headers object to avoid redundant allocations.\n */\nconst EMPTY_HEADERS: Readonly<Record<string, never>> = Object.freeze({});\n\n/**\n * @ru \u0411\u044B\u0441\u0442\u0440\u0430\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430, \u044F\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u043B\u0438 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 ReadableStream.\n * @en Fast check to determine if a value is a ReadableStream.\n * @param value - The value to check.\n * @returns True if the value is a ReadableStream.\n */\nfunction isReadableStream(value: unknown): value is ReadableStream<Uint8Array> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"getReader\" in value &&\n typeof (value as Record<string, unknown>).getReader === \"function\"\n );\n}\n\n/**\n * @ru \u0411\u044B\u0441\u0442\u0440\u0430\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430, \u044F\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u043B\u0438 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 Blob.\n * @en Fast check to determine if a value is a Blob.\n * @param value - The value to check.\n * @returns True if the value is a Blob.\n */\nfunction isBlob(value: unknown): value is Blob {\n return typeof Blob !== \"undefined\" && value instanceof Blob;\n}\n\n/**\n * @ru \u0412\u044B\u0441\u043E\u043A\u043E\u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u0433\u043B\u0443\u0431\u043E\u043A\u043E\u0435 \u043A\u043B\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u0442\u0435\u043B\u0430 \u043E\u0442\u0432\u0435\u0442\u0430.\n * \u0418\u0437\u0431\u0435\u0433\u0430\u0435\u0442 \u043D\u0430\u043A\u043B\u0430\u0434\u043D\u044B\u0445 \u0440\u0430\u0441\u0445\u043E\u0434\u043E\u0432 structuredClone \u0434\u043B\u044F \u043F\u0440\u043E\u0441\u0442\u044B\u0445 \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432.\n * @en High-performance deep cloning of the response body.\n * Avoids structuredClone overhead for simple objects.\n * @template T - The type of the body.\n * @param body - The body to clone.\n * @returns The cloned body.\n */\nexport const cloneBodyFast = <T>(body: T): T => {\n if (typeof body !== \"object\" || body === null) return body;\n const obj = body as Record<string, unknown>;\n\n if (\n body instanceof Uint8Array ||\n typeof obj.pipe === \"function\" ||\n typeof obj.getReader === \"function\"\n ) {\n return body;\n }\n\n const proto = Object.getPrototypeOf(body);\n if (proto === Object.prototype || proto === null) {\n return { ...body } as T;\n }\n\n try {\n return structuredClone(body);\n } catch {\n try {\n return JSON.parse(JSON.stringify(body)) as T;\n } catch {\n return { ...body };\n }\n }\n};\n\n/**\n * @ru \u0412\u044B\u0441\u043E\u043A\u043E\u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439 \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440 HTTP-\u043E\u0442\u0432\u0435\u0442\u0430 \u0441 \u043B\u0435\u043D\u0438\u0432\u044B\u043C \u043F\u0430\u0440\u0441\u0438\u043D\u0433\u043E\u043C \u0438 \u043A\u044D\u0448\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435\u043C.\n * \u0413\u0430\u0440\u0430\u043D\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u0434\u0435\u043D\u0442\u0438\u0447\u043D\u044B\u0439 API \u0447\u0442\u0435\u043D\u0438\u044F \u0442\u0435\u043B\u0430 \u043E\u0442\u0432\u0435\u0442\u0430 \u0432\u043E \u0432\u0441\u0435\u0445 \u0440\u0430\u043D\u0442\u0430\u0439\u043C\u0430\u0445.\n * @en High-performance HTTP response container with lazy parsing and caching.\n * Guarantees identical response body reading API across all runtimes.\n * @template T - Expected type of the parsed response body.\n */\nexport class HyperHttpResponse<T = unknown> implements HttpResponse<T>, CacheHolder {\n public status: number;\n public headers: Record<string, string | string[]>;\n\n /**\n * @ru \u0422\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430. \u041C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u0440\u0430\u0441\u043F\u0430\u0440\u0441\u0435\u043D\u043D\u044B\u043C \u0442\u0438\u043F\u043E\u043C T, \u043F\u043E\u0442\u043E\u043A\u043E\u043C HyperBody, \u0431\u0443\u0444\u0435\u0440\u043E\u043C Uint8Array \u0438\u043B\u0438 null.\n * @en Response body. Can be the parsed type T, a HyperBody stream, Uint8Array buffer, or null.\n */\n public body: T | HyperBody | Uint8Array | null;\n\n public url: string;\n public data: T | null = null;\n\n public [TEXT_CACHE]: string | undefined = undefined;\n public [JSON_CACHE]: unknown | undefined = undefined;\n public [ARRAY_BUFFER_CACHE]: ArrayBuffer | SharedArrayBuffer | undefined = undefined;\n\n private _bodyConsumed = false;\n private _raw: FetchResponseLike | undefined;\n\n /**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0451\u0442 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440 \u043E\u0442\u0432\u0435\u0442\u0430 \u0438\u0437 \u0441\u044B\u0440\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430.\n * @en Creates a response instance from raw transport data.\n * @param rawResponse - The raw response from the transport layer.\n */\n constructor(rawResponse: TransportResponse) {\n this.status = rawResponse.status;\n this.headers = rawResponse.headers || EMPTY_HEADERS;\n this.body = rawResponse.body as T | HyperBody | Uint8Array | null;\n this.url = rawResponse.url ?? \"\";\n this._raw = (rawResponse as InternalTransportResponse)._raw;\n }\n\n /**\n * @ru \u041B\u0435\u043D\u0438\u0432\u043E \u0432\u044B\u0447\u0438\u0442\u044B\u0432\u0430\u0435\u0442 \u0438 \u043A\u044D\u0448\u0438\u0440\u0443\u0435\u0442 \u0442\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u0432 \u0432\u0438\u0434\u0435 ArrayBuffer \u0438 \u0442\u0435\u043A\u0441\u0442\u0430.\n * @en Lazily consumes and caches the response body as ArrayBuffer and text.\n */\n private async _consumeBody(): Promise<void> {\n if (this._bodyConsumed) return;\n this._bodyConsumed = true;\n\n const body = this.body;\n if (!body) return;\n\n if (typeof body === \"string\") {\n this[TEXT_CACHE] = body;\n return;\n }\n\n if (body instanceof Uint8Array) {\n this[ARRAY_BUFFER_CACHE] =\n body.buffer.byteLength === body.byteLength\n ? body.buffer\n : body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength);\n this[TEXT_CACHE] = STATIC_DECODER.decode(body);\n return;\n }\n\n if (body instanceof ArrayBuffer) {\n this[ARRAY_BUFFER_CACHE] = body;\n this[TEXT_CACHE] = STATIC_DECODER.decode(body);\n return;\n }\n\n if (this._raw && body === this._raw.body && typeof this._raw.arrayBuffer === \"function\") {\n const buf = await this._raw.arrayBuffer();\n this[ARRAY_BUFFER_CACHE] = buf;\n this[TEXT_CACHE] = STATIC_DECODER.decode(buf);\n this.body = new Uint8Array(buf) as T | HyperBody | Uint8Array | null;\n return;\n }\n\n if (CURRENT_RUNTIME === \"bun\" && body && typeof body === \"object\" && \"arrayBuffer\" in body) {\n const bunBody = body as { arrayBuffer: () => Promise<ArrayBuffer> };\n if (typeof bunBody.arrayBuffer === \"function\") {\n const buf = await bunBody.arrayBuffer();\n this[ARRAY_BUFFER_CACHE] = buf;\n this[TEXT_CACHE] = STATIC_DECODER.decode(buf);\n this.body = new Uint8Array(buf) as T | HyperBody | Uint8Array | null;\n return;\n }\n }\n\n if (isReadableStream(body) || isBlob(body)) {\n if (isReadableStream(body) && body.locked) {\n throw new Error(\"[Hyperttp] Stream is locked.\");\n }\n const response = new Response(body as unknown as BodyInit);\n const buf = await response.arrayBuffer();\n this[ARRAY_BUFFER_CACHE] = buf;\n this[TEXT_CACHE] = STATIC_DECODER.decode(buf);\n this.body = new Uint8Array(buf) as T | HyperBody | Uint8Array | null;\n }\n }\n\n /**\n * @ru \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u043A\u0430\u043A ArrayBuffer. \u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u043A\u044D\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044F.\n * @en Returns the response body as an ArrayBuffer. Result is cached.\n * @returns Promise resolving to the ArrayBuffer or SharedArrayBuffer.\n */\n public async arrayBuffer(): Promise<ArrayBuffer | SharedArrayBuffer> {\n if (this[ARRAY_BUFFER_CACHE] !== undefined) return this[ARRAY_BUFFER_CACHE]!;\n\n const body = this.body;\n if (body instanceof Uint8Array) {\n this._bodyConsumed = true;\n return (this[ARRAY_BUFFER_CACHE] =\n body.buffer.byteLength === body.byteLength\n ? body.buffer\n : body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength));\n }\n\n if (body instanceof ArrayBuffer) {\n this._bodyConsumed = true;\n return (this[ARRAY_BUFFER_CACHE] = body);\n }\n\n if (isBlob(body)) {\n this._bodyConsumed = true;\n return (this[ARRAY_BUFFER_CACHE] = await body.arrayBuffer());\n }\n\n await this._consumeBody();\n if (this[ARRAY_BUFFER_CACHE] === undefined) {\n throw new Error(\"[Hyperttp] Response body is not available as ArrayBuffer\");\n }\n return this[ARRAY_BUFFER_CACHE]!;\n }\n\n /**\n * @ru \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u043A\u0430\u043A \u0442\u0435\u043A\u0441\u0442. \u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u043A\u044D\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044F.\n * @en Returns the response body as text. Result is cached.\n * @returns Promise resolving to the text string.\n */\n public async text(): Promise<string> {\n if (this[TEXT_CACHE] !== undefined) return this[TEXT_CACHE]!;\n\n const body = this.body;\n if (typeof body === \"string\") {\n this._bodyConsumed = true;\n return (this[TEXT_CACHE] = body);\n }\n\n if (body instanceof Uint8Array) {\n this._bodyConsumed = true;\n return (this[TEXT_CACHE] = STATIC_DECODER.decode(body));\n }\n\n if (body instanceof ArrayBuffer) {\n this._bodyConsumed = true;\n return (this[TEXT_CACHE] = STATIC_DECODER.decode(body));\n }\n\n if (isBlob(body)) {\n this._bodyConsumed = true;\n return (this[TEXT_CACHE] = await body.text());\n }\n\n await this._consumeBody();\n if (this[TEXT_CACHE] === undefined) {\n throw new Error(\"[Hyperttp] Response body is not available as text\");\n }\n return this[TEXT_CACHE]!;\n }\n\n /**\n * @ru \u041F\u0430\u0440\u0441\u0438\u0442 \u0442\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u043A\u0430\u043A JSON. \u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u043A\u044D\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044F.\n * @en Parses the response body as JSON. Result is cached.\n * @template TJson - Expected type of the parsed JSON.\n * @returns Promise resolving to the parsed JSON object.\n */\n public async json<TJson = T>(): Promise<TJson> {\n if (this[JSON_CACHE] !== undefined) return this[JSON_CACHE] as TJson;\n\n if (this[TEXT_CACHE] !== undefined) {\n return (this[JSON_CACHE] = JSON.parse(this[TEXT_CACHE]!)) as TJson;\n }\n\n const body = this.body;\n if (\n typeof body === \"object\" &&\n body !== null &&\n !isReadableStream(body) &&\n !isBlob(body) &&\n !(body instanceof Uint8Array) &&\n !(body instanceof ArrayBuffer)\n ) {\n this._bodyConsumed = true;\n return (this[JSON_CACHE] = body) as TJson;\n }\n\n await this._consumeBody();\n if (this[TEXT_CACHE] !== undefined) {\n return (this[JSON_CACHE] = JSON.parse(this[TEXT_CACHE]!)) as TJson;\n }\n throw new Error(\"[Hyperttp] Response body is not available as JSON\");\n }\n\n /**\n * @ru \u041E\u0442\u0431\u0440\u0430\u0441\u044B\u0432\u0430\u0435\u0442 \u0442\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u0434\u043B\u044F \u043E\u0441\u0432\u043E\u0431\u043E\u0436\u0434\u0435\u043D\u0438\u044F \u0440\u0435\u0441\u0443\u0440\u0441\u043E\u0432 (\u0441\u043E\u043A\u0435\u0442\u0430).\n * @en Discards the response body to free up resources (socket).\n * @returns Promise that resolves when the body is drained.\n */\n public async dump(): Promise<void> {\n if (this._bodyConsumed) return;\n this._bodyConsumed = true;\n\n const body = this.body;\n if (isReadableStream(body)) {\n if (!body.locked) await body.cancel().catch(() => {});\n } else if (isBlob(body)) {\n await body.arrayBuffer();\n }\n }\n\n /**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0451\u0442 \u0433\u043B\u0443\u0431\u043E\u043A\u0443\u044E \u0438\u0437\u043E\u043B\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u0443\u044E \u043A\u043E\u043F\u0438\u044E \u043E\u0442\u0432\u0435\u0442\u0430.\n * \u0414\u043B\u044F \u0441\u0442\u0440\u0438\u043C\u043E\u0432 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442 tee() \u0434\u043B\u044F \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0433\u043E \u0440\u0430\u0437\u0434\u0432\u043E\u0435\u043D\u0438\u044F \u043F\u043E\u0442\u043E\u043A\u0430.\n * @en Creates a deep isolated copy of the response.\n * Uses tee() for streams to safely duplicate the flow.\n * @returns A new HttpResponse instance with cloned data.\n */\n public clone(): HttpResponse<T> {\n const cloned = Object.create(HyperHttpResponse.prototype) as HyperHttpResponse<T>;\n\n cloned.status = this.status;\n cloned.headers = this.headers;\n cloned.url = this.url;\n cloned.data = this.data ? cloneBodyFast(this.data) : null;\n cloned._bodyConsumed = this._bodyConsumed;\n cloned._raw = this._bodyConsumed ? undefined : this._raw;\n\n cloned[TEXT_CACHE] = this[TEXT_CACHE];\n cloned[JSON_CACHE] = this[JSON_CACHE];\n cloned[ARRAY_BUFFER_CACHE] = this[ARRAY_BUFFER_CACHE];\n\n if (isReadableStream(this.body) && !this._bodyConsumed) {\n if (this.body.locked) {\n cloned.body = this.body;\n } else {\n const [b1, b2] = this.body.tee();\n this.body = b1 as T | HyperBody | Uint8Array | null;\n cloned.body = b2 as T | HyperBody | Uint8Array | null;\n }\n } else {\n cloned.body = this.body;\n }\n\n return cloned;\n }\n}\n\n/**\n * @ru \u0411\u044B\u0441\u0442\u0440\u043E\u0435 \u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440\u0430 HyperHttpResponse \u0438\u0437 \u0441\u044B\u0440\u043E\u0433\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430.\n * @en Fast creation of a HyperHttpResponse instance from a raw transport response.\n * @param rawResponse - The raw transport response.\n * @returns A new HyperHttpResponse instance.\n */\nexport const mapResponseFast = (rawResponse: TransportResponse): HttpResponse<unknown> => {\n return new HyperHttpResponse(rawResponse);\n};\n\n/**\n * @ru \u0411\u044B\u0441\u0442\u0440\u043E\u0435 \u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u0430 StreamResponse \u0431\u0435\u0437 overhead-\u0430 \u043A\u043B\u0430\u0441\u0441\u043E\u0432.\n * @en Fast creation of a StreamResponse object without class overhead.\n * @param rawResponse - The raw transport response.\n * @returns A lightweight StreamResponse object.\n */\nexport const mapStreamFast = (rawResponse: TransportResponse) => ({\n status: rawResponse.status,\n headers: rawResponse.headers,\n body: rawResponse.body,\n url: rawResponse.url ?? \"\",\n});\n\n/**\n * @ru \u041E\u043F\u0442\u0438\u043C\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E\u0435 \u0441\u043B\u0438\u044F\u043D\u0438\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432.\n * \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442 \u0440\u0430\u043D\u043D\u0438\u0439 \u0432\u043E\u0437\u0432\u0440\u0430\u0442 \u043F\u0440\u0438 \u043F\u0435\u0440\u0432\u043E\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0446\u0438\u043A\u043B\u0430, \u0447\u0442\u043E \u0431\u044B\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043C Object.keys().length > 0.\n * @en Optimized headers merging.\n * Uses early return on the first loop iteration, which is faster than Object.keys().length > 0.\n * @param base - Base headers object.\n * @param override - Headers to override or add.\n * @returns Merged headers object.\n */\nexport const mergeHeadersFast = (\n base: Record<string, string | string[]>,\n override?: Record<string, string | string[]>,\n): Record<string, string | string[]> => {\n if (!override) return base;\n for (const _ in override) {\n return { ...base, ...override };\n }\n return base;\n};\n"],
|
|
5
|
-
"mappings": "aACA,OAAS,mBAAAA,MAAuB,
|
|
6
|
-
"names": ["CURRENT_RUNTIME", "TEXT_CACHE", "JSON_CACHE", "
|
|
4
|
+
"sourcesContent": ["import type { HttpResponse, HyperTransport, HyperBody } from \"@hyperttp/types\";\nimport { CURRENT_RUNTIME } from \"../transports/manager.js\";\n\ntype TransportResponse = Awaited<ReturnType<HyperTransport[\"execute\"]>>;\n\ninterface InternalTransportResponse extends TransportResponse {\n _raw?: FetchResponseLike;\n}\n\ninterface FetchResponseLike {\n body: unknown;\n arrayBuffer(): Promise<ArrayBuffer>;\n text(): Promise<string>;\n json(): Promise<unknown>;\n}\n\nconst RAW_CACHE = Symbol(\"hyperttp.rawCache\");\nconst TEXT_CACHE = Symbol(\"hyperttp.textCache\");\nconst JSON_CACHE = Symbol(\"hyperttp.jsonCache\");\n\ntype CacheHolder = {\n [RAW_CACHE]?: Uint8Array;\n [TEXT_CACHE]?: string;\n [JSON_CACHE]?: unknown;\n};\n\nconst STATIC_DECODER = new TextDecoder();\nconst STATIC_ENCODER = new TextEncoder();\nconst EMPTY_HEADERS: Readonly<Record<string, never>> = Object.freeze({});\n\nfunction isReadableStream(value: unknown): value is ReadableStream<Uint8Array> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"getReader\" in value &&\n typeof (value as Record<string, unknown>).getReader === \"function\"\n );\n}\n\nfunction isBlob(value: unknown): value is Blob {\n return typeof Blob !== \"undefined\" && value instanceof Blob;\n}\n\n/**\n * @ru \u0411\u044B\u0441\u0442\u0440\u043E\u0435 \u043A\u043B\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u0442\u0435\u043B\u0430 \u043E\u0442\u0432\u0435\u0442\u0430 \u0441 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u043E\u0439 structuredClone, JSON \u0438 \u0440\u0443\u0447\u043D\u043E\u0433\u043E \u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F.\n * @en Fast response body clone supporting structuredClone, JSON, and manual copy.\n * @param body - The body value to clone.\n * @returns Cloned body.\n */\nexport const cloneBodyFast = <T>(body: T): T => {\n if (typeof body !== \"object\" || body === null) return body;\n const obj = body as Record<string, unknown>;\n\n if (\n body instanceof Uint8Array ||\n typeof obj.pipe === \"function\" ||\n typeof obj.getReader === \"function\"\n ) {\n return body;\n }\n\n const proto = Object.getPrototypeOf(body);\n if (proto === Object.prototype || proto === null) {\n const target = Object.create(proto);\n for (const key in body) {\n if (Object.prototype.hasOwnProperty.call(body, key)) {\n target[key] = body[key];\n }\n }\n return target as T;\n }\n\n try {\n return structuredClone(body);\n } catch {\n try {\n return JSON.parse(JSON.stringify(body)) as T;\n } catch {\n const target = Object.create(proto);\n for (const key in body) {\n if (Object.prototype.hasOwnProperty.call(body, key)) {\n target[key] = body[key];\n }\n }\n return target as T;\n }\n }\n};\n\n/**\n * @ru \u0420\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F HttpResponse \u0441 \u043B\u0435\u043D\u0438\u0432\u044B\u043C \u043F\u043E\u0442\u0440\u0435\u0431\u043B\u0435\u043D\u0438\u0435\u043C \u0442\u0435\u043B\u0430, \u043A\u044D\u0448\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435\u043C raw/text/json \u0438 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u043E\u0439 \u043F\u0443\u043B\u0438\u043D\u0433\u0430.\n * @en HttpResponse implementation with lazy body consumption, raw/text/json caching, and pooling support.\n */\nexport class HyperHttpResponse<T = unknown> implements HttpResponse<T>, CacheHolder {\n public status!: number;\n public headers!: Record<string, string | string[]>;\n public body!: T | HyperBody | Uint8Array | null;\n public url!: string;\n public data!: T | null;\n\n public [RAW_CACHE]!: Uint8Array | undefined;\n public [TEXT_CACHE]!: string | undefined;\n public [JSON_CACHE]!: unknown | undefined;\n\n private _bodyConsumed!: boolean;\n private _raw!: FetchResponseLike | undefined;\n\n constructor(rawResponse?: TransportResponse) {\n this.status = 0;\n this.headers = EMPTY_HEADERS;\n this.body = null;\n this.url = \"\";\n this.data = null;\n this[RAW_CACHE] = undefined;\n this[TEXT_CACHE] = undefined;\n this[JSON_CACHE] = undefined;\n this._bodyConsumed = false;\n this._raw = undefined;\n if (rawResponse) this.init(rawResponse);\n }\n\n /**\n * @ru \u0418\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043E\u0442\u0432\u0435\u0442 \u0438\u0437 \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u043D\u043E\u0433\u043E \u043E\u0442\u0432\u0435\u0442\u0430. \u0421\u0431\u0440\u0430\u0441\u044B\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u043A\u044D\u0448\u0438.\n * @en Initializes the response from a transport response. Resets all caches.\n * @param rawResponse - The raw transport response.\n * @returns This instance for chaining.\n */\n public init(rawResponse: TransportResponse): this {\n this.status = rawResponse.status;\n this.headers = rawResponse.headers || EMPTY_HEADERS;\n this.body = rawResponse.body as T | HyperBody | Uint8Array | null;\n this.url = rawResponse.url ?? \"\";\n this.data = null;\n this[RAW_CACHE] = undefined;\n this[TEXT_CACHE] = undefined;\n this[JSON_CACHE] = undefined;\n this._bodyConsumed = false;\n this._raw = (rawResponse as InternalTransportResponse)._raw;\n return this;\n }\n\n private async _consumeBody(): Promise<void> {\n if (this[RAW_CACHE] !== undefined) return;\n\n const body = this.body;\n if (!body) return;\n\n if (body instanceof Uint8Array) {\n this[RAW_CACHE] = body;\n this._bodyConsumed = true;\n return;\n }\n\n if (typeof body === \"string\") {\n this[RAW_CACHE] = STATIC_ENCODER.encode(body);\n this._bodyConsumed = true;\n return;\n }\n\n if (body instanceof ArrayBuffer) {\n this[RAW_CACHE] = new Uint8Array(body);\n this._bodyConsumed = true;\n return;\n }\n\n if (this._raw && body === this._raw.body && typeof this._raw.arrayBuffer === \"function\") {\n const buf = await this._raw.arrayBuffer();\n this[RAW_CACHE] = new Uint8Array(buf);\n this.body = this[RAW_CACHE] as T | HyperBody | Uint8Array | null;\n this._bodyConsumed = true;\n return;\n }\n\n if (CURRENT_RUNTIME === \"bun\" && body && typeof body === \"object\" && \"arrayBuffer\" in body) {\n const bunBody = body as { arrayBuffer: () => Promise<ArrayBuffer> };\n if (typeof bunBody.arrayBuffer === \"function\") {\n const buf = await bunBody.arrayBuffer();\n this[RAW_CACHE] = new Uint8Array(buf);\n this.body = this[RAW_CACHE] as T | HyperBody | Uint8Array | null;\n this._bodyConsumed = true;\n return;\n }\n }\n\n if (isReadableStream(body) || isBlob(body)) {\n if (isReadableStream(body) && body.locked) {\n throw new Error(\"[Hyperttp] Stream is locked.\");\n }\n const response = new Response(body as unknown as BodyInit);\n const buf = await response.arrayBuffer();\n this[RAW_CACHE] = new Uint8Array(buf);\n this.body = this[RAW_CACHE] as T | HyperBody | Uint8Array | null;\n this._bodyConsumed = true;\n }\n }\n\n /**\n * @ru \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u043A\u0430\u043A ArrayBuffer, \u043F\u043E\u0442\u0440\u0435\u0431\u043B\u044F\u044F \u0435\u0433\u043E \u043F\u0440\u0438 \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E\u0441\u0442\u0438.\n * @en Returns the response body as ArrayBuffer, consuming it if necessary.\n * @returns Promise resolving to an ArrayBuffer.\n */\n public async arrayBuffer(): Promise<ArrayBuffer> {\n await this._consumeBody();\n if (this[RAW_CACHE] === undefined) {\n throw new Error(\"[Hyperttp] Response body is not available as ArrayBuffer\");\n }\n return this[RAW_CACHE].buffer as ArrayBuffer;\n }\n\n /**\n * @ru \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u043A\u0430\u043A \u0441\u0442\u0440\u043E\u043A\u0443 \u0441 \u043A\u044D\u0448\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435\u043C.\n * @en Returns the response body as text with caching.\n * @returns Promise resolving to the decoded text.\n */\n public async text(): Promise<string> {\n if (this[TEXT_CACHE] !== undefined) return this[TEXT_CACHE]!;\n await this._consumeBody();\n if (this[RAW_CACHE] === undefined) {\n throw new Error(\"[Hyperttp] Response body is not available as text\");\n }\n this[TEXT_CACHE] = STATIC_DECODER.decode(this[RAW_CACHE]!);\n return this[TEXT_CACHE]!;\n }\n\n /**\n * @ru \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430, \u0440\u0430\u0437\u043E\u0431\u0440\u0430\u043D\u043D\u043E\u0435 \u043A\u0430\u043A JSON. \u0414\u043B\u044F \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432 \u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0445 \u043D\u0430\u043F\u0440\u044F\u043C\u0443\u044E (\u0431\u0435\u0437 \u043F\u043E\u0442\u0440\u0435\u0431\u043B\u0435\u043D\u0438\u044F).\n * @en Returns the response body parsed as JSON. Returns objects directly (no consumption).\n * @returns Promise resolving to the parsed JSON value.\n */\n public async json<TJson = T>(): Promise<TJson> {\n const body = this.body;\n if (\n !this._bodyConsumed &&\n typeof body === \"object\" &&\n body !== null &&\n !isReadableStream(body) &&\n !isBlob(body) &&\n !(body instanceof Uint8Array) &&\n !(body instanceof ArrayBuffer)\n ) {\n this._bodyConsumed = true;\n return body as TJson;\n }\n\n await this._consumeBody();\n if (this[RAW_CACHE] === undefined) {\n throw new Error(\"[Hyperttp] Response body is not available as JSON\");\n }\n if (this[TEXT_CACHE] === undefined) {\n this[TEXT_CACHE] = STATIC_DECODER.decode(this[RAW_CACHE]!);\n }\n return JSON.parse(this[TEXT_CACHE]!) as TJson;\n }\n\n /**\n * @ru \u041F\u043E\u043B\u043D\u044B\u0439 \u0441\u0431\u0440\u043E\u0441 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044F \u0434\u043B\u044F \u043F\u0435\u0440\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F \u0432 \u043F\u0443\u043B\u0435. \u041E\u0447\u0438\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u043A\u044D\u0448\u0438 \u0438 \u043F\u0440\u0438\u0432\u0430\u0442\u043D\u044B\u0435 \u043F\u043E\u043B\u044F.\n * @en Full state reset for pool reuse. Clears all caches and private fields.\n */\n public reset(): void {\n this.status = 0;\n this.headers = EMPTY_HEADERS;\n this.body = null;\n this.url = \"\";\n this.data = null;\n this[RAW_CACHE] = undefined;\n this[TEXT_CACHE] = undefined;\n this[JSON_CACHE] = undefined;\n this._bodyConsumed = false;\n this._raw = undefined;\n }\n\n /**\n * @ru \u0421\u0431\u0440\u0430\u0441\u044B\u0432\u0430\u0435\u0442 \u0442\u0435\u043B\u043E \u043E\u0442\u0432\u0435\u0442\u0430 (\u0434\u043B\u044F \u0441\u0442\u0440\u0438\u043C\u043E\u0432 \u2014 \u043E\u0442\u043C\u0435\u043D\u044F\u0435\u0442/cancel).\n * @en Discards the response body (cancels streams).\n * @returns Promise that resolves when the body is discarded.\n */\n public async dump(): Promise<void> {\n if (this._bodyConsumed) return;\n this._bodyConsumed = true;\n\n const body = this.body;\n if (isReadableStream(body)) {\n if (!body.locked) await body.cancel().catch(() => {});\n } else if (isBlob(body)) {\n await body.arrayBuffer();\n }\n }\n\n /**\n * @ru \u041A\u043B\u043E\u043D\u0438\u0440\u0443\u0435\u0442 \u043E\u0442\u0432\u0435\u0442 \u0441 \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u043C \u0441\u0442\u0440\u0438\u043C\u043E\u0432 \u0447\u0435\u0440\u0435\u0437 tee().\n * @en Clones the response, splitting streams via tee().\n * @returns A new HttpResponse instance.\n */\n public clone(): HttpResponse<T> {\n const cloned = new HyperHttpResponse<T>();\n cloned.status = this.status;\n cloned.headers = this.headers;\n cloned.url = this.url;\n cloned.data = this.data ? cloneBodyFast(this.data) : null;\n cloned._bodyConsumed = this._bodyConsumed;\n cloned._raw = this._bodyConsumed ? undefined : this._raw;\n\n cloned[RAW_CACHE] = this[RAW_CACHE];\n cloned[TEXT_CACHE] = this[TEXT_CACHE];\n cloned[JSON_CACHE] = this[JSON_CACHE];\n\n if (isReadableStream(this.body) && !this._bodyConsumed) {\n if (this.body.locked) {\n cloned.body = this.body;\n } else {\n const [b1, b2] = this.body.tee();\n this.body = b1 as T | HyperBody | Uint8Array | null;\n cloned.body = b2 as T | HyperBody | Uint8Array | null;\n }\n } else {\n cloned.body = this.body;\n }\n\n return cloned;\n }\n}\n\nexport const responsePool: HyperHttpResponse<any>[] = [];\nconst RESPONSE_POOL_MAX = 64;\n\n/**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0451\u0442 HttpResponse \u0438\u0437 \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u043D\u043E\u0433\u043E \u043E\u0442\u0432\u0435\u0442\u0430 \u0441 \u043F\u0435\u0440\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043C \u043F\u0443\u043B\u0430.\n * @en Creates an HttpResponse from a transport response reusing the pool.\n * @param rawResponse - The raw transport response.\n * @returns An HttpResponse instance.\n */\nexport const mapResponseFast = (rawResponse: TransportResponse): HttpResponse<unknown> => {\n const instance = responsePool.pop() ?? new HyperHttpResponse();\n return instance.init(rawResponse);\n};\n\n/**\n * @ru \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 HttpResponse \u0432 \u043F\u0443\u043B \u043F\u0435\u0440\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F.\n * @en Returns an HttpResponse to the reuse pool.\n * @param res - The response to recycle.\n */\nexport const recycleResponse = (res: HttpResponse<unknown>): void => {\n if (res instanceof HyperHttpResponse && responsePool.length < RESPONSE_POOL_MAX) {\n res.reset();\n responsePool.push(res);\n }\n};\n\n/**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0451\u0442 StreamResponse \u0431\u0435\u0437 \u043F\u043E\u0442\u0440\u0435\u0431\u043B\u0435\u043D\u0438\u044F \u0442\u0435\u043B\u0430.\n * @en Creates a StreamResponse without consuming the body.\n * @param rawResponse - The raw transport response.\n * @returns A StreamResponse-like object.\n */\nexport const mapStreamFast = (rawResponse: TransportResponse) => ({\n status: rawResponse.status,\n headers: rawResponse.headers,\n body: rawResponse.body,\n url: rawResponse.url ?? \"\",\n});\n\n/**\n * @ru \u0411\u044B\u0441\u0442\u0440\u043E\u0435 \u0441\u043B\u0438\u044F\u043D\u0438\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432 \u0441 \u043C\u0443\u0442\u0430\u0446\u0438\u0435\u0439 \u0431\u0430\u0437\u043E\u0432\u043E\u0433\u043E \u043E\u0431\u044A\u0435\u043A\u0442\u0430.\n * @en Fast header merge mutating the base object.\n * @param base - Base headers object (mutated).\n * @param override - Optional headers to overlay.\n * @returns The mutated base headers object.\n */\nexport const mergeHeadersFast = (\n base: Record<string, string | string[]>,\n override?: Record<string, string | string[]>,\n): Record<string, string | string[]> => {\n if (!override) return base;\n\n let hasOverride = false;\n for (const _ in override) {\n hasOverride = true;\n break;\n }\n if (!hasOverride) return base;\n\n for (const key in override) {\n if (Object.prototype.hasOwnProperty.call(override, key)) {\n base[key] = override[key]!;\n }\n }\n return base;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["CURRENT_RUNTIME", "RAW_CACHE", "TEXT_CACHE", "JSON_CACHE", "STATIC_DECODER", "STATIC_ENCODER", "EMPTY_HEADERS", "isReadableStream", "value", "isBlob", "body", "obj", "proto", "target", "key", "rawResponse", "buf", "bunBody", "cloned", "b1", "b2", "RESPONSE_POOL_MAX", "res", "base", "override", "hasOverride", "_"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retryUtils.d.ts","sourceRoot":"","sources":["../../src/utils/retryUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAQpD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,MAAM,CAO7E;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"retryUtils.d.ts","sourceRoot":"","sources":["../../src/utils/retryUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAQpD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,MAAM,CAO7E;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC5D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO,CAM/E"}
|
package/utils/retryUtils.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const u=new Set([502,503,504]);export function calcDelay(e,t){const{baseDelay:n=1e3,maxDelay:r=1e4,jitter:
|
|
1
|
+
"use strict";const u=new Set([502,503,504]);export function calcDelay(e,t){const{baseDelay:n=1e3,maxDelay:r=1e4,jitter:o=!0}=t,c=Math.min(e,31),a=Math.min(n*Math.pow(2,c),r);if(!o)return a;const i=a*(.75+Math.random()*.5);return Math.min(Math.max(0,i),r)}export async function drainBody(e){if(!(!e||typeof e!="object"))try{const t=e;if(typeof t.dump=="function"){await t.dump();return}if(typeof t.destroy=="function"){t.destroy();return}if(typeof t.resume=="function"){t.resume();return}if(typeof t.cancel=="function"){await t.cancel();return}typeof t.getReader=="function"&&t.getReader().cancel()}catch{}}export function shouldRetry(e,t){const n=t.retryStatusCodes;return n!==void 0?n.length>0&&n.includes(e):u.has(e)}
|
|
2
2
|
//# sourceMappingURL=retryUtils.js.map
|
package/utils/retryUtils.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/retryUtils.ts"],
|
|
4
|
-
"sourcesContent": ["import type { RetryOptions } from \"@hyperttp/types\";\n\n/**\n * @ru \u041A\u043E\u0434\u044B \u0441\u0442\u0430\u0442\u0443\u0441\u0430 HTTP, \u043F\u043E \u043A\u043E\u0442\u043E\u0440\u044B\u043C \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u044B\u0435 \u043F\u043E\u043F\u044B\u0442\u043A\u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u044E\u0442\u0441\u044F \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E.\n * @en Default HTTP status codes that trigger retries when no explicit codes are provided.\n */\nconst DEFAULT_RETRY_STATUS_CODES = new Set<number>([502, 503, 504]);\n\n/**\n * @ru \u0412\u044B\u0447\u0438\u0441\u043B\u044F\u0435\u0442 \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u0443 \u043F\u0435\u0440\u0435\u0434 \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E\u0439 \u043F\u043E\u043F\u044B\u0442\u043A\u043E\u0439 \u0441 \u044D\u043A\u0441\u043F\u043E\u043D\u0435\u043D\u0446\u0438\u0430\u043B\u044C\u043D\u043E\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u043E\u0439 \u0438 \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u044B\u043C \u0434\u0436\u0438\u0442\u0442\u0435\u0440\u043E\u043C.\n * @en Calculates the delay before a retry using exponential backoff and optional jitter.\n */\nexport function calcDelay(attempt: number, retryOptions: RetryOptions): number {\n const { baseDelay = 1000, maxDelay = 10000, jitter = true } = retryOptions;\n const safeAttempt = Math.min(attempt, 31);\n const base = Math.min(baseDelay * Math.pow(2, safeAttempt), maxDelay);\n if (!jitter) return base;\n const jittered = base * (0.75 + Math.random() * 0.5);\n return Math.min(Math.max(0, jittered), maxDelay);\n}\n\n/**\n * @ru \u041F\u044B\u0442\u0430\u0435\u0442\u0441\u044F \u043E\u0441\u0432\u043E\u0431\u043E\u0434\u0438\u0442\u044C \u0440\u0435\u0441\u0443\u0440\u0441\u044B \u0442\u0435\u043B\u0430 \u043E\u0442\u0432\u0435\u0442\u0430, \u043D\u0435 \u0434\u043E\u0436\u0438\u0434\u0430\u044F\u0441\u044C \u043F\u043E\u043B\u043D\u043E\u0433\u043E \u043F\u043E\u0442\u0440\u0435\u0431\u043B\u0435\u043D\u0438\u044F. \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043C\u0435\u0442\u043E\u0434\u044B dump, resume, destroy.\n * @en Attempts to release response body resources without fully consuming it. Supports dump, resume, destroy methods.\n */\nexport async function drainBody(body: unknown): Promise<void> {\n if (!body || typeof body !== \"object\") return;\n try {\n const stream = body as Record<string, unknown>;\n\n if (typeof stream.dump === \"function\") {\n await (stream.dump as () => Promise<void>)();\n return;\n }\n\n if (typeof stream.destroy === \"function\") {\n (stream.destroy as () => void)();\n return;\n }\n\n if (typeof stream.resume === \"function\") {\n (stream.resume as () => void)();\n }\n } catch {\n //\n }\n}\n\n/**\n * @ru \u041E\u043F\u0440\u0435\u0434\u0435\u043B\u044F\u0435\u0442, \u0441\u043B\u0435\u0434\u0443\u0435\u0442 \u043B\u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u0443\u044E \u043F\u043E\u043F\u044B\u0442\u043A\u0443 \u0434\u043B\u044F \u0434\u0430\u043D\u043D\u043E\u0433\u043E \u043A\u043E\u0434\u0430 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043D\u0430 \u043E\u0441\u043D\u043E\u0432\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A.\n * @en Determines whether to retry for the given status code based on retry options.\n */\nexport function shouldRetry(status: number, retryOptions: RetryOptions): boolean {\n const codes = retryOptions.retryStatusCodes;\n if (codes !== undefined) {\n return codes.length > 0 && codes.includes(status);\n }\n return DEFAULT_RETRY_STATUS_CODES.has(status);\n}\n"],
|
|
5
|
-
"mappings": "aAMA,MAAMA,EAA6B,IAAI,IAAY,CAAC,IAAK,IAAK,GAAG,CAAC,EAM5D,gBAAU,UAAUC,EAAiBC,EAA0B,CACnE,KAAM,CAAE,UAAAC,EAAY,IAAM,SAAAC,EAAW,IAAO,OAAAC,EAAS,EAAI,EAAKH,EACxDI,EAAc,KAAK,IAAIL,EAAS,EAAE,EAClCM,EAAO,KAAK,IAAIJ,EAAY,KAAK,IAAI,EAAGG,CAAW,EAAGF,CAAQ,EACpE,GAAI,CAACC,EAAQ,OAAOE,EACpB,MAAMC,EAAWD,GAAQ,IAAO,KAAK,OAAM,EAAK,IAChD,OAAO,KAAK,IAAI,KAAK,IAAI,EAAGC,CAAQ,EAAGJ,CAAQ,CACjD,CAMA,sBAAsB,UAAUK,EAAa,CAC3C,GAAI,GAACA,GAAQ,OAAOA,GAAS,UAC7B,GAAI,CACF,MAAMC,EAASD,EAEf,GAAI,OAAOC,EAAO,MAAS,WAAY,CACrC,MAAOA,EAAO,KAA4B,EAC1C,MACF,CAEA,GAAI,OAAOA,EAAO,SAAY,WAAY,CACvCA,EAAO,QAAsB,EAC9B,MACF,
|
|
4
|
+
"sourcesContent": ["import type { RetryOptions } from \"@hyperttp/types\";\n\n/**\n * @ru \u041A\u043E\u0434\u044B \u0441\u0442\u0430\u0442\u0443\u0441\u0430 HTTP, \u043F\u043E \u043A\u043E\u0442\u043E\u0440\u044B\u043C \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u044B\u0435 \u043F\u043E\u043F\u044B\u0442\u043A\u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u044F\u044E\u0442\u0441\u044F \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E.\n * @en Default HTTP status codes that trigger retries when no explicit codes are provided.\n */\nconst DEFAULT_RETRY_STATUS_CODES = new Set<number>([502, 503, 504]);\n\n/**\n * @ru \u0412\u044B\u0447\u0438\u0441\u043B\u044F\u0435\u0442 \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u0443 \u043F\u0435\u0440\u0435\u0434 \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E\u0439 \u043F\u043E\u043F\u044B\u0442\u043A\u043E\u0439 \u0441 \u044D\u043A\u0441\u043F\u043E\u043D\u0435\u043D\u0446\u0438\u0430\u043B\u044C\u043D\u043E\u0439 \u0437\u0430\u0434\u0435\u0440\u0436\u043A\u043E\u0439 \u0438 \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u044B\u043C \u0434\u0436\u0438\u0442\u0442\u0435\u0440\u043E\u043C.\n * @en Calculates the delay before a retry using exponential backoff and optional jitter.\n */\nexport function calcDelay(attempt: number, retryOptions: RetryOptions): number {\n const { baseDelay = 1000, maxDelay = 10000, jitter = true } = retryOptions;\n const safeAttempt = Math.min(attempt, 31);\n const base = Math.min(baseDelay * Math.pow(2, safeAttempt), maxDelay);\n if (!jitter) return base;\n const jittered = base * (0.75 + Math.random() * 0.5);\n return Math.min(Math.max(0, jittered), maxDelay);\n}\n\n/**\n * @ru \u041F\u044B\u0442\u0430\u0435\u0442\u0441\u044F \u043E\u0441\u0432\u043E\u0431\u043E\u0434\u0438\u0442\u044C \u0440\u0435\u0441\u0443\u0440\u0441\u044B \u0442\u0435\u043B\u0430 \u043E\u0442\u0432\u0435\u0442\u0430, \u043D\u0435 \u0434\u043E\u0436\u0438\u0434\u0430\u044F\u0441\u044C \u043F\u043E\u043B\u043D\u043E\u0433\u043E \u043F\u043E\u0442\u0440\u0435\u0431\u043B\u0435\u043D\u0438\u044F. \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043C\u0435\u0442\u043E\u0434\u044B dump, resume, destroy.\n * @en Attempts to release response body resources without fully consuming it. Supports dump, resume, destroy methods.\n */\nexport async function drainBody(body: unknown): Promise<void> {\n if (!body || typeof body !== \"object\") return;\n try {\n const stream = body as Record<string, unknown>;\n\n if (typeof stream.dump === \"function\") {\n await (stream.dump as () => Promise<void>)();\n return;\n }\n\n if (typeof stream.destroy === \"function\") {\n (stream.destroy as () => void)();\n return;\n }\n\n if (typeof stream.resume === \"function\") {\n (stream.resume as () => void)();\n return;\n }\n\n if (typeof stream.cancel === \"function\") {\n await (stream.cancel as () => Promise<void>)();\n return;\n }\n\n if (typeof stream.getReader === \"function\") {\n const reader = (stream as unknown as ReadableStream).getReader();\n reader.cancel();\n }\n } catch {\n //\n }\n}\n\n/**\n * @ru \u041E\u043F\u0440\u0435\u0434\u0435\u043B\u044F\u0435\u0442, \u0441\u043B\u0435\u0434\u0443\u0435\u0442 \u043B\u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u0443\u044E \u043F\u043E\u043F\u044B\u0442\u043A\u0443 \u0434\u043B\u044F \u0434\u0430\u043D\u043D\u043E\u0433\u043E \u043A\u043E\u0434\u0430 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043D\u0430 \u043E\u0441\u043D\u043E\u0432\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A.\n * @en Determines whether to retry for the given status code based on retry options.\n */\nexport function shouldRetry(status: number, retryOptions: RetryOptions): boolean {\n const codes = retryOptions.retryStatusCodes;\n if (codes !== undefined) {\n return codes.length > 0 && codes.includes(status);\n }\n return DEFAULT_RETRY_STATUS_CODES.has(status);\n}\n"],
|
|
5
|
+
"mappings": "aAMA,MAAMA,EAA6B,IAAI,IAAY,CAAC,IAAK,IAAK,GAAG,CAAC,EAM5D,gBAAU,UAAUC,EAAiBC,EAA0B,CACnE,KAAM,CAAE,UAAAC,EAAY,IAAM,SAAAC,EAAW,IAAO,OAAAC,EAAS,EAAI,EAAKH,EACxDI,EAAc,KAAK,IAAIL,EAAS,EAAE,EAClCM,EAAO,KAAK,IAAIJ,EAAY,KAAK,IAAI,EAAGG,CAAW,EAAGF,CAAQ,EACpE,GAAI,CAACC,EAAQ,OAAOE,EACpB,MAAMC,EAAWD,GAAQ,IAAO,KAAK,OAAM,EAAK,IAChD,OAAO,KAAK,IAAI,KAAK,IAAI,EAAGC,CAAQ,EAAGJ,CAAQ,CACjD,CAMA,sBAAsB,UAAUK,EAAa,CAC3C,GAAI,GAACA,GAAQ,OAAOA,GAAS,UAC7B,GAAI,CACF,MAAMC,EAASD,EAEf,GAAI,OAAOC,EAAO,MAAS,WAAY,CACrC,MAAOA,EAAO,KAA4B,EAC1C,MACF,CAEA,GAAI,OAAOA,EAAO,SAAY,WAAY,CACvCA,EAAO,QAAsB,EAC9B,MACF,CAEA,GAAI,OAAOA,EAAO,QAAW,WAAY,CACtCA,EAAO,OAAqB,EAC7B,MACF,CAEA,GAAI,OAAOA,EAAO,QAAW,WAAY,CACvC,MAAOA,EAAO,OAA8B,EAC5C,MACF,CAEI,OAAOA,EAAO,WAAc,YACdA,EAAqC,UAAS,EACvD,OAAM,CAEjB,MAAQ,CAER,CACF,CAMM,gBAAU,YAAYC,EAAgBT,EAA0B,CACpE,MAAMU,EAAQV,EAAa,iBAC3B,OAAIU,IAAU,OACLA,EAAM,OAAS,GAAKA,EAAM,SAASD,CAAM,EAE3CX,EAA2B,IAAIW,CAAM,CAC9C",
|
|
6
6
|
"names": ["DEFAULT_RETRY_STATUS_CODES", "attempt", "retryOptions", "baseDelay", "maxDelay", "jitter", "safeAttempt", "base", "jittered", "body", "stream", "status", "codes"]
|
|
7
7
|
}
|