@langchain/core 1.1.2 → 1.1.4

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/chat_history.cjs +1 -1
  3. package/dist/chat_history.js +1 -1
  4. package/dist/language_models/chat_models.cjs +1 -1
  5. package/dist/language_models/chat_models.js +1 -1
  6. package/dist/messages/ai.cjs +6 -48
  7. package/dist/messages/ai.cjs.map +1 -1
  8. package/dist/messages/ai.js +6 -48
  9. package/dist/messages/ai.js.map +1 -1
  10. package/dist/messages/base.cjs +3 -2
  11. package/dist/messages/base.cjs.map +1 -1
  12. package/dist/messages/base.js +3 -2
  13. package/dist/messages/base.js.map +1 -1
  14. package/dist/messages/index.cjs +4 -2
  15. package/dist/messages/index.d.cts +2 -2
  16. package/dist/messages/index.d.ts +2 -2
  17. package/dist/messages/index.js +5 -4
  18. package/dist/messages/transformers.cjs +2 -2
  19. package/dist/messages/transformers.js +2 -2
  20. package/dist/messages/utils.cjs +77 -4
  21. package/dist/messages/utils.cjs.map +1 -1
  22. package/dist/messages/utils.d.cts +33 -2
  23. package/dist/messages/utils.d.ts +33 -2
  24. package/dist/messages/utils.js +77 -5
  25. package/dist/messages/utils.js.map +1 -1
  26. package/dist/prompts/chat.cjs +2 -2
  27. package/dist/prompts/chat.js +2 -2
  28. package/dist/runnables/base.cjs +3 -3
  29. package/dist/runnables/base.cjs.map +1 -1
  30. package/dist/runnables/base.js +1 -1
  31. package/dist/runnables/base.js.map +1 -1
  32. package/dist/runnables/graph_mermaid.cjs +2 -1
  33. package/dist/runnables/graph_mermaid.cjs.map +1 -1
  34. package/dist/runnables/graph_mermaid.js +3 -1
  35. package/dist/runnables/graph_mermaid.js.map +1 -1
  36. package/dist/runnables/history.cjs +1 -1
  37. package/dist/runnables/history.js +1 -1
  38. package/dist/runnables/utils.cjs +5 -0
  39. package/dist/runnables/utils.cjs.map +1 -1
  40. package/dist/runnables/utils.js +5 -1
  41. package/dist/runnables/utils.js.map +1 -1
  42. package/dist/utils/async_caller.cjs +2 -7
  43. package/dist/utils/async_caller.cjs.map +1 -1
  44. package/dist/utils/async_caller.js +1 -6
  45. package/dist/utils/async_caller.js.map +1 -1
  46. package/dist/utils/is-network-error/index.cjs +27 -0
  47. package/dist/utils/is-network-error/index.cjs.map +1 -0
  48. package/dist/utils/is-network-error/index.js +26 -0
  49. package/dist/utils/is-network-error/index.js.map +1 -0
  50. package/dist/utils/p-retry/index.cjs +141 -0
  51. package/dist/utils/p-retry/index.cjs.map +1 -0
  52. package/dist/utils/p-retry/index.js +141 -0
  53. package/dist/utils/p-retry/index.js.map +1 -0
  54. package/dist/utils/testing/message_history.cjs +1 -1
  55. package/dist/utils/testing/message_history.js +1 -1
  56. package/dist/utils/types/index.cjs +4 -0
  57. package/dist/utils/types/index.d.cts +2 -2
  58. package/dist/utils/types/index.d.ts +2 -2
  59. package/dist/utils/types/index.js +4 -2
  60. package/dist/utils/types/zod.cjs +24 -0
  61. package/dist/utils/types/zod.cjs.map +1 -1
  62. package/dist/utils/types/zod.d.cts +4 -1
  63. package/dist/utils/types/zod.d.ts +4 -1
  64. package/dist/utils/types/zod.js +23 -1
  65. package/dist/utils/types/zod.js.map +1 -1
  66. package/package.json +1 -2
@@ -1,3 +1,4 @@
1
+ const require_utils = require('./utils.cjs');
1
2
 
2
3
  //#region src/runnables/graph_mermaid.ts
3
4
  function _escapeNodeLabel(nodeLabel) {
@@ -88,7 +89,7 @@ function drawMermaid(nodes, edges, config) {
88
89
  async function drawMermaidImage(mermaidSyntax, config) {
89
90
  let backgroundColor = config?.backgroundColor ?? "white";
90
91
  const imageType = config?.imageType ?? "png";
91
- const mermaidSyntaxEncoded = btoa(mermaidSyntax);
92
+ const mermaidSyntaxEncoded = require_utils.toBase64Url(mermaidSyntax);
92
93
  if (backgroundColor !== void 0) {
93
94
  const hexColorPattern = /^#(?:[0-9a-fA-F]{3}){1,2}$/;
94
95
  if (!hexColorPattern.test(backgroundColor)) backgroundColor = `!${backgroundColor}`;
@@ -1 +1 @@
1
- {"version":3,"file":"graph_mermaid.cjs","names":["nodeLabel: string","nodeColors: Record<string, string>","nodes: Record<string, Node>","edges: Edge[]","config?: {\n firstNode?: string;\n lastNode?: string;\n curveStyle?: string;\n withStyles?: boolean;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }","formatDict: Record<string, string>","edgeGroups: Record<string, Edge[]>","prefix: string","edges","mermaidSyntax: string","config?: {\n /**\n * The type of image to render.\n * @default \"png\"\n */\n imageType?: \"png\" | \"jpeg\" | \"webp\";\n backgroundColor?: string;\n }"],"sources":["../../src/runnables/graph_mermaid.ts"],"sourcesContent":["import { Edge, Node } from \"./types.js\";\n\nfunction _escapeNodeLabel(nodeLabel: string): string {\n // Escapes the node label for Mermaid syntax.\n return nodeLabel.replace(/[^a-zA-Z-_0-9]/g, \"_\");\n}\n\nconst MARKDOWN_SPECIAL_CHARS = [\"*\", \"_\", \"`\"];\n\nfunction _generateMermaidGraphStyles(\n nodeColors: Record<string, string>\n): string {\n let styles = \"\";\n for (const [className, color] of Object.entries(nodeColors)) {\n styles += `\\tclassDef ${className} ${color};\\n`;\n }\n return styles;\n}\n\n/**\n * Draws a Mermaid graph using the provided graph data\n */\nexport function drawMermaid(\n nodes: Record<string, Node>,\n edges: Edge[],\n config?: {\n firstNode?: string;\n lastNode?: string;\n curveStyle?: string;\n withStyles?: boolean;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }\n): string {\n const {\n firstNode,\n lastNode,\n nodeColors,\n withStyles = true,\n curveStyle = \"linear\",\n wrapLabelNWords = 9,\n } = config ?? {};\n // Initialize Mermaid graph configuration\n let mermaidGraph = withStyles\n ? `%%{init: {'flowchart': {'curve': '${curveStyle}'}}}%%\\ngraph TD;\\n`\n : \"graph TD;\\n\";\n if (withStyles) {\n // Node formatting templates\n const defaultClassLabel = \"default\";\n const formatDict: Record<string, string> = {\n [defaultClassLabel]: \"{0}({1})\",\n };\n if (firstNode !== undefined) {\n formatDict[firstNode] = \"{0}([{1}]):::first\";\n }\n if (lastNode !== undefined) {\n formatDict[lastNode] = \"{0}([{1}]):::last\";\n }\n\n // Add nodes to the graph\n for (const [key, node] of Object.entries(nodes)) {\n const nodeName = node.name.split(\":\").pop() ?? \"\";\n const label = MARKDOWN_SPECIAL_CHARS.some(\n (char) => nodeName.startsWith(char) && nodeName.endsWith(char)\n )\n ? `<p>${nodeName}</p>`\n : nodeName;\n\n let finalLabel = label;\n if (Object.keys(node.metadata ?? {}).length) {\n finalLabel += `<hr/><small><em>${Object.entries(node.metadata ?? {})\n .map(([k, v]) => `${k} = ${v}`)\n .join(\"\\n\")}</em></small>`;\n }\n\n const nodeLabel = (formatDict[key] ?? formatDict[defaultClassLabel])\n .replace(\"{0}\", _escapeNodeLabel(key))\n .replace(\"{1}\", finalLabel);\n\n mermaidGraph += `\\t${nodeLabel}\\n`;\n }\n }\n\n // Group edges by their common prefixes\n const edgeGroups: Record<string, Edge[]> = {};\n for (const edge of edges) {\n const srcParts = edge.source.split(\":\");\n const tgtParts = edge.target.split(\":\");\n const commonPrefix = srcParts\n .filter((src, i) => src === tgtParts[i])\n .join(\":\");\n if (!edgeGroups[commonPrefix]) {\n edgeGroups[commonPrefix] = [];\n }\n edgeGroups[commonPrefix].push(edge);\n }\n\n const seenSubgraphs = new Set<string>();\n\n function addSubgraph(edges: Edge[], prefix: string): void {\n const selfLoop = edges.length === 1 && edges[0].source === edges[0].target;\n if (prefix && !selfLoop) {\n const subgraph = prefix.split(\":\").pop()!;\n if (seenSubgraphs.has(subgraph)) {\n throw new Error(\n `Found duplicate subgraph '${subgraph}' -- this likely means that ` +\n \"you're reusing a subgraph node with the same name. \" +\n \"Please adjust your graph to have subgraph nodes with unique names.\"\n );\n }\n\n seenSubgraphs.add(subgraph);\n mermaidGraph += `\\tsubgraph ${subgraph}\\n`;\n }\n\n for (const edge of edges) {\n const { source, target, data, conditional } = edge;\n\n let edgeLabel = \"\";\n if (data !== undefined) {\n let edgeData = data;\n const words = edgeData.split(\" \");\n if (words.length > wrapLabelNWords) {\n edgeData = Array.from(\n { length: Math.ceil(words.length / wrapLabelNWords) },\n (_, i) =>\n words\n .slice(i * wrapLabelNWords, (i + 1) * wrapLabelNWords)\n .join(\" \")\n ).join(\"&nbsp;<br>&nbsp;\");\n }\n edgeLabel = conditional\n ? ` -. &nbsp;${edgeData}&nbsp; .-> `\n : ` -- &nbsp;${edgeData}&nbsp; --> `;\n } else {\n edgeLabel = conditional ? \" -.-> \" : \" --> \";\n }\n\n mermaidGraph += `\\t${_escapeNodeLabel(\n source\n )}${edgeLabel}${_escapeNodeLabel(target)};\\n`;\n }\n\n // Recursively add nested subgraphs\n for (const nestedPrefix in edgeGroups) {\n if (nestedPrefix.startsWith(`${prefix}:`) && nestedPrefix !== prefix) {\n addSubgraph(edgeGroups[nestedPrefix], nestedPrefix);\n }\n }\n\n if (prefix && !selfLoop) {\n mermaidGraph += \"\\tend\\n\";\n }\n }\n\n // Start with the top-level edges (no common prefix)\n addSubgraph(edgeGroups[\"\"] ?? [], \"\");\n\n // Add remaining subgraphs\n for (const prefix in edgeGroups) {\n if (!prefix.includes(\":\") && prefix !== \"\") {\n addSubgraph(edgeGroups[prefix], prefix);\n }\n }\n\n // Add custom styles for nodes\n if (withStyles) {\n mermaidGraph += _generateMermaidGraphStyles(nodeColors ?? {});\n }\n\n return mermaidGraph;\n}\n\n/**\n * Renders Mermaid graph using the Mermaid.INK API.\n *\n * @example\n * ```javascript\n * const image = await drawMermaidImage(mermaidSyntax, {\n * backgroundColor: \"white\",\n * imageType: \"png\",\n * });\n * fs.writeFileSync(\"image.png\", image);\n * ```\n *\n * @param mermaidSyntax - The Mermaid syntax to render.\n * @param config - The configuration for the image.\n * @returns The image as a Blob.\n */\nexport async function drawMermaidImage(\n mermaidSyntax: string,\n config?: {\n /**\n * The type of image to render.\n * @default \"png\"\n */\n imageType?: \"png\" | \"jpeg\" | \"webp\";\n backgroundColor?: string;\n }\n) {\n let backgroundColor = config?.backgroundColor ?? \"white\";\n const imageType = config?.imageType ?? \"png\";\n\n // Use btoa for compatibility, assume ASCII\n const mermaidSyntaxEncoded = btoa(mermaidSyntax);\n // Check if the background color is a hexadecimal color code using regex\n if (backgroundColor !== undefined) {\n const hexColorPattern = /^#(?:[0-9a-fA-F]{3}){1,2}$/;\n if (!hexColorPattern.test(backgroundColor)) {\n backgroundColor = `!${backgroundColor}`;\n }\n }\n const imageUrl = `https://mermaid.ink/img/${mermaidSyntaxEncoded}?bgColor=${backgroundColor}&type=${imageType}`;\n const res = await fetch(imageUrl);\n if (!res.ok) {\n throw new Error(\n [\n `Failed to render the graph using the Mermaid.INK API.`,\n `Status code: ${res.status}`,\n `Status text: ${res.statusText}`,\n ].join(\"\\n\")\n );\n }\n const content = await res.blob();\n return content;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"graph_mermaid.cjs","names":["nodeLabel: string","nodeColors: Record<string, string>","nodes: Record<string, Node>","edges: Edge[]","config?: {\n firstNode?: string;\n lastNode?: string;\n curveStyle?: string;\n withStyles?: boolean;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }","formatDict: Record<string, string>","edgeGroups: Record<string, Edge[]>","prefix: string","edges","mermaidSyntax: string","config?: {\n /**\n * The type of image to render.\n * @default \"png\"\n */\n imageType?: \"png\" | \"jpeg\" | \"webp\";\n backgroundColor?: string;\n }","toBase64Url"],"sources":["../../src/runnables/graph_mermaid.ts"],"sourcesContent":["import { Edge, Node } from \"./types.js\";\nimport { toBase64Url } from \"./utils.js\";\n\nfunction _escapeNodeLabel(nodeLabel: string): string {\n // Escapes the node label for Mermaid syntax.\n return nodeLabel.replace(/[^a-zA-Z-_0-9]/g, \"_\");\n}\n\nconst MARKDOWN_SPECIAL_CHARS = [\"*\", \"_\", \"`\"];\n\nfunction _generateMermaidGraphStyles(\n nodeColors: Record<string, string>\n): string {\n let styles = \"\";\n for (const [className, color] of Object.entries(nodeColors)) {\n styles += `\\tclassDef ${className} ${color};\\n`;\n }\n return styles;\n}\n\n/**\n * Draws a Mermaid graph using the provided graph data\n */\nexport function drawMermaid(\n nodes: Record<string, Node>,\n edges: Edge[],\n config?: {\n firstNode?: string;\n lastNode?: string;\n curveStyle?: string;\n withStyles?: boolean;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }\n): string {\n const {\n firstNode,\n lastNode,\n nodeColors,\n withStyles = true,\n curveStyle = \"linear\",\n wrapLabelNWords = 9,\n } = config ?? {};\n // Initialize Mermaid graph configuration\n let mermaidGraph = withStyles\n ? `%%{init: {'flowchart': {'curve': '${curveStyle}'}}}%%\\ngraph TD;\\n`\n : \"graph TD;\\n\";\n if (withStyles) {\n // Node formatting templates\n const defaultClassLabel = \"default\";\n const formatDict: Record<string, string> = {\n [defaultClassLabel]: \"{0}({1})\",\n };\n if (firstNode !== undefined) {\n formatDict[firstNode] = \"{0}([{1}]):::first\";\n }\n if (lastNode !== undefined) {\n formatDict[lastNode] = \"{0}([{1}]):::last\";\n }\n\n // Add nodes to the graph\n for (const [key, node] of Object.entries(nodes)) {\n const nodeName = node.name.split(\":\").pop() ?? \"\";\n const label = MARKDOWN_SPECIAL_CHARS.some(\n (char) => nodeName.startsWith(char) && nodeName.endsWith(char)\n )\n ? `<p>${nodeName}</p>`\n : nodeName;\n\n let finalLabel = label;\n if (Object.keys(node.metadata ?? {}).length) {\n finalLabel += `<hr/><small><em>${Object.entries(node.metadata ?? {})\n .map(([k, v]) => `${k} = ${v}`)\n .join(\"\\n\")}</em></small>`;\n }\n\n const nodeLabel = (formatDict[key] ?? formatDict[defaultClassLabel])\n .replace(\"{0}\", _escapeNodeLabel(key))\n .replace(\"{1}\", finalLabel);\n\n mermaidGraph += `\\t${nodeLabel}\\n`;\n }\n }\n\n // Group edges by their common prefixes\n const edgeGroups: Record<string, Edge[]> = {};\n for (const edge of edges) {\n const srcParts = edge.source.split(\":\");\n const tgtParts = edge.target.split(\":\");\n const commonPrefix = srcParts\n .filter((src, i) => src === tgtParts[i])\n .join(\":\");\n if (!edgeGroups[commonPrefix]) {\n edgeGroups[commonPrefix] = [];\n }\n edgeGroups[commonPrefix].push(edge);\n }\n\n const seenSubgraphs = new Set<string>();\n\n function addSubgraph(edges: Edge[], prefix: string): void {\n const selfLoop = edges.length === 1 && edges[0].source === edges[0].target;\n if (prefix && !selfLoop) {\n const subgraph = prefix.split(\":\").pop()!;\n if (seenSubgraphs.has(subgraph)) {\n throw new Error(\n `Found duplicate subgraph '${subgraph}' -- this likely means that ` +\n \"you're reusing a subgraph node with the same name. \" +\n \"Please adjust your graph to have subgraph nodes with unique names.\"\n );\n }\n\n seenSubgraphs.add(subgraph);\n mermaidGraph += `\\tsubgraph ${subgraph}\\n`;\n }\n\n for (const edge of edges) {\n const { source, target, data, conditional } = edge;\n\n let edgeLabel = \"\";\n if (data !== undefined) {\n let edgeData = data;\n const words = edgeData.split(\" \");\n if (words.length > wrapLabelNWords) {\n edgeData = Array.from(\n { length: Math.ceil(words.length / wrapLabelNWords) },\n (_, i) =>\n words\n .slice(i * wrapLabelNWords, (i + 1) * wrapLabelNWords)\n .join(\" \")\n ).join(\"&nbsp;<br>&nbsp;\");\n }\n edgeLabel = conditional\n ? ` -. &nbsp;${edgeData}&nbsp; .-> `\n : ` -- &nbsp;${edgeData}&nbsp; --> `;\n } else {\n edgeLabel = conditional ? \" -.-> \" : \" --> \";\n }\n\n mermaidGraph += `\\t${_escapeNodeLabel(\n source\n )}${edgeLabel}${_escapeNodeLabel(target)};\\n`;\n }\n\n // Recursively add nested subgraphs\n for (const nestedPrefix in edgeGroups) {\n if (nestedPrefix.startsWith(`${prefix}:`) && nestedPrefix !== prefix) {\n addSubgraph(edgeGroups[nestedPrefix], nestedPrefix);\n }\n }\n\n if (prefix && !selfLoop) {\n mermaidGraph += \"\\tend\\n\";\n }\n }\n\n // Start with the top-level edges (no common prefix)\n addSubgraph(edgeGroups[\"\"] ?? [], \"\");\n\n // Add remaining subgraphs\n for (const prefix in edgeGroups) {\n if (!prefix.includes(\":\") && prefix !== \"\") {\n addSubgraph(edgeGroups[prefix], prefix);\n }\n }\n\n // Add custom styles for nodes\n if (withStyles) {\n mermaidGraph += _generateMermaidGraphStyles(nodeColors ?? {});\n }\n\n return mermaidGraph;\n}\n\n/**\n * Renders Mermaid graph using the Mermaid.INK API.\n *\n * @example\n * ```javascript\n * const image = await drawMermaidImage(mermaidSyntax, {\n * backgroundColor: \"white\",\n * imageType: \"png\",\n * });\n * fs.writeFileSync(\"image.png\", image);\n * ```\n *\n * @param mermaidSyntax - The Mermaid syntax to render.\n * @param config - The configuration for the image.\n * @returns The image as a Blob.\n */\nexport async function drawMermaidImage(\n mermaidSyntax: string,\n config?: {\n /**\n * The type of image to render.\n * @default \"png\"\n */\n imageType?: \"png\" | \"jpeg\" | \"webp\";\n backgroundColor?: string;\n }\n) {\n let backgroundColor = config?.backgroundColor ?? \"white\";\n const imageType = config?.imageType ?? \"png\";\n\n const mermaidSyntaxEncoded = toBase64Url(mermaidSyntax);\n\n // Check if the background color is a hexadecimal color code using regex\n if (backgroundColor !== undefined) {\n const hexColorPattern = /^#(?:[0-9a-fA-F]{3}){1,2}$/;\n if (!hexColorPattern.test(backgroundColor)) {\n backgroundColor = `!${backgroundColor}`;\n }\n }\n const imageUrl = `https://mermaid.ink/img/${mermaidSyntaxEncoded}?bgColor=${backgroundColor}&type=${imageType}`;\n const res = await fetch(imageUrl);\n if (!res.ok) {\n throw new Error(\n [\n `Failed to render the graph using the Mermaid.INK API.`,\n `Status code: ${res.status}`,\n `Status text: ${res.statusText}`,\n ].join(\"\\n\")\n );\n }\n const content = await res.blob();\n return content;\n}\n"],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import { toBase64Url } from "./utils.js";
2
+
1
3
  //#region src/runnables/graph_mermaid.ts
2
4
  function _escapeNodeLabel(nodeLabel) {
3
5
  return nodeLabel.replace(/[^a-zA-Z-_0-9]/g, "_");
@@ -87,7 +89,7 @@ function drawMermaid(nodes, edges, config) {
87
89
  async function drawMermaidImage(mermaidSyntax, config) {
88
90
  let backgroundColor = config?.backgroundColor ?? "white";
89
91
  const imageType = config?.imageType ?? "png";
90
- const mermaidSyntaxEncoded = btoa(mermaidSyntax);
92
+ const mermaidSyntaxEncoded = toBase64Url(mermaidSyntax);
91
93
  if (backgroundColor !== void 0) {
92
94
  const hexColorPattern = /^#(?:[0-9a-fA-F]{3}){1,2}$/;
93
95
  if (!hexColorPattern.test(backgroundColor)) backgroundColor = `!${backgroundColor}`;
@@ -1 +1 @@
1
- {"version":3,"file":"graph_mermaid.js","names":["nodeLabel: string","nodeColors: Record<string, string>","nodes: Record<string, Node>","edges: Edge[]","config?: {\n firstNode?: string;\n lastNode?: string;\n curveStyle?: string;\n withStyles?: boolean;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }","formatDict: Record<string, string>","edgeGroups: Record<string, Edge[]>","prefix: string","edges","mermaidSyntax: string","config?: {\n /**\n * The type of image to render.\n * @default \"png\"\n */\n imageType?: \"png\" | \"jpeg\" | \"webp\";\n backgroundColor?: string;\n }"],"sources":["../../src/runnables/graph_mermaid.ts"],"sourcesContent":["import { Edge, Node } from \"./types.js\";\n\nfunction _escapeNodeLabel(nodeLabel: string): string {\n // Escapes the node label for Mermaid syntax.\n return nodeLabel.replace(/[^a-zA-Z-_0-9]/g, \"_\");\n}\n\nconst MARKDOWN_SPECIAL_CHARS = [\"*\", \"_\", \"`\"];\n\nfunction _generateMermaidGraphStyles(\n nodeColors: Record<string, string>\n): string {\n let styles = \"\";\n for (const [className, color] of Object.entries(nodeColors)) {\n styles += `\\tclassDef ${className} ${color};\\n`;\n }\n return styles;\n}\n\n/**\n * Draws a Mermaid graph using the provided graph data\n */\nexport function drawMermaid(\n nodes: Record<string, Node>,\n edges: Edge[],\n config?: {\n firstNode?: string;\n lastNode?: string;\n curveStyle?: string;\n withStyles?: boolean;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }\n): string {\n const {\n firstNode,\n lastNode,\n nodeColors,\n withStyles = true,\n curveStyle = \"linear\",\n wrapLabelNWords = 9,\n } = config ?? {};\n // Initialize Mermaid graph configuration\n let mermaidGraph = withStyles\n ? `%%{init: {'flowchart': {'curve': '${curveStyle}'}}}%%\\ngraph TD;\\n`\n : \"graph TD;\\n\";\n if (withStyles) {\n // Node formatting templates\n const defaultClassLabel = \"default\";\n const formatDict: Record<string, string> = {\n [defaultClassLabel]: \"{0}({1})\",\n };\n if (firstNode !== undefined) {\n formatDict[firstNode] = \"{0}([{1}]):::first\";\n }\n if (lastNode !== undefined) {\n formatDict[lastNode] = \"{0}([{1}]):::last\";\n }\n\n // Add nodes to the graph\n for (const [key, node] of Object.entries(nodes)) {\n const nodeName = node.name.split(\":\").pop() ?? \"\";\n const label = MARKDOWN_SPECIAL_CHARS.some(\n (char) => nodeName.startsWith(char) && nodeName.endsWith(char)\n )\n ? `<p>${nodeName}</p>`\n : nodeName;\n\n let finalLabel = label;\n if (Object.keys(node.metadata ?? {}).length) {\n finalLabel += `<hr/><small><em>${Object.entries(node.metadata ?? {})\n .map(([k, v]) => `${k} = ${v}`)\n .join(\"\\n\")}</em></small>`;\n }\n\n const nodeLabel = (formatDict[key] ?? formatDict[defaultClassLabel])\n .replace(\"{0}\", _escapeNodeLabel(key))\n .replace(\"{1}\", finalLabel);\n\n mermaidGraph += `\\t${nodeLabel}\\n`;\n }\n }\n\n // Group edges by their common prefixes\n const edgeGroups: Record<string, Edge[]> = {};\n for (const edge of edges) {\n const srcParts = edge.source.split(\":\");\n const tgtParts = edge.target.split(\":\");\n const commonPrefix = srcParts\n .filter((src, i) => src === tgtParts[i])\n .join(\":\");\n if (!edgeGroups[commonPrefix]) {\n edgeGroups[commonPrefix] = [];\n }\n edgeGroups[commonPrefix].push(edge);\n }\n\n const seenSubgraphs = new Set<string>();\n\n function addSubgraph(edges: Edge[], prefix: string): void {\n const selfLoop = edges.length === 1 && edges[0].source === edges[0].target;\n if (prefix && !selfLoop) {\n const subgraph = prefix.split(\":\").pop()!;\n if (seenSubgraphs.has(subgraph)) {\n throw new Error(\n `Found duplicate subgraph '${subgraph}' -- this likely means that ` +\n \"you're reusing a subgraph node with the same name. \" +\n \"Please adjust your graph to have subgraph nodes with unique names.\"\n );\n }\n\n seenSubgraphs.add(subgraph);\n mermaidGraph += `\\tsubgraph ${subgraph}\\n`;\n }\n\n for (const edge of edges) {\n const { source, target, data, conditional } = edge;\n\n let edgeLabel = \"\";\n if (data !== undefined) {\n let edgeData = data;\n const words = edgeData.split(\" \");\n if (words.length > wrapLabelNWords) {\n edgeData = Array.from(\n { length: Math.ceil(words.length / wrapLabelNWords) },\n (_, i) =>\n words\n .slice(i * wrapLabelNWords, (i + 1) * wrapLabelNWords)\n .join(\" \")\n ).join(\"&nbsp;<br>&nbsp;\");\n }\n edgeLabel = conditional\n ? ` -. &nbsp;${edgeData}&nbsp; .-> `\n : ` -- &nbsp;${edgeData}&nbsp; --> `;\n } else {\n edgeLabel = conditional ? \" -.-> \" : \" --> \";\n }\n\n mermaidGraph += `\\t${_escapeNodeLabel(\n source\n )}${edgeLabel}${_escapeNodeLabel(target)};\\n`;\n }\n\n // Recursively add nested subgraphs\n for (const nestedPrefix in edgeGroups) {\n if (nestedPrefix.startsWith(`${prefix}:`) && nestedPrefix !== prefix) {\n addSubgraph(edgeGroups[nestedPrefix], nestedPrefix);\n }\n }\n\n if (prefix && !selfLoop) {\n mermaidGraph += \"\\tend\\n\";\n }\n }\n\n // Start with the top-level edges (no common prefix)\n addSubgraph(edgeGroups[\"\"] ?? [], \"\");\n\n // Add remaining subgraphs\n for (const prefix in edgeGroups) {\n if (!prefix.includes(\":\") && prefix !== \"\") {\n addSubgraph(edgeGroups[prefix], prefix);\n }\n }\n\n // Add custom styles for nodes\n if (withStyles) {\n mermaidGraph += _generateMermaidGraphStyles(nodeColors ?? {});\n }\n\n return mermaidGraph;\n}\n\n/**\n * Renders Mermaid graph using the Mermaid.INK API.\n *\n * @example\n * ```javascript\n * const image = await drawMermaidImage(mermaidSyntax, {\n * backgroundColor: \"white\",\n * imageType: \"png\",\n * });\n * fs.writeFileSync(\"image.png\", image);\n * ```\n *\n * @param mermaidSyntax - The Mermaid syntax to render.\n * @param config - The configuration for the image.\n * @returns The image as a Blob.\n */\nexport async function drawMermaidImage(\n mermaidSyntax: string,\n config?: {\n /**\n * The type of image to render.\n * @default \"png\"\n */\n imageType?: \"png\" | \"jpeg\" | \"webp\";\n backgroundColor?: string;\n }\n) {\n let backgroundColor = config?.backgroundColor ?? \"white\";\n const imageType = config?.imageType ?? \"png\";\n\n // Use btoa for compatibility, assume ASCII\n const mermaidSyntaxEncoded = btoa(mermaidSyntax);\n // Check if the background color is a hexadecimal color code using regex\n if (backgroundColor !== undefined) {\n const hexColorPattern = /^#(?:[0-9a-fA-F]{3}){1,2}$/;\n if (!hexColorPattern.test(backgroundColor)) {\n backgroundColor = `!${backgroundColor}`;\n }\n }\n const imageUrl = `https://mermaid.ink/img/${mermaidSyntaxEncoded}?bgColor=${backgroundColor}&type=${imageType}`;\n const res = await fetch(imageUrl);\n if (!res.ok) {\n throw new Error(\n [\n `Failed to render the graph using the Mermaid.INK API.`,\n `Status code: ${res.status}`,\n `Status text: ${res.statusText}`,\n ].join(\"\\n\")\n );\n }\n const content = await res.blob();\n return content;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"graph_mermaid.js","names":["nodeLabel: string","nodeColors: Record<string, string>","nodes: Record<string, Node>","edges: Edge[]","config?: {\n firstNode?: string;\n lastNode?: string;\n curveStyle?: string;\n withStyles?: boolean;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }","formatDict: Record<string, string>","edgeGroups: Record<string, Edge[]>","prefix: string","edges","mermaidSyntax: string","config?: {\n /**\n * The type of image to render.\n * @default \"png\"\n */\n imageType?: \"png\" | \"jpeg\" | \"webp\";\n backgroundColor?: string;\n }"],"sources":["../../src/runnables/graph_mermaid.ts"],"sourcesContent":["import { Edge, Node } from \"./types.js\";\nimport { toBase64Url } from \"./utils.js\";\n\nfunction _escapeNodeLabel(nodeLabel: string): string {\n // Escapes the node label for Mermaid syntax.\n return nodeLabel.replace(/[^a-zA-Z-_0-9]/g, \"_\");\n}\n\nconst MARKDOWN_SPECIAL_CHARS = [\"*\", \"_\", \"`\"];\n\nfunction _generateMermaidGraphStyles(\n nodeColors: Record<string, string>\n): string {\n let styles = \"\";\n for (const [className, color] of Object.entries(nodeColors)) {\n styles += `\\tclassDef ${className} ${color};\\n`;\n }\n return styles;\n}\n\n/**\n * Draws a Mermaid graph using the provided graph data\n */\nexport function drawMermaid(\n nodes: Record<string, Node>,\n edges: Edge[],\n config?: {\n firstNode?: string;\n lastNode?: string;\n curveStyle?: string;\n withStyles?: boolean;\n nodeColors?: Record<string, string>;\n wrapLabelNWords?: number;\n }\n): string {\n const {\n firstNode,\n lastNode,\n nodeColors,\n withStyles = true,\n curveStyle = \"linear\",\n wrapLabelNWords = 9,\n } = config ?? {};\n // Initialize Mermaid graph configuration\n let mermaidGraph = withStyles\n ? `%%{init: {'flowchart': {'curve': '${curveStyle}'}}}%%\\ngraph TD;\\n`\n : \"graph TD;\\n\";\n if (withStyles) {\n // Node formatting templates\n const defaultClassLabel = \"default\";\n const formatDict: Record<string, string> = {\n [defaultClassLabel]: \"{0}({1})\",\n };\n if (firstNode !== undefined) {\n formatDict[firstNode] = \"{0}([{1}]):::first\";\n }\n if (lastNode !== undefined) {\n formatDict[lastNode] = \"{0}([{1}]):::last\";\n }\n\n // Add nodes to the graph\n for (const [key, node] of Object.entries(nodes)) {\n const nodeName = node.name.split(\":\").pop() ?? \"\";\n const label = MARKDOWN_SPECIAL_CHARS.some(\n (char) => nodeName.startsWith(char) && nodeName.endsWith(char)\n )\n ? `<p>${nodeName}</p>`\n : nodeName;\n\n let finalLabel = label;\n if (Object.keys(node.metadata ?? {}).length) {\n finalLabel += `<hr/><small><em>${Object.entries(node.metadata ?? {})\n .map(([k, v]) => `${k} = ${v}`)\n .join(\"\\n\")}</em></small>`;\n }\n\n const nodeLabel = (formatDict[key] ?? formatDict[defaultClassLabel])\n .replace(\"{0}\", _escapeNodeLabel(key))\n .replace(\"{1}\", finalLabel);\n\n mermaidGraph += `\\t${nodeLabel}\\n`;\n }\n }\n\n // Group edges by their common prefixes\n const edgeGroups: Record<string, Edge[]> = {};\n for (const edge of edges) {\n const srcParts = edge.source.split(\":\");\n const tgtParts = edge.target.split(\":\");\n const commonPrefix = srcParts\n .filter((src, i) => src === tgtParts[i])\n .join(\":\");\n if (!edgeGroups[commonPrefix]) {\n edgeGroups[commonPrefix] = [];\n }\n edgeGroups[commonPrefix].push(edge);\n }\n\n const seenSubgraphs = new Set<string>();\n\n function addSubgraph(edges: Edge[], prefix: string): void {\n const selfLoop = edges.length === 1 && edges[0].source === edges[0].target;\n if (prefix && !selfLoop) {\n const subgraph = prefix.split(\":\").pop()!;\n if (seenSubgraphs.has(subgraph)) {\n throw new Error(\n `Found duplicate subgraph '${subgraph}' -- this likely means that ` +\n \"you're reusing a subgraph node with the same name. \" +\n \"Please adjust your graph to have subgraph nodes with unique names.\"\n );\n }\n\n seenSubgraphs.add(subgraph);\n mermaidGraph += `\\tsubgraph ${subgraph}\\n`;\n }\n\n for (const edge of edges) {\n const { source, target, data, conditional } = edge;\n\n let edgeLabel = \"\";\n if (data !== undefined) {\n let edgeData = data;\n const words = edgeData.split(\" \");\n if (words.length > wrapLabelNWords) {\n edgeData = Array.from(\n { length: Math.ceil(words.length / wrapLabelNWords) },\n (_, i) =>\n words\n .slice(i * wrapLabelNWords, (i + 1) * wrapLabelNWords)\n .join(\" \")\n ).join(\"&nbsp;<br>&nbsp;\");\n }\n edgeLabel = conditional\n ? ` -. &nbsp;${edgeData}&nbsp; .-> `\n : ` -- &nbsp;${edgeData}&nbsp; --> `;\n } else {\n edgeLabel = conditional ? \" -.-> \" : \" --> \";\n }\n\n mermaidGraph += `\\t${_escapeNodeLabel(\n source\n )}${edgeLabel}${_escapeNodeLabel(target)};\\n`;\n }\n\n // Recursively add nested subgraphs\n for (const nestedPrefix in edgeGroups) {\n if (nestedPrefix.startsWith(`${prefix}:`) && nestedPrefix !== prefix) {\n addSubgraph(edgeGroups[nestedPrefix], nestedPrefix);\n }\n }\n\n if (prefix && !selfLoop) {\n mermaidGraph += \"\\tend\\n\";\n }\n }\n\n // Start with the top-level edges (no common prefix)\n addSubgraph(edgeGroups[\"\"] ?? [], \"\");\n\n // Add remaining subgraphs\n for (const prefix in edgeGroups) {\n if (!prefix.includes(\":\") && prefix !== \"\") {\n addSubgraph(edgeGroups[prefix], prefix);\n }\n }\n\n // Add custom styles for nodes\n if (withStyles) {\n mermaidGraph += _generateMermaidGraphStyles(nodeColors ?? {});\n }\n\n return mermaidGraph;\n}\n\n/**\n * Renders Mermaid graph using the Mermaid.INK API.\n *\n * @example\n * ```javascript\n * const image = await drawMermaidImage(mermaidSyntax, {\n * backgroundColor: \"white\",\n * imageType: \"png\",\n * });\n * fs.writeFileSync(\"image.png\", image);\n * ```\n *\n * @param mermaidSyntax - The Mermaid syntax to render.\n * @param config - The configuration for the image.\n * @returns The image as a Blob.\n */\nexport async function drawMermaidImage(\n mermaidSyntax: string,\n config?: {\n /**\n * The type of image to render.\n * @default \"png\"\n */\n imageType?: \"png\" | \"jpeg\" | \"webp\";\n backgroundColor?: string;\n }\n) {\n let backgroundColor = config?.backgroundColor ?? \"white\";\n const imageType = config?.imageType ?? \"png\";\n\n const mermaidSyntaxEncoded = toBase64Url(mermaidSyntax);\n\n // Check if the background color is a hexadecimal color code using regex\n if (backgroundColor !== undefined) {\n const hexColorPattern = /^#(?:[0-9a-fA-F]{3}){1,2}$/;\n if (!hexColorPattern.test(backgroundColor)) {\n backgroundColor = `!${backgroundColor}`;\n }\n }\n const imageUrl = `https://mermaid.ink/img/${mermaidSyntaxEncoded}?bgColor=${backgroundColor}&type=${imageType}`;\n const res = await fetch(imageUrl);\n if (!res.ok) {\n throw new Error(\n [\n `Failed to render the graph using the Mermaid.INK API.`,\n `Status code: ${res.status}`,\n `Status text: ${res.statusText}`,\n ].join(\"\\n\")\n );\n }\n const content = await res.blob();\n return content;\n}\n"],"mappings":";;;AAGA,SAAS,iBAAiBA,WAA2B;AAEnD,QAAO,UAAU,QAAQ,mBAAmB,IAAI;AACjD;AAED,MAAM,yBAAyB;CAAC;CAAK;CAAK;AAAI;AAE9C,SAAS,4BACPC,YACQ;CACR,IAAI,SAAS;AACb,MAAK,MAAM,CAAC,WAAW,MAAM,IAAI,OAAO,QAAQ,WAAW,EACzD,UAAU,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,CAAC;AAEjD,QAAO;AACR;;;;AAKD,SAAgB,YACdC,OACAC,OACAC,QAQQ;CACR,MAAM,EACJ,WACA,UACA,YACA,aAAa,MACb,aAAa,UACb,kBAAkB,GACnB,GAAG,UAAU,CAAE;CAEhB,IAAI,eAAe,aACf,CAAC,kCAAkC,EAAE,WAAW,mBAAmB,CAAC,GACpE;AACJ,KAAI,YAAY;EAEd,MAAM,oBAAoB;EAC1B,MAAMC,aAAqC,GACxC,oBAAoB,WACtB;AACD,MAAI,cAAc,QAChB,WAAW,aAAa;AAE1B,MAAI,aAAa,QACf,WAAW,YAAY;AAIzB,OAAK,MAAM,CAAC,KAAK,KAAK,IAAI,OAAO,QAAQ,MAAM,EAAE;GAC/C,MAAM,WAAW,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI;GAC/C,MAAM,QAAQ,uBAAuB,KACnC,CAAC,SAAS,SAAS,WAAW,KAAK,IAAI,SAAS,SAAS,KAAK,CAC/D,GACG,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,GACpB;GAEJ,IAAI,aAAa;AACjB,OAAI,OAAO,KAAK,KAAK,YAAY,CAAE,EAAC,CAAC,QACnC,cAAc,CAAC,gBAAgB,EAAE,OAAO,QAAQ,KAAK,YAAY,CAAE,EAAC,CACjE,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAC9B,KAAK,KAAK,CAAC,aAAa,CAAC;GAG9B,MAAM,aAAa,WAAW,QAAQ,WAAW,oBAC9C,QAAQ,OAAO,iBAAiB,IAAI,CAAC,CACrC,QAAQ,OAAO,WAAW;GAE7B,gBAAgB,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC;EACnC;CACF;CAGD,MAAMC,aAAqC,CAAE;AAC7C,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,WAAW,KAAK,OAAO,MAAM,IAAI;EACvC,MAAM,WAAW,KAAK,OAAO,MAAM,IAAI;EACvC,MAAM,eAAe,SAClB,OAAO,CAAC,KAAK,MAAM,QAAQ,SAAS,GAAG,CACvC,KAAK,IAAI;AACZ,MAAI,CAAC,WAAW,eACd,WAAW,gBAAgB,CAAE;EAE/B,WAAW,cAAc,KAAK,KAAK;CACpC;CAED,MAAM,gCAAgB,IAAI;CAE1B,SAAS,YAAYH,SAAeI,QAAsB;EACxD,MAAM,WAAWC,QAAM,WAAW,KAAKA,QAAM,GAAG,WAAWA,QAAM,GAAG;AACpE,MAAI,UAAU,CAAC,UAAU;GACvB,MAAM,WAAW,OAAO,MAAM,IAAI,CAAC,KAAK;AACxC,OAAI,cAAc,IAAI,SAAS,CAC7B,OAAM,IAAI,MACR,CAAC,0BAA0B,EAAE,SAAS,iJAA4B,CAEI;GAI1E,cAAc,IAAI,SAAS;GAC3B,gBAAgB,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC;EAC3C;AAED,OAAK,MAAM,QAAQA,SAAO;GACxB,MAAM,EAAE,QAAQ,QAAQ,MAAM,aAAa,GAAG;GAE9C,IAAI,YAAY;AAChB,OAAI,SAAS,QAAW;IACtB,IAAI,WAAW;IACf,MAAM,QAAQ,SAAS,MAAM,IAAI;AACjC,QAAI,MAAM,SAAS,iBACjB,WAAW,MAAM,KACf,EAAE,QAAQ,KAAK,KAAK,MAAM,SAAS,gBAAgB,CAAE,GACrD,CAAC,GAAG,MACF,MACG,MAAM,IAAI,kBAAkB,IAAI,KAAK,gBAAgB,CACrD,KAAK,IAAI,CACf,CAAC,KAAK,mBAAmB;IAE5B,YAAY,cACR,CAAC,UAAU,EAAE,SAAS,WAAW,CAAC,GAClC,CAAC,UAAU,EAAE,SAAS,WAAW,CAAC;GACvC,OACC,YAAY,cAAc,WAAW;GAGvC,gBAAgB,CAAC,EAAE,EAAE,iBACnB,OACD,GAAG,YAAY,iBAAiB,OAAO,CAAC,GAAG,CAAC;EAC9C;AAGD,OAAK,MAAM,gBAAgB,WACzB,KAAI,aAAa,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,iBAAiB,QAC5D,YAAY,WAAW,eAAe,aAAa;AAIvD,MAAI,UAAU,CAAC,UACb,gBAAgB;CAEnB;CAGD,YAAY,WAAW,OAAO,CAAE,GAAE,GAAG;AAGrC,MAAK,MAAM,UAAU,WACnB,KAAI,CAAC,OAAO,SAAS,IAAI,IAAI,WAAW,IACtC,YAAY,WAAW,SAAS,OAAO;AAK3C,KAAI,YACF,gBAAgB,4BAA4B,cAAc,CAAE,EAAC;AAG/D,QAAO;AACR;;;;;;;;;;;;;;;;;AAkBD,eAAsB,iBACpBC,eACAC,QAQA;CACA,IAAI,kBAAkB,QAAQ,mBAAmB;CACjD,MAAM,YAAY,QAAQ,aAAa;CAEvC,MAAM,uBAAuB,YAAY,cAAc;AAGvD,KAAI,oBAAoB,QAAW;EACjC,MAAM,kBAAkB;AACxB,MAAI,CAAC,gBAAgB,KAAK,gBAAgB,EACxC,kBAAkB,CAAC,CAAC,EAAE,iBAAiB;CAE1C;CACD,MAAM,WAAW,CAAC,wBAAwB,EAAE,qBAAqB,SAAS,EAAE,gBAAgB,MAAM,EAAE,WAAW;CAC/G,MAAM,MAAM,MAAM,MAAM,SAAS;AACjC,KAAI,CAAC,IAAI,GACP,OAAM,IAAI,MACR;EACE,CAAC,qDAAqD,CAAC;EACvD,CAAC,aAAa,EAAE,IAAI,QAAQ;EAC5B,CAAC,aAAa,EAAE,IAAI,YAAY;CACjC,EAAC,KAAK,KAAK;CAGhB,MAAM,UAAU,MAAM,IAAI,MAAM;AAChC,QAAO;AACR"}
@@ -1,6 +1,6 @@
1
1
  const require_base = require('../messages/base.cjs');
2
- const require_ai = require('../messages/ai.cjs');
3
2
  const require_human = require('../messages/human.cjs');
3
+ const require_ai = require('../messages/ai.cjs');
4
4
  const require_base$1 = require('./base.cjs');
5
5
  require('../messages/index.cjs');
6
6
  const require_passthrough = require('./passthrough.cjs');
@@ -1,6 +1,6 @@
1
1
  import { isBaseMessage } from "../messages/base.js";
2
- import { AIMessage } from "../messages/ai.js";
3
2
  import { HumanMessage } from "../messages/human.js";
3
+ import { AIMessage } from "../messages/ai.js";
4
4
  import { RunnableBinding, RunnableLambda } from "./base.js";
5
5
  import "../messages/index.js";
6
6
  import { RunnablePassthrough } from "./passthrough.js";
@@ -37,8 +37,13 @@ var _RootEventFilter = class {
37
37
  return include;
38
38
  }
39
39
  };
40
+ const toBase64Url = (str) => {
41
+ const encoded = btoa(str);
42
+ return encoded.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
43
+ };
40
44
 
41
45
  //#endregion
42
46
  exports._RootEventFilter = _RootEventFilter;
43
47
  exports.isRunnableInterface = isRunnableInterface;
48
+ exports.toBase64Url = toBase64Url;
44
49
  //# sourceMappingURL=utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","names":["thing: any","fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }","event: StreamEvent","rootType: string"],"sources":["../../src/runnables/utils.ts"],"sourcesContent":["import { StreamEvent } from \"../tracers/event_stream.js\";\nimport type { RunnableInterface } from \"./types.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isRunnableInterface(thing: any): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n}\n\n/**\n * Utility to filter the root event in the streamEvents implementation.\n * This is simply binding the arguments to the namespace to make save on\n * a bit of typing in the streamEvents implementation.\n *\n * TODO: Refactor and remove.\n */\nexport class _RootEventFilter {\n includeNames?: string[];\n\n includeTypes?: string[];\n\n includeTags?: string[];\n\n excludeNames?: string[];\n\n excludeTypes?: string[];\n\n excludeTags?: string[];\n\n constructor(fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }) {\n this.includeNames = fields.includeNames;\n this.includeTypes = fields.includeTypes;\n this.includeTags = fields.includeTags;\n this.excludeNames = fields.excludeNames;\n this.excludeTypes = fields.excludeTypes;\n this.excludeTags = fields.excludeTags;\n }\n\n includeEvent(event: StreamEvent, rootType: string): boolean {\n let include =\n this.includeNames === undefined &&\n this.includeTypes === undefined &&\n this.includeTags === undefined;\n const eventTags = event.tags ?? [];\n\n if (this.includeNames !== undefined) {\n include = include || this.includeNames.includes(event.name);\n }\n if (this.includeTypes !== undefined) {\n include = include || this.includeTypes.includes(rootType);\n }\n if (this.includeTags !== undefined) {\n include =\n include || eventTags.some((tag) => this.includeTags?.includes(tag));\n }\n\n if (this.excludeNames !== undefined) {\n include = include && !this.excludeNames.includes(event.name);\n }\n if (this.excludeTypes !== undefined) {\n include = include && !this.excludeTypes.includes(rootType);\n }\n if (this.excludeTags !== undefined) {\n include =\n include && eventTags.every((tag) => !this.excludeTags?.includes(tag));\n }\n\n return include;\n }\n}\n"],"mappings":";;AAIA,SAAgB,oBAAoBA,OAAwC;AAC1E,QAAO,QAAQ,MAAM,cAAc;AACpC;;;;;;;;AASD,IAAa,mBAAb,MAA8B;CAC5B;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,YAAYC,QAOT;EACD,KAAK,eAAe,OAAO;EAC3B,KAAK,eAAe,OAAO;EAC3B,KAAK,cAAc,OAAO;EAC1B,KAAK,eAAe,OAAO;EAC3B,KAAK,eAAe,OAAO;EAC3B,KAAK,cAAc,OAAO;CAC3B;CAED,aAAaC,OAAoBC,UAA2B;EAC1D,IAAI,UACF,KAAK,iBAAiB,UACtB,KAAK,iBAAiB,UACtB,KAAK,gBAAgB;EACvB,MAAM,YAAY,MAAM,QAAQ,CAAE;AAElC,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,KAAK,aAAa,SAAS,MAAM,KAAK;AAE7D,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,KAAK,aAAa,SAAS,SAAS;AAE3D,MAAI,KAAK,gBAAgB,QACvB,UACE,WAAW,UAAU,KAAK,CAAC,QAAQ,KAAK,aAAa,SAAS,IAAI,CAAC;AAGvE,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,CAAC,KAAK,aAAa,SAAS,MAAM,KAAK;AAE9D,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,CAAC,KAAK,aAAa,SAAS,SAAS;AAE5D,MAAI,KAAK,gBAAgB,QACvB,UACE,WAAW,UAAU,MAAM,CAAC,QAAQ,CAAC,KAAK,aAAa,SAAS,IAAI,CAAC;AAGzE,SAAO;CACR;AACF"}
1
+ {"version":3,"file":"utils.cjs","names":["thing: any","fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }","event: StreamEvent","rootType: string","str: string"],"sources":["../../src/runnables/utils.ts"],"sourcesContent":["import { StreamEvent } from \"../tracers/event_stream.js\";\nimport type { RunnableInterface } from \"./types.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isRunnableInterface(thing: any): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n}\n\n/**\n * Utility to filter the root event in the streamEvents implementation.\n * This is simply binding the arguments to the namespace to make save on\n * a bit of typing in the streamEvents implementation.\n *\n * TODO: Refactor and remove.\n */\nexport class _RootEventFilter {\n includeNames?: string[];\n\n includeTypes?: string[];\n\n includeTags?: string[];\n\n excludeNames?: string[];\n\n excludeTypes?: string[];\n\n excludeTags?: string[];\n\n constructor(fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }) {\n this.includeNames = fields.includeNames;\n this.includeTypes = fields.includeTypes;\n this.includeTags = fields.includeTags;\n this.excludeNames = fields.excludeNames;\n this.excludeTypes = fields.excludeTypes;\n this.excludeTags = fields.excludeTags;\n }\n\n includeEvent(event: StreamEvent, rootType: string): boolean {\n let include =\n this.includeNames === undefined &&\n this.includeTypes === undefined &&\n this.includeTags === undefined;\n const eventTags = event.tags ?? [];\n\n if (this.includeNames !== undefined) {\n include = include || this.includeNames.includes(event.name);\n }\n if (this.includeTypes !== undefined) {\n include = include || this.includeTypes.includes(rootType);\n }\n if (this.includeTags !== undefined) {\n include =\n include || eventTags.some((tag) => this.includeTags?.includes(tag));\n }\n\n if (this.excludeNames !== undefined) {\n include = include && !this.excludeNames.includes(event.name);\n }\n if (this.excludeTypes !== undefined) {\n include = include && !this.excludeTypes.includes(rootType);\n }\n if (this.excludeTags !== undefined) {\n include =\n include && eventTags.every((tag) => !this.excludeTags?.includes(tag));\n }\n\n return include;\n }\n}\n\nexport const toBase64Url = (str: string): string => {\n // Use btoa for compatibility, assume ASCII\n const encoded = btoa(str);\n return encoded.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n};\n"],"mappings":";;AAIA,SAAgB,oBAAoBA,OAAwC;AAC1E,QAAO,QAAQ,MAAM,cAAc;AACpC;;;;;;;;AASD,IAAa,mBAAb,MAA8B;CAC5B;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,YAAYC,QAOT;EACD,KAAK,eAAe,OAAO;EAC3B,KAAK,eAAe,OAAO;EAC3B,KAAK,cAAc,OAAO;EAC1B,KAAK,eAAe,OAAO;EAC3B,KAAK,eAAe,OAAO;EAC3B,KAAK,cAAc,OAAO;CAC3B;CAED,aAAaC,OAAoBC,UAA2B;EAC1D,IAAI,UACF,KAAK,iBAAiB,UACtB,KAAK,iBAAiB,UACtB,KAAK,gBAAgB;EACvB,MAAM,YAAY,MAAM,QAAQ,CAAE;AAElC,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,KAAK,aAAa,SAAS,MAAM,KAAK;AAE7D,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,KAAK,aAAa,SAAS,SAAS;AAE3D,MAAI,KAAK,gBAAgB,QACvB,UACE,WAAW,UAAU,KAAK,CAAC,QAAQ,KAAK,aAAa,SAAS,IAAI,CAAC;AAGvE,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,CAAC,KAAK,aAAa,SAAS,MAAM,KAAK;AAE9D,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,CAAC,KAAK,aAAa,SAAS,SAAS;AAE5D,MAAI,KAAK,gBAAgB,QACvB,UACE,WAAW,UAAU,MAAM,CAAC,QAAQ,CAAC,KAAK,aAAa,SAAS,IAAI,CAAC;AAGzE,SAAO;CACR;AACF;AAED,MAAa,cAAc,CAACC,QAAwB;CAElD,MAAM,UAAU,KAAK,IAAI;AACzB,QAAO,QAAQ,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;AAC1E"}
@@ -36,7 +36,11 @@ var _RootEventFilter = class {
36
36
  return include;
37
37
  }
38
38
  };
39
+ const toBase64Url = (str) => {
40
+ const encoded = btoa(str);
41
+ return encoded.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
42
+ };
39
43
 
40
44
  //#endregion
41
- export { _RootEventFilter, isRunnableInterface };
45
+ export { _RootEventFilter, isRunnableInterface, toBase64Url };
42
46
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["thing: any","fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }","event: StreamEvent","rootType: string"],"sources":["../../src/runnables/utils.ts"],"sourcesContent":["import { StreamEvent } from \"../tracers/event_stream.js\";\nimport type { RunnableInterface } from \"./types.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isRunnableInterface(thing: any): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n}\n\n/**\n * Utility to filter the root event in the streamEvents implementation.\n * This is simply binding the arguments to the namespace to make save on\n * a bit of typing in the streamEvents implementation.\n *\n * TODO: Refactor and remove.\n */\nexport class _RootEventFilter {\n includeNames?: string[];\n\n includeTypes?: string[];\n\n includeTags?: string[];\n\n excludeNames?: string[];\n\n excludeTypes?: string[];\n\n excludeTags?: string[];\n\n constructor(fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }) {\n this.includeNames = fields.includeNames;\n this.includeTypes = fields.includeTypes;\n this.includeTags = fields.includeTags;\n this.excludeNames = fields.excludeNames;\n this.excludeTypes = fields.excludeTypes;\n this.excludeTags = fields.excludeTags;\n }\n\n includeEvent(event: StreamEvent, rootType: string): boolean {\n let include =\n this.includeNames === undefined &&\n this.includeTypes === undefined &&\n this.includeTags === undefined;\n const eventTags = event.tags ?? [];\n\n if (this.includeNames !== undefined) {\n include = include || this.includeNames.includes(event.name);\n }\n if (this.includeTypes !== undefined) {\n include = include || this.includeTypes.includes(rootType);\n }\n if (this.includeTags !== undefined) {\n include =\n include || eventTags.some((tag) => this.includeTags?.includes(tag));\n }\n\n if (this.excludeNames !== undefined) {\n include = include && !this.excludeNames.includes(event.name);\n }\n if (this.excludeTypes !== undefined) {\n include = include && !this.excludeTypes.includes(rootType);\n }\n if (this.excludeTags !== undefined) {\n include =\n include && eventTags.every((tag) => !this.excludeTags?.includes(tag));\n }\n\n return include;\n }\n}\n"],"mappings":";AAIA,SAAgB,oBAAoBA,OAAwC;AAC1E,QAAO,QAAQ,MAAM,cAAc;AACpC;;;;;;;;AASD,IAAa,mBAAb,MAA8B;CAC5B;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,YAAYC,QAOT;EACD,KAAK,eAAe,OAAO;EAC3B,KAAK,eAAe,OAAO;EAC3B,KAAK,cAAc,OAAO;EAC1B,KAAK,eAAe,OAAO;EAC3B,KAAK,eAAe,OAAO;EAC3B,KAAK,cAAc,OAAO;CAC3B;CAED,aAAaC,OAAoBC,UAA2B;EAC1D,IAAI,UACF,KAAK,iBAAiB,UACtB,KAAK,iBAAiB,UACtB,KAAK,gBAAgB;EACvB,MAAM,YAAY,MAAM,QAAQ,CAAE;AAElC,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,KAAK,aAAa,SAAS,MAAM,KAAK;AAE7D,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,KAAK,aAAa,SAAS,SAAS;AAE3D,MAAI,KAAK,gBAAgB,QACvB,UACE,WAAW,UAAU,KAAK,CAAC,QAAQ,KAAK,aAAa,SAAS,IAAI,CAAC;AAGvE,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,CAAC,KAAK,aAAa,SAAS,MAAM,KAAK;AAE9D,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,CAAC,KAAK,aAAa,SAAS,SAAS;AAE5D,MAAI,KAAK,gBAAgB,QACvB,UACE,WAAW,UAAU,MAAM,CAAC,QAAQ,CAAC,KAAK,aAAa,SAAS,IAAI,CAAC;AAGzE,SAAO;CACR;AACF"}
1
+ {"version":3,"file":"utils.js","names":["thing: any","fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }","event: StreamEvent","rootType: string","str: string"],"sources":["../../src/runnables/utils.ts"],"sourcesContent":["import { StreamEvent } from \"../tracers/event_stream.js\";\nimport type { RunnableInterface } from \"./types.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isRunnableInterface(thing: any): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n}\n\n/**\n * Utility to filter the root event in the streamEvents implementation.\n * This is simply binding the arguments to the namespace to make save on\n * a bit of typing in the streamEvents implementation.\n *\n * TODO: Refactor and remove.\n */\nexport class _RootEventFilter {\n includeNames?: string[];\n\n includeTypes?: string[];\n\n includeTags?: string[];\n\n excludeNames?: string[];\n\n excludeTypes?: string[];\n\n excludeTags?: string[];\n\n constructor(fields: {\n includeNames?: string[];\n includeTypes?: string[];\n includeTags?: string[];\n excludeNames?: string[];\n excludeTypes?: string[];\n excludeTags?: string[];\n }) {\n this.includeNames = fields.includeNames;\n this.includeTypes = fields.includeTypes;\n this.includeTags = fields.includeTags;\n this.excludeNames = fields.excludeNames;\n this.excludeTypes = fields.excludeTypes;\n this.excludeTags = fields.excludeTags;\n }\n\n includeEvent(event: StreamEvent, rootType: string): boolean {\n let include =\n this.includeNames === undefined &&\n this.includeTypes === undefined &&\n this.includeTags === undefined;\n const eventTags = event.tags ?? [];\n\n if (this.includeNames !== undefined) {\n include = include || this.includeNames.includes(event.name);\n }\n if (this.includeTypes !== undefined) {\n include = include || this.includeTypes.includes(rootType);\n }\n if (this.includeTags !== undefined) {\n include =\n include || eventTags.some((tag) => this.includeTags?.includes(tag));\n }\n\n if (this.excludeNames !== undefined) {\n include = include && !this.excludeNames.includes(event.name);\n }\n if (this.excludeTypes !== undefined) {\n include = include && !this.excludeTypes.includes(rootType);\n }\n if (this.excludeTags !== undefined) {\n include =\n include && eventTags.every((tag) => !this.excludeTags?.includes(tag));\n }\n\n return include;\n }\n}\n\nexport const toBase64Url = (str: string): string => {\n // Use btoa for compatibility, assume ASCII\n const encoded = btoa(str);\n return encoded.replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n};\n"],"mappings":";AAIA,SAAgB,oBAAoBA,OAAwC;AAC1E,QAAO,QAAQ,MAAM,cAAc;AACpC;;;;;;;;AASD,IAAa,mBAAb,MAA8B;CAC5B;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA,YAAYC,QAOT;EACD,KAAK,eAAe,OAAO;EAC3B,KAAK,eAAe,OAAO;EAC3B,KAAK,cAAc,OAAO;EAC1B,KAAK,eAAe,OAAO;EAC3B,KAAK,eAAe,OAAO;EAC3B,KAAK,cAAc,OAAO;CAC3B;CAED,aAAaC,OAAoBC,UAA2B;EAC1D,IAAI,UACF,KAAK,iBAAiB,UACtB,KAAK,iBAAiB,UACtB,KAAK,gBAAgB;EACvB,MAAM,YAAY,MAAM,QAAQ,CAAE;AAElC,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,KAAK,aAAa,SAAS,MAAM,KAAK;AAE7D,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,KAAK,aAAa,SAAS,SAAS;AAE3D,MAAI,KAAK,gBAAgB,QACvB,UACE,WAAW,UAAU,KAAK,CAAC,QAAQ,KAAK,aAAa,SAAS,IAAI,CAAC;AAGvE,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,CAAC,KAAK,aAAa,SAAS,MAAM,KAAK;AAE9D,MAAI,KAAK,iBAAiB,QACxB,UAAU,WAAW,CAAC,KAAK,aAAa,SAAS,SAAS;AAE5D,MAAI,KAAK,gBAAgB,QACvB,UACE,WAAW,UAAU,MAAM,CAAC,QAAQ,CAAC,KAAK,aAAa,SAAS,IAAI,CAAC;AAGzE,SAAO;CACR;AACF;AAED,MAAa,cAAc,CAACC,QAAwB;CAElD,MAAM,UAAU,KAAK,IAAI;AACzB,QAAO,QAAQ,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG;AAC1E"}
@@ -1,15 +1,11 @@
1
1
  const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
2
  const require_signal = require('./signal.cjs');
3
+ const require_index = require('./p-retry/index.cjs');
3
4
  const p_queue = require_rolldown_runtime.__toESM(require("p-queue"));
4
5
 
5
6
  //#region src/utils/async_caller.ts
6
7
  var async_caller_exports = {};
7
8
  require_rolldown_runtime.__export(async_caller_exports, { AsyncCaller: () => AsyncCaller });
8
- let pRetryModule = null;
9
- async function getPRetry() {
10
- if (!pRetryModule) pRetryModule = await import("p-retry");
11
- return pRetryModule.default;
12
- }
13
9
  const STATUS_NO_RETRY = [
14
10
  400,
15
11
  401,
@@ -58,8 +54,7 @@ var AsyncCaller = class {
58
54
  this.queue = new PQueue({ concurrency: this.maxConcurrency });
59
55
  }
60
56
  async call(callable, ...args) {
61
- const pRetry = await getPRetry();
62
- return this.queue.add(() => pRetry(() => callable(...args).catch((error) => {
57
+ return this.queue.add(() => require_index.pRetry(() => callable(...args).catch((error) => {
63
58
  if (error instanceof Error) throw error;
64
59
  else throw new Error(error);
65
60
  }), {
@@ -1 +1 @@
1
- {"version":3,"file":"async_caller.cjs","names":["pRetryModule: typeof import(\"p-retry\") | null","error: any","params: AsyncCallerParams","PQueueMod","callable: T","options: AsyncCallerCallOptions","listener: (() => void) | undefined","getAbortSignalError"],"sources":["../../src/utils/async_caller.ts"],"sourcesContent":["import PQueueMod from \"p-queue\";\n\nimport { getAbortSignalError } from \"./signal.js\";\n\n// p-retry is ESM-only, so we use dynamic import for CJS compatibility.\n// The module is cached after first import, so subsequent calls are essentially free.\n// This approach is recommended by the p-retry author for async contexts:\n// https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\nlet pRetryModule: typeof import(\"p-retry\") | null = null;\n\nasync function getPRetry() {\n if (!pRetryModule) {\n pRetryModule = await import(\"p-retry\");\n }\n return pRetryModule.default;\n}\n\nconst STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment Required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 409, // Conflict\n];\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst defaultFailedAttemptHandler = (error: any) => {\n if (\n error.message.startsWith(\"Cancel\") ||\n error.message.startsWith(\"AbortError\") ||\n error.name === \"AbortError\"\n ) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n throw error;\n }\n const status =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (error as any)?.response?.status ?? (error as any)?.status;\n if (status && STATUS_NO_RETRY.includes(+status)) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.error?.code === \"insufficient_quota\") {\n const err = new Error(error?.message);\n err.name = \"InsufficientQuotaError\";\n throw err;\n }\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type FailedAttemptHandler = (error: any) => any;\n\nexport interface AsyncCallerParams {\n /**\n * The maximum number of concurrent calls that can be made.\n * Defaults to `Infinity`, which means no limit.\n */\n maxConcurrency?: number;\n /**\n * The maximum number of retries that can be made for a single call,\n * with an exponential backoff between each attempt. Defaults to 6.\n */\n maxRetries?: number;\n /**\n * Custom handler to handle failed attempts. Takes the originally thrown\n * error object as input, and should itself throw an error if the input\n * error is not retryable.\n */\n onFailedAttempt?: FailedAttemptHandler;\n}\n\nexport interface AsyncCallerCallOptions {\n signal?: AbortSignal;\n}\n\n/**\n * A class that can be used to make async calls with concurrency and retry logic.\n *\n * This is useful for making calls to any kind of \"expensive\" external resource,\n * be it because it's rate-limited, subject to network issues, etc.\n *\n * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults\n * to `Infinity`. This means that by default, all calls will be made in parallel.\n *\n * Retries are limited by the `maxRetries` parameter, which defaults to 6. This\n * means that by default, each call will be retried up to 6 times, with an\n * exponential backoff between each attempt.\n */\nexport class AsyncCaller {\n protected maxConcurrency: AsyncCallerParams[\"maxConcurrency\"];\n\n protected maxRetries: AsyncCallerParams[\"maxRetries\"];\n\n protected onFailedAttempt: AsyncCallerParams[\"onFailedAttempt\"];\n\n private queue: typeof import(\"p-queue\")[\"default\"][\"prototype\"];\n\n constructor(params: AsyncCallerParams) {\n this.maxConcurrency = params.maxConcurrency ?? Infinity;\n this.maxRetries = params.maxRetries ?? 6;\n this.onFailedAttempt =\n params.onFailedAttempt ?? defaultFailedAttemptHandler;\n\n const PQueue = (\n \"default\" in PQueueMod ? PQueueMod.default : PQueueMod\n ) as typeof PQueueMod;\n this.queue = new PQueue({ concurrency: this.maxConcurrency });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async call<A extends any[], T extends (...args: A) => Promise<any>>(\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n const pRetry = await getPRetry();\n return this.queue.add(\n () =>\n pRetry(\n () =>\n callable(...args).catch((error) => {\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof Error) {\n throw error;\n } else {\n throw new Error(error);\n }\n }),\n {\n onFailedAttempt: ({ error }) => this.onFailedAttempt?.(error),\n retries: this.maxRetries,\n randomize: true,\n // If needed we can change some of the defaults here,\n // but they're quite sensible.\n }\n ),\n { throwOnTimeout: true }\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callWithOptions<A extends any[], T extends (...args: A) => Promise<any>>(\n options: AsyncCallerCallOptions,\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n // Note this doesn't cancel the underlying request,\n // when available prefer to use the signal option of the underlying call\n if (options.signal) {\n let listener: (() => void) | undefined;\n return Promise.race([\n this.call<A, T>(callable, ...args),\n new Promise<never>((_, reject) => {\n listener = () => {\n reject(getAbortSignalError(options.signal));\n };\n options.signal?.addEventListener(\"abort\", listener);\n }),\n ]).finally(() => {\n if (options.signal && listener) {\n options.signal.removeEventListener(\"abort\", listener);\n }\n });\n }\n return this.call<A, T>(callable, ...args);\n }\n\n fetch(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {\n return this.call(() =>\n fetch(...args).then((res) => (res.ok ? res : Promise.reject(res)))\n );\n }\n}\n"],"mappings":";;;;;;;AAQA,IAAIA,eAAgD;AAEpD,eAAe,YAAY;AACzB,KAAI,CAAC,cACH,eAAe,MAAM,OAAO;AAE9B,QAAO,aAAa;AACrB;AAED,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAGD,MAAM,8BAA8B,CAACC,UAAe;AAClD,KACE,MAAM,QAAQ,WAAW,SAAS,IAClC,MAAM,QAAQ,WAAW,aAAa,IACtC,MAAM,SAAS,aAEf,OAAM;AAGR,KAAK,OAAe,SAAS,eAC3B,OAAM;CAER,MAAM,SAEH,OAAe,UAAU,UAAW,OAAe;AACtD,KAAI,UAAU,gBAAgB,SAAS,CAAC,OAAO,CAC7C,OAAM;AAGR,KAAK,OAAe,OAAO,SAAS,sBAAsB;EACxD,MAAM,MAAM,IAAI,MAAM,OAAO;EAC7B,IAAI,OAAO;AACX,QAAM;CACP;AACF;;;;;;;;;;;;;;AAyCD,IAAa,cAAb,MAAyB;CACvB,AAAU;CAEV,AAAU;CAEV,AAAU;CAEV,AAAQ;CAER,YAAYC,QAA2B;EACrC,KAAK,iBAAiB,OAAO,kBAAkB;EAC/C,KAAK,aAAa,OAAO,cAAc;EACvC,KAAK,kBACH,OAAO,mBAAmB;EAE5B,MAAM,SACJ,aAAaC,kBAAYA,gBAAU,UAAUA;EAE/C,KAAK,QAAQ,IAAI,OAAO,EAAE,aAAa,KAAK,eAAgB;CAC7D;CAGD,MAAM,KACJC,UACA,GAAG,MAC8B;EACjC,MAAM,SAAS,MAAM,WAAW;AAChC,SAAO,KAAK,MAAM,IAChB,MACE,OACE,MACE,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU;AAEjC,OAAI,iBAAiB,MACnB,OAAM;OAEN,OAAM,IAAI,MAAM;EAEnB,EAAC,EACJ;GACE,iBAAiB,CAAC,EAAE,OAAO,KAAK,KAAK,kBAAkB,MAAM;GAC7D,SAAS,KAAK;GACd,WAAW;EAGZ,EACF,EACH,EAAE,gBAAgB,KAAM,EACzB;CACF;CAGD,gBACEC,SACAD,UACA,GAAG,MAC8B;AAGjC,MAAI,QAAQ,QAAQ;GAClB,IAAIE;AACJ,UAAO,QAAQ,KAAK,CAClB,KAAK,KAAW,UAAU,GAAG,KAAK,EAClC,IAAI,QAAe,CAAC,GAAG,WAAW;IAChC,WAAW,MAAM;KACf,OAAOC,mCAAoB,QAAQ,OAAO,CAAC;IAC5C;IACD,QAAQ,QAAQ,iBAAiB,SAAS,SAAS;GACpD,EACF,EAAC,CAAC,QAAQ,MAAM;AACf,QAAI,QAAQ,UAAU,UACpB,QAAQ,OAAO,oBAAoB,SAAS,SAAS;GAExD,EAAC;EACH;AACD,SAAO,KAAK,KAAW,UAAU,GAAG,KAAK;CAC1C;CAED,MAAM,GAAG,MAA0D;AACjE,SAAO,KAAK,KAAK,MACf,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAS,IAAI,KAAK,MAAM,QAAQ,OAAO,IAAI,CAAE,CACnE;CACF;AACF"}
1
+ {"version":3,"file":"async_caller.cjs","names":["error: any","params: AsyncCallerParams","PQueueMod","callable: T","pRetry","options: AsyncCallerCallOptions","listener: (() => void) | undefined","getAbortSignalError"],"sources":["../../src/utils/async_caller.ts"],"sourcesContent":["import PQueueMod from \"p-queue\";\n\nimport { getAbortSignalError } from \"./signal.js\";\nimport pRetry from \"./p-retry/index.js\";\n\nconst STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment Required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 409, // Conflict\n];\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst defaultFailedAttemptHandler = (error: any) => {\n if (\n error.message.startsWith(\"Cancel\") ||\n error.message.startsWith(\"AbortError\") ||\n error.name === \"AbortError\"\n ) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n throw error;\n }\n const status =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (error as any)?.response?.status ?? (error as any)?.status;\n if (status && STATUS_NO_RETRY.includes(+status)) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.error?.code === \"insufficient_quota\") {\n const err = new Error(error?.message);\n err.name = \"InsufficientQuotaError\";\n throw err;\n }\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type FailedAttemptHandler = (error: any) => any;\n\nexport interface AsyncCallerParams {\n /**\n * The maximum number of concurrent calls that can be made.\n * Defaults to `Infinity`, which means no limit.\n */\n maxConcurrency?: number;\n /**\n * The maximum number of retries that can be made for a single call,\n * with an exponential backoff between each attempt. Defaults to 6.\n */\n maxRetries?: number;\n /**\n * Custom handler to handle failed attempts. Takes the originally thrown\n * error object as input, and should itself throw an error if the input\n * error is not retryable.\n */\n onFailedAttempt?: FailedAttemptHandler;\n}\n\nexport interface AsyncCallerCallOptions {\n signal?: AbortSignal;\n}\n\n/**\n * A class that can be used to make async calls with concurrency and retry logic.\n *\n * This is useful for making calls to any kind of \"expensive\" external resource,\n * be it because it's rate-limited, subject to network issues, etc.\n *\n * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults\n * to `Infinity`. This means that by default, all calls will be made in parallel.\n *\n * Retries are limited by the `maxRetries` parameter, which defaults to 6. This\n * means that by default, each call will be retried up to 6 times, with an\n * exponential backoff between each attempt.\n */\nexport class AsyncCaller {\n protected maxConcurrency: AsyncCallerParams[\"maxConcurrency\"];\n\n protected maxRetries: AsyncCallerParams[\"maxRetries\"];\n\n protected onFailedAttempt: AsyncCallerParams[\"onFailedAttempt\"];\n\n private queue: typeof import(\"p-queue\")[\"default\"][\"prototype\"];\n\n constructor(params: AsyncCallerParams) {\n this.maxConcurrency = params.maxConcurrency ?? Infinity;\n this.maxRetries = params.maxRetries ?? 6;\n this.onFailedAttempt =\n params.onFailedAttempt ?? defaultFailedAttemptHandler;\n\n const PQueue = (\n \"default\" in PQueueMod ? PQueueMod.default : PQueueMod\n ) as typeof PQueueMod;\n this.queue = new PQueue({ concurrency: this.maxConcurrency });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async call<A extends any[], T extends (...args: A) => Promise<any>>(\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n return this.queue.add(\n () =>\n pRetry(\n () =>\n callable(...args).catch((error) => {\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof Error) {\n throw error;\n } else {\n throw new Error(error);\n }\n }),\n {\n onFailedAttempt: ({ error }) => this.onFailedAttempt?.(error),\n retries: this.maxRetries,\n randomize: true,\n // If needed we can change some of the defaults here,\n // but they're quite sensible.\n }\n ),\n { throwOnTimeout: true }\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callWithOptions<A extends any[], T extends (...args: A) => Promise<any>>(\n options: AsyncCallerCallOptions,\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n // Note this doesn't cancel the underlying request,\n // when available prefer to use the signal option of the underlying call\n if (options.signal) {\n let listener: (() => void) | undefined;\n return Promise.race([\n this.call<A, T>(callable, ...args),\n new Promise<never>((_, reject) => {\n listener = () => {\n reject(getAbortSignalError(options.signal));\n };\n options.signal?.addEventListener(\"abort\", listener);\n }),\n ]).finally(() => {\n if (options.signal && listener) {\n options.signal.removeEventListener(\"abort\", listener);\n }\n });\n }\n return this.call<A, T>(callable, ...args);\n }\n\n fetch(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {\n return this.call(() =>\n fetch(...args).then((res) => (res.ok ? res : Promise.reject(res)))\n );\n }\n}\n"],"mappings":";;;;;;;;AAKA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAGD,MAAM,8BAA8B,CAACA,UAAe;AAClD,KACE,MAAM,QAAQ,WAAW,SAAS,IAClC,MAAM,QAAQ,WAAW,aAAa,IACtC,MAAM,SAAS,aAEf,OAAM;AAGR,KAAK,OAAe,SAAS,eAC3B,OAAM;CAER,MAAM,SAEH,OAAe,UAAU,UAAW,OAAe;AACtD,KAAI,UAAU,gBAAgB,SAAS,CAAC,OAAO,CAC7C,OAAM;AAGR,KAAK,OAAe,OAAO,SAAS,sBAAsB;EACxD,MAAM,MAAM,IAAI,MAAM,OAAO;EAC7B,IAAI,OAAO;AACX,QAAM;CACP;AACF;;;;;;;;;;;;;;AAyCD,IAAa,cAAb,MAAyB;CACvB,AAAU;CAEV,AAAU;CAEV,AAAU;CAEV,AAAQ;CAER,YAAYC,QAA2B;EACrC,KAAK,iBAAiB,OAAO,kBAAkB;EAC/C,KAAK,aAAa,OAAO,cAAc;EACvC,KAAK,kBACH,OAAO,mBAAmB;EAE5B,MAAM,SACJ,aAAaC,kBAAYA,gBAAU,UAAUA;EAE/C,KAAK,QAAQ,IAAI,OAAO,EAAE,aAAa,KAAK,eAAgB;CAC7D;CAGD,MAAM,KACJC,UACA,GAAG,MAC8B;AACjC,SAAO,KAAK,MAAM,IAChB,MACEC,qBACE,MACE,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU;AAEjC,OAAI,iBAAiB,MACnB,OAAM;OAEN,OAAM,IAAI,MAAM;EAEnB,EAAC,EACJ;GACE,iBAAiB,CAAC,EAAE,OAAO,KAAK,KAAK,kBAAkB,MAAM;GAC7D,SAAS,KAAK;GACd,WAAW;EAGZ,EACF,EACH,EAAE,gBAAgB,KAAM,EACzB;CACF;CAGD,gBACEC,SACAF,UACA,GAAG,MAC8B;AAGjC,MAAI,QAAQ,QAAQ;GAClB,IAAIG;AACJ,UAAO,QAAQ,KAAK,CAClB,KAAK,KAAW,UAAU,GAAG,KAAK,EAClC,IAAI,QAAe,CAAC,GAAG,WAAW;IAChC,WAAW,MAAM;KACf,OAAOC,mCAAoB,QAAQ,OAAO,CAAC;IAC5C;IACD,QAAQ,QAAQ,iBAAiB,SAAS,SAAS;GACpD,EACF,EAAC,CAAC,QAAQ,MAAM;AACf,QAAI,QAAQ,UAAU,UACpB,QAAQ,OAAO,oBAAoB,SAAS,SAAS;GAExD,EAAC;EACH;AACD,SAAO,KAAK,KAAW,UAAU,GAAG,KAAK;CAC1C;CAED,MAAM,GAAG,MAA0D;AACjE,SAAO,KAAK,KAAK,MACf,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAS,IAAI,KAAK,MAAM,QAAQ,OAAO,IAAI,CAAE,CACnE;CACF;AACF"}
@@ -1,15 +1,11 @@
1
1
  import { __export } from "../_virtual/rolldown_runtime.js";
2
2
  import { getAbortSignalError } from "./signal.js";
3
+ import { pRetry } from "./p-retry/index.js";
3
4
  import PQueueMod from "p-queue";
4
5
 
5
6
  //#region src/utils/async_caller.ts
6
7
  var async_caller_exports = {};
7
8
  __export(async_caller_exports, { AsyncCaller: () => AsyncCaller });
8
- let pRetryModule = null;
9
- async function getPRetry() {
10
- if (!pRetryModule) pRetryModule = await import("p-retry");
11
- return pRetryModule.default;
12
- }
13
9
  const STATUS_NO_RETRY = [
14
10
  400,
15
11
  401,
@@ -58,7 +54,6 @@ var AsyncCaller = class {
58
54
  this.queue = new PQueue({ concurrency: this.maxConcurrency });
59
55
  }
60
56
  async call(callable, ...args) {
61
- const pRetry = await getPRetry();
62
57
  return this.queue.add(() => pRetry(() => callable(...args).catch((error) => {
63
58
  if (error instanceof Error) throw error;
64
59
  else throw new Error(error);
@@ -1 +1 @@
1
- {"version":3,"file":"async_caller.js","names":["pRetryModule: typeof import(\"p-retry\") | null","error: any","params: AsyncCallerParams","callable: T","options: AsyncCallerCallOptions","listener: (() => void) | undefined"],"sources":["../../src/utils/async_caller.ts"],"sourcesContent":["import PQueueMod from \"p-queue\";\n\nimport { getAbortSignalError } from \"./signal.js\";\n\n// p-retry is ESM-only, so we use dynamic import for CJS compatibility.\n// The module is cached after first import, so subsequent calls are essentially free.\n// This approach is recommended by the p-retry author for async contexts:\n// https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\nlet pRetryModule: typeof import(\"p-retry\") | null = null;\n\nasync function getPRetry() {\n if (!pRetryModule) {\n pRetryModule = await import(\"p-retry\");\n }\n return pRetryModule.default;\n}\n\nconst STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment Required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 409, // Conflict\n];\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst defaultFailedAttemptHandler = (error: any) => {\n if (\n error.message.startsWith(\"Cancel\") ||\n error.message.startsWith(\"AbortError\") ||\n error.name === \"AbortError\"\n ) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n throw error;\n }\n const status =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (error as any)?.response?.status ?? (error as any)?.status;\n if (status && STATUS_NO_RETRY.includes(+status)) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.error?.code === \"insufficient_quota\") {\n const err = new Error(error?.message);\n err.name = \"InsufficientQuotaError\";\n throw err;\n }\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type FailedAttemptHandler = (error: any) => any;\n\nexport interface AsyncCallerParams {\n /**\n * The maximum number of concurrent calls that can be made.\n * Defaults to `Infinity`, which means no limit.\n */\n maxConcurrency?: number;\n /**\n * The maximum number of retries that can be made for a single call,\n * with an exponential backoff between each attempt. Defaults to 6.\n */\n maxRetries?: number;\n /**\n * Custom handler to handle failed attempts. Takes the originally thrown\n * error object as input, and should itself throw an error if the input\n * error is not retryable.\n */\n onFailedAttempt?: FailedAttemptHandler;\n}\n\nexport interface AsyncCallerCallOptions {\n signal?: AbortSignal;\n}\n\n/**\n * A class that can be used to make async calls with concurrency and retry logic.\n *\n * This is useful for making calls to any kind of \"expensive\" external resource,\n * be it because it's rate-limited, subject to network issues, etc.\n *\n * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults\n * to `Infinity`. This means that by default, all calls will be made in parallel.\n *\n * Retries are limited by the `maxRetries` parameter, which defaults to 6. This\n * means that by default, each call will be retried up to 6 times, with an\n * exponential backoff between each attempt.\n */\nexport class AsyncCaller {\n protected maxConcurrency: AsyncCallerParams[\"maxConcurrency\"];\n\n protected maxRetries: AsyncCallerParams[\"maxRetries\"];\n\n protected onFailedAttempt: AsyncCallerParams[\"onFailedAttempt\"];\n\n private queue: typeof import(\"p-queue\")[\"default\"][\"prototype\"];\n\n constructor(params: AsyncCallerParams) {\n this.maxConcurrency = params.maxConcurrency ?? Infinity;\n this.maxRetries = params.maxRetries ?? 6;\n this.onFailedAttempt =\n params.onFailedAttempt ?? defaultFailedAttemptHandler;\n\n const PQueue = (\n \"default\" in PQueueMod ? PQueueMod.default : PQueueMod\n ) as typeof PQueueMod;\n this.queue = new PQueue({ concurrency: this.maxConcurrency });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async call<A extends any[], T extends (...args: A) => Promise<any>>(\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n const pRetry = await getPRetry();\n return this.queue.add(\n () =>\n pRetry(\n () =>\n callable(...args).catch((error) => {\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof Error) {\n throw error;\n } else {\n throw new Error(error);\n }\n }),\n {\n onFailedAttempt: ({ error }) => this.onFailedAttempt?.(error),\n retries: this.maxRetries,\n randomize: true,\n // If needed we can change some of the defaults here,\n // but they're quite sensible.\n }\n ),\n { throwOnTimeout: true }\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callWithOptions<A extends any[], T extends (...args: A) => Promise<any>>(\n options: AsyncCallerCallOptions,\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n // Note this doesn't cancel the underlying request,\n // when available prefer to use the signal option of the underlying call\n if (options.signal) {\n let listener: (() => void) | undefined;\n return Promise.race([\n this.call<A, T>(callable, ...args),\n new Promise<never>((_, reject) => {\n listener = () => {\n reject(getAbortSignalError(options.signal));\n };\n options.signal?.addEventListener(\"abort\", listener);\n }),\n ]).finally(() => {\n if (options.signal && listener) {\n options.signal.removeEventListener(\"abort\", listener);\n }\n });\n }\n return this.call<A, T>(callable, ...args);\n }\n\n fetch(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {\n return this.call(() =>\n fetch(...args).then((res) => (res.ok ? res : Promise.reject(res)))\n );\n }\n}\n"],"mappings":";;;;;;;AAQA,IAAIA,eAAgD;AAEpD,eAAe,YAAY;AACzB,KAAI,CAAC,cACH,eAAe,MAAM,OAAO;AAE9B,QAAO,aAAa;AACrB;AAED,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAGD,MAAM,8BAA8B,CAACC,UAAe;AAClD,KACE,MAAM,QAAQ,WAAW,SAAS,IAClC,MAAM,QAAQ,WAAW,aAAa,IACtC,MAAM,SAAS,aAEf,OAAM;AAGR,KAAK,OAAe,SAAS,eAC3B,OAAM;CAER,MAAM,SAEH,OAAe,UAAU,UAAW,OAAe;AACtD,KAAI,UAAU,gBAAgB,SAAS,CAAC,OAAO,CAC7C,OAAM;AAGR,KAAK,OAAe,OAAO,SAAS,sBAAsB;EACxD,MAAM,MAAM,IAAI,MAAM,OAAO;EAC7B,IAAI,OAAO;AACX,QAAM;CACP;AACF;;;;;;;;;;;;;;AAyCD,IAAa,cAAb,MAAyB;CACvB,AAAU;CAEV,AAAU;CAEV,AAAU;CAEV,AAAQ;CAER,YAAYC,QAA2B;EACrC,KAAK,iBAAiB,OAAO,kBAAkB;EAC/C,KAAK,aAAa,OAAO,cAAc;EACvC,KAAK,kBACH,OAAO,mBAAmB;EAE5B,MAAM,SACJ,aAAa,YAAY,UAAU,UAAU;EAE/C,KAAK,QAAQ,IAAI,OAAO,EAAE,aAAa,KAAK,eAAgB;CAC7D;CAGD,MAAM,KACJC,UACA,GAAG,MAC8B;EACjC,MAAM,SAAS,MAAM,WAAW;AAChC,SAAO,KAAK,MAAM,IAChB,MACE,OACE,MACE,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU;AAEjC,OAAI,iBAAiB,MACnB,OAAM;OAEN,OAAM,IAAI,MAAM;EAEnB,EAAC,EACJ;GACE,iBAAiB,CAAC,EAAE,OAAO,KAAK,KAAK,kBAAkB,MAAM;GAC7D,SAAS,KAAK;GACd,WAAW;EAGZ,EACF,EACH,EAAE,gBAAgB,KAAM,EACzB;CACF;CAGD,gBACEC,SACAD,UACA,GAAG,MAC8B;AAGjC,MAAI,QAAQ,QAAQ;GAClB,IAAIE;AACJ,UAAO,QAAQ,KAAK,CAClB,KAAK,KAAW,UAAU,GAAG,KAAK,EAClC,IAAI,QAAe,CAAC,GAAG,WAAW;IAChC,WAAW,MAAM;KACf,OAAO,oBAAoB,QAAQ,OAAO,CAAC;IAC5C;IACD,QAAQ,QAAQ,iBAAiB,SAAS,SAAS;GACpD,EACF,EAAC,CAAC,QAAQ,MAAM;AACf,QAAI,QAAQ,UAAU,UACpB,QAAQ,OAAO,oBAAoB,SAAS,SAAS;GAExD,EAAC;EACH;AACD,SAAO,KAAK,KAAW,UAAU,GAAG,KAAK;CAC1C;CAED,MAAM,GAAG,MAA0D;AACjE,SAAO,KAAK,KAAK,MACf,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAS,IAAI,KAAK,MAAM,QAAQ,OAAO,IAAI,CAAE,CACnE;CACF;AACF"}
1
+ {"version":3,"file":"async_caller.js","names":["error: any","params: AsyncCallerParams","callable: T","options: AsyncCallerCallOptions","listener: (() => void) | undefined"],"sources":["../../src/utils/async_caller.ts"],"sourcesContent":["import PQueueMod from \"p-queue\";\n\nimport { getAbortSignalError } from \"./signal.js\";\nimport pRetry from \"./p-retry/index.js\";\n\nconst STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment Required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 409, // Conflict\n];\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst defaultFailedAttemptHandler = (error: any) => {\n if (\n error.message.startsWith(\"Cancel\") ||\n error.message.startsWith(\"AbortError\") ||\n error.name === \"AbortError\"\n ) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n throw error;\n }\n const status =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (error as any)?.response?.status ?? (error as any)?.status;\n if (status && STATUS_NO_RETRY.includes(+status)) {\n throw error;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.error?.code === \"insufficient_quota\") {\n const err = new Error(error?.message);\n err.name = \"InsufficientQuotaError\";\n throw err;\n }\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type FailedAttemptHandler = (error: any) => any;\n\nexport interface AsyncCallerParams {\n /**\n * The maximum number of concurrent calls that can be made.\n * Defaults to `Infinity`, which means no limit.\n */\n maxConcurrency?: number;\n /**\n * The maximum number of retries that can be made for a single call,\n * with an exponential backoff between each attempt. Defaults to 6.\n */\n maxRetries?: number;\n /**\n * Custom handler to handle failed attempts. Takes the originally thrown\n * error object as input, and should itself throw an error if the input\n * error is not retryable.\n */\n onFailedAttempt?: FailedAttemptHandler;\n}\n\nexport interface AsyncCallerCallOptions {\n signal?: AbortSignal;\n}\n\n/**\n * A class that can be used to make async calls with concurrency and retry logic.\n *\n * This is useful for making calls to any kind of \"expensive\" external resource,\n * be it because it's rate-limited, subject to network issues, etc.\n *\n * Concurrent calls are limited by the `maxConcurrency` parameter, which defaults\n * to `Infinity`. This means that by default, all calls will be made in parallel.\n *\n * Retries are limited by the `maxRetries` parameter, which defaults to 6. This\n * means that by default, each call will be retried up to 6 times, with an\n * exponential backoff between each attempt.\n */\nexport class AsyncCaller {\n protected maxConcurrency: AsyncCallerParams[\"maxConcurrency\"];\n\n protected maxRetries: AsyncCallerParams[\"maxRetries\"];\n\n protected onFailedAttempt: AsyncCallerParams[\"onFailedAttempt\"];\n\n private queue: typeof import(\"p-queue\")[\"default\"][\"prototype\"];\n\n constructor(params: AsyncCallerParams) {\n this.maxConcurrency = params.maxConcurrency ?? Infinity;\n this.maxRetries = params.maxRetries ?? 6;\n this.onFailedAttempt =\n params.onFailedAttempt ?? defaultFailedAttemptHandler;\n\n const PQueue = (\n \"default\" in PQueueMod ? PQueueMod.default : PQueueMod\n ) as typeof PQueueMod;\n this.queue = new PQueue({ concurrency: this.maxConcurrency });\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async call<A extends any[], T extends (...args: A) => Promise<any>>(\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n return this.queue.add(\n () =>\n pRetry(\n () =>\n callable(...args).catch((error) => {\n // eslint-disable-next-line no-instanceof/no-instanceof\n if (error instanceof Error) {\n throw error;\n } else {\n throw new Error(error);\n }\n }),\n {\n onFailedAttempt: ({ error }) => this.onFailedAttempt?.(error),\n retries: this.maxRetries,\n randomize: true,\n // If needed we can change some of the defaults here,\n // but they're quite sensible.\n }\n ),\n { throwOnTimeout: true }\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callWithOptions<A extends any[], T extends (...args: A) => Promise<any>>(\n options: AsyncCallerCallOptions,\n callable: T,\n ...args: Parameters<T>\n ): Promise<Awaited<ReturnType<T>>> {\n // Note this doesn't cancel the underlying request,\n // when available prefer to use the signal option of the underlying call\n if (options.signal) {\n let listener: (() => void) | undefined;\n return Promise.race([\n this.call<A, T>(callable, ...args),\n new Promise<never>((_, reject) => {\n listener = () => {\n reject(getAbortSignalError(options.signal));\n };\n options.signal?.addEventListener(\"abort\", listener);\n }),\n ]).finally(() => {\n if (options.signal && listener) {\n options.signal.removeEventListener(\"abort\", listener);\n }\n });\n }\n return this.call<A, T>(callable, ...args);\n }\n\n fetch(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {\n return this.call(() =>\n fetch(...args).then((res) => (res.ok ? res : Promise.reject(res)))\n );\n }\n}\n"],"mappings":";;;;;;;;AAKA,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAGD,MAAM,8BAA8B,CAACA,UAAe;AAClD,KACE,MAAM,QAAQ,WAAW,SAAS,IAClC,MAAM,QAAQ,WAAW,aAAa,IACtC,MAAM,SAAS,aAEf,OAAM;AAGR,KAAK,OAAe,SAAS,eAC3B,OAAM;CAER,MAAM,SAEH,OAAe,UAAU,UAAW,OAAe;AACtD,KAAI,UAAU,gBAAgB,SAAS,CAAC,OAAO,CAC7C,OAAM;AAGR,KAAK,OAAe,OAAO,SAAS,sBAAsB;EACxD,MAAM,MAAM,IAAI,MAAM,OAAO;EAC7B,IAAI,OAAO;AACX,QAAM;CACP;AACF;;;;;;;;;;;;;;AAyCD,IAAa,cAAb,MAAyB;CACvB,AAAU;CAEV,AAAU;CAEV,AAAU;CAEV,AAAQ;CAER,YAAYC,QAA2B;EACrC,KAAK,iBAAiB,OAAO,kBAAkB;EAC/C,KAAK,aAAa,OAAO,cAAc;EACvC,KAAK,kBACH,OAAO,mBAAmB;EAE5B,MAAM,SACJ,aAAa,YAAY,UAAU,UAAU;EAE/C,KAAK,QAAQ,IAAI,OAAO,EAAE,aAAa,KAAK,eAAgB;CAC7D;CAGD,MAAM,KACJC,UACA,GAAG,MAC8B;AACjC,SAAO,KAAK,MAAM,IAChB,MACE,OACE,MACE,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU;AAEjC,OAAI,iBAAiB,MACnB,OAAM;OAEN,OAAM,IAAI,MAAM;EAEnB,EAAC,EACJ;GACE,iBAAiB,CAAC,EAAE,OAAO,KAAK,KAAK,kBAAkB,MAAM;GAC7D,SAAS,KAAK;GACd,WAAW;EAGZ,EACF,EACH,EAAE,gBAAgB,KAAM,EACzB;CACF;CAGD,gBACEC,SACAD,UACA,GAAG,MAC8B;AAGjC,MAAI,QAAQ,QAAQ;GAClB,IAAIE;AACJ,UAAO,QAAQ,KAAK,CAClB,KAAK,KAAW,UAAU,GAAG,KAAK,EAClC,IAAI,QAAe,CAAC,GAAG,WAAW;IAChC,WAAW,MAAM;KACf,OAAO,oBAAoB,QAAQ,OAAO,CAAC;IAC5C;IACD,QAAQ,QAAQ,iBAAiB,SAAS,SAAS;GACpD,EACF,EAAC,CAAC,QAAQ,MAAM;AACf,QAAI,QAAQ,UAAU,UACpB,QAAQ,OAAO,oBAAoB,SAAS,SAAS;GAExD,EAAC;EACH;AACD,SAAO,KAAK,KAAW,UAAU,GAAG,KAAK;CAC1C;CAED,MAAM,GAAG,MAA0D;AACjE,SAAO,KAAK,KAAK,MACf,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAS,IAAI,KAAK,MAAM,QAAQ,OAAO,IAAI,CAAE,CACnE;CACF;AACF"}
@@ -0,0 +1,27 @@
1
+
2
+ //#region src/utils/is-network-error/index.js
3
+ const objectToString = Object.prototype.toString;
4
+ const isError = (value) => objectToString.call(value) === "[object Error]";
5
+ const errorMessages = new Set([
6
+ "network error",
7
+ "Failed to fetch",
8
+ "NetworkError when attempting to fetch resource.",
9
+ "The Internet connection appears to be offline.",
10
+ "Network request failed",
11
+ "fetch failed",
12
+ "terminated",
13
+ " A network error occurred.",
14
+ "Network connection lost"
15
+ ]);
16
+ function isNetworkError(error) {
17
+ const isValid = error && isError(error) && error.name === "TypeError" && typeof error.message === "string";
18
+ if (!isValid) return false;
19
+ const { message, stack } = error;
20
+ if (message === "Load failed") return stack === void 0 || "__sentry_captured__" in error;
21
+ if (message.startsWith("error sending request for url")) return true;
22
+ return errorMessages.has(message);
23
+ }
24
+
25
+ //#endregion
26
+ exports.isNetworkError = isNetworkError;
27
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/utils/is-network-error/index.js"],"sourcesContent":["/* eslint-disable */\nconst objectToString = Object.prototype.toString;\n\nconst isError = (value) => objectToString.call(value) === \"[object Error]\";\n\nconst errorMessages = new Set([\n \"network error\", // Chrome\n \"Failed to fetch\", // Chrome\n \"NetworkError when attempting to fetch resource.\", // Firefox\n \"The Internet connection appears to be offline.\", // Safari 16\n \"Network request failed\", // `cross-fetch`\n \"fetch failed\", // Undici (Node.js)\n \"terminated\", // Undici (Node.js)\n \" A network error occurred.\", // Bun (WebKit)\n \"Network connection lost\", // Cloudflare Workers (fetch)\n]);\n\nexport default function isNetworkError(error) {\n const isValid =\n error &&\n isError(error) &&\n error.name === \"TypeError\" &&\n typeof error.message === \"string\";\n\n if (!isValid) {\n return false;\n }\n\n const { message, stack } = error;\n\n // Safari 17+ has generic message but no stack for network errors\n if (message === \"Load failed\") {\n return (\n stack === undefined ||\n // Sentry adds its own stack trace to the fetch error, so also check for that\n \"__sentry_captured__\" in error\n );\n }\n\n // Deno network errors start with specific text\n if (message.startsWith(\"error sending request for url\")) {\n return true;\n }\n\n // Standard network error messages\n return errorMessages.has(message);\n}\n"],"mappings":";;AACA,MAAM,iBAAiB,OAAO,UAAU;AAExC,MAAM,UAAU,CAAC,UAAU,eAAe,KAAK,MAAM,KAAK;AAE1D,MAAM,gBAAgB,IAAI,IAAI;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAED,SAAwB,eAAe,OAAO;CAC5C,MAAM,UACJ,SACA,QAAQ,MAAM,IACd,MAAM,SAAS,eACf,OAAO,MAAM,YAAY;AAE3B,KAAI,CAAC,QACH,QAAO;CAGT,MAAM,EAAE,SAAS,OAAO,GAAG;AAG3B,KAAI,YAAY,cACd,QACE,UAAU,UAEV,yBAAyB;AAK7B,KAAI,QAAQ,WAAW,gCAAgC,CACrD,QAAO;AAIT,QAAO,cAAc,IAAI,QAAQ;AAClC"}
@@ -0,0 +1,26 @@
1
+ //#region src/utils/is-network-error/index.js
2
+ const objectToString = Object.prototype.toString;
3
+ const isError = (value) => objectToString.call(value) === "[object Error]";
4
+ const errorMessages = new Set([
5
+ "network error",
6
+ "Failed to fetch",
7
+ "NetworkError when attempting to fetch resource.",
8
+ "The Internet connection appears to be offline.",
9
+ "Network request failed",
10
+ "fetch failed",
11
+ "terminated",
12
+ " A network error occurred.",
13
+ "Network connection lost"
14
+ ]);
15
+ function isNetworkError(error) {
16
+ const isValid = error && isError(error) && error.name === "TypeError" && typeof error.message === "string";
17
+ if (!isValid) return false;
18
+ const { message, stack } = error;
19
+ if (message === "Load failed") return stack === void 0 || "__sentry_captured__" in error;
20
+ if (message.startsWith("error sending request for url")) return true;
21
+ return errorMessages.has(message);
22
+ }
23
+
24
+ //#endregion
25
+ export { isNetworkError };
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/is-network-error/index.js"],"sourcesContent":["/* eslint-disable */\nconst objectToString = Object.prototype.toString;\n\nconst isError = (value) => objectToString.call(value) === \"[object Error]\";\n\nconst errorMessages = new Set([\n \"network error\", // Chrome\n \"Failed to fetch\", // Chrome\n \"NetworkError when attempting to fetch resource.\", // Firefox\n \"The Internet connection appears to be offline.\", // Safari 16\n \"Network request failed\", // `cross-fetch`\n \"fetch failed\", // Undici (Node.js)\n \"terminated\", // Undici (Node.js)\n \" A network error occurred.\", // Bun (WebKit)\n \"Network connection lost\", // Cloudflare Workers (fetch)\n]);\n\nexport default function isNetworkError(error) {\n const isValid =\n error &&\n isError(error) &&\n error.name === \"TypeError\" &&\n typeof error.message === \"string\";\n\n if (!isValid) {\n return false;\n }\n\n const { message, stack } = error;\n\n // Safari 17+ has generic message but no stack for network errors\n if (message === \"Load failed\") {\n return (\n stack === undefined ||\n // Sentry adds its own stack trace to the fetch error, so also check for that\n \"__sentry_captured__\" in error\n );\n }\n\n // Deno network errors start with specific text\n if (message.startsWith(\"error sending request for url\")) {\n return true;\n }\n\n // Standard network error messages\n return errorMessages.has(message);\n}\n"],"mappings":";AACA,MAAM,iBAAiB,OAAO,UAAU;AAExC,MAAM,UAAU,CAAC,UAAU,eAAe,KAAK,MAAM,KAAK;AAE1D,MAAM,gBAAgB,IAAI,IAAI;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AAED,SAAwB,eAAe,OAAO;CAC5C,MAAM,UACJ,SACA,QAAQ,MAAM,IACd,MAAM,SAAS,eACf,OAAO,MAAM,YAAY;AAE3B,KAAI,CAAC,QACH,QAAO;CAGT,MAAM,EAAE,SAAS,OAAO,GAAG;AAG3B,KAAI,YAAY,cACd,QACE,UAAU,UAEV,yBAAyB;AAK7B,KAAI,QAAQ,WAAW,gCAAgC,CACrD,QAAO;AAIT,QAAO,cAAc,IAAI,QAAQ;AAClC"}
@@ -0,0 +1,141 @@
1
+ const require_index = require('../is-network-error/index.cjs');
2
+
3
+ //#region src/utils/p-retry/index.js
4
+ function validateRetries(retries) {
5
+ if (typeof retries === "number") {
6
+ if (retries < 0) throw new TypeError("Expected `retries` to be a non-negative number.");
7
+ if (Number.isNaN(retries)) throw new TypeError("Expected `retries` to be a valid number or Infinity, got NaN.");
8
+ } else if (retries !== void 0) throw new TypeError("Expected `retries` to be a number or Infinity.");
9
+ }
10
+ function validateNumberOption(name, value, { min = 0, allowInfinity = false } = {}) {
11
+ if (value === void 0) return;
12
+ if (typeof value !== "number" || Number.isNaN(value)) throw new TypeError(`Expected \`${name}\` to be a number${allowInfinity ? " or Infinity" : ""}.`);
13
+ if (!allowInfinity && !Number.isFinite(value)) throw new TypeError(`Expected \`${name}\` to be a finite number.`);
14
+ if (value < min) throw new TypeError(`Expected \`${name}\` to be \u2265 ${min}.`);
15
+ }
16
+ var AbortError = class extends Error {
17
+ constructor(message) {
18
+ super();
19
+ if (message instanceof Error) {
20
+ this.originalError = message;
21
+ ({message} = message);
22
+ } else {
23
+ this.originalError = new Error(message);
24
+ this.originalError.stack = this.stack;
25
+ }
26
+ this.name = "AbortError";
27
+ this.message = message;
28
+ }
29
+ };
30
+ function calculateDelay(retriesConsumed, options) {
31
+ const attempt = Math.max(1, retriesConsumed + 1);
32
+ const random = options.randomize ? Math.random() + 1 : 1;
33
+ let timeout = Math.round(random * options.minTimeout * options.factor ** (attempt - 1));
34
+ timeout = Math.min(timeout, options.maxTimeout);
35
+ return timeout;
36
+ }
37
+ function calculateRemainingTime(start, max) {
38
+ if (!Number.isFinite(max)) return max;
39
+ return max - (performance.now() - start);
40
+ }
41
+ async function onAttemptFailure({ error, attemptNumber, retriesConsumed, startTime, options }) {
42
+ const normalizedError = error instanceof Error ? error : /* @__PURE__ */ new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`);
43
+ if (normalizedError instanceof AbortError) throw normalizedError.originalError;
44
+ const retriesLeft = Number.isFinite(options.retries) ? Math.max(0, options.retries - retriesConsumed) : options.retries;
45
+ const maxRetryTime = options.maxRetryTime ?? Number.POSITIVE_INFINITY;
46
+ const context = Object.freeze({
47
+ error: normalizedError,
48
+ attemptNumber,
49
+ retriesLeft,
50
+ retriesConsumed
51
+ });
52
+ await options.onFailedAttempt(context);
53
+ if (calculateRemainingTime(startTime, maxRetryTime) <= 0) throw normalizedError;
54
+ const consumeRetry = await options.shouldConsumeRetry(context);
55
+ const remainingTime = calculateRemainingTime(startTime, maxRetryTime);
56
+ if (remainingTime <= 0 || retriesLeft <= 0) throw normalizedError;
57
+ if (normalizedError instanceof TypeError && !require_index.isNetworkError(normalizedError)) {
58
+ if (consumeRetry) throw normalizedError;
59
+ options.signal?.throwIfAborted();
60
+ return false;
61
+ }
62
+ if (!await options.shouldRetry(context)) throw normalizedError;
63
+ if (!consumeRetry) {
64
+ options.signal?.throwIfAborted();
65
+ return false;
66
+ }
67
+ const delayTime = calculateDelay(retriesConsumed, options);
68
+ const finalDelay = Math.min(delayTime, remainingTime);
69
+ if (finalDelay > 0) await new Promise((resolve, reject) => {
70
+ const onAbort = () => {
71
+ clearTimeout(timeoutToken);
72
+ options.signal?.removeEventListener("abort", onAbort);
73
+ reject(options.signal.reason);
74
+ };
75
+ const timeoutToken = setTimeout(() => {
76
+ options.signal?.removeEventListener("abort", onAbort);
77
+ resolve();
78
+ }, finalDelay);
79
+ if (options.unref) timeoutToken.unref?.();
80
+ options.signal?.addEventListener("abort", onAbort, { once: true });
81
+ });
82
+ options.signal?.throwIfAborted();
83
+ return true;
84
+ }
85
+ async function pRetry(input, options = {}) {
86
+ options = { ...options };
87
+ validateRetries(options.retries);
88
+ if (Object.hasOwn(options, "forever")) throw new Error("The `forever` option is no longer supported. For many use-cases, you can set `retries: Infinity` instead.");
89
+ options.retries ??= 10;
90
+ options.factor ??= 2;
91
+ options.minTimeout ??= 1e3;
92
+ options.maxTimeout ??= Number.POSITIVE_INFINITY;
93
+ options.maxRetryTime ??= Number.POSITIVE_INFINITY;
94
+ options.randomize ??= false;
95
+ options.onFailedAttempt ??= () => {};
96
+ options.shouldRetry ??= () => true;
97
+ options.shouldConsumeRetry ??= () => true;
98
+ validateNumberOption("factor", options.factor, {
99
+ min: 0,
100
+ allowInfinity: false
101
+ });
102
+ validateNumberOption("minTimeout", options.minTimeout, {
103
+ min: 0,
104
+ allowInfinity: false
105
+ });
106
+ validateNumberOption("maxTimeout", options.maxTimeout, {
107
+ min: 0,
108
+ allowInfinity: true
109
+ });
110
+ validateNumberOption("maxRetryTime", options.maxRetryTime, {
111
+ min: 0,
112
+ allowInfinity: true
113
+ });
114
+ if (!(options.factor > 0)) options.factor = 1;
115
+ options.signal?.throwIfAborted();
116
+ let attemptNumber = 0;
117
+ let retriesConsumed = 0;
118
+ const startTime = performance.now();
119
+ while (Number.isFinite(options.retries) ? retriesConsumed <= options.retries : true) {
120
+ attemptNumber++;
121
+ try {
122
+ options.signal?.throwIfAborted();
123
+ const result = await input(attemptNumber);
124
+ options.signal?.throwIfAborted();
125
+ return result;
126
+ } catch (error) {
127
+ if (await onAttemptFailure({
128
+ error,
129
+ attemptNumber,
130
+ retriesConsumed,
131
+ startTime,
132
+ options
133
+ })) retriesConsumed++;
134
+ }
135
+ }
136
+ throw new Error("Retry attempts exhausted without throwing an error.");
137
+ }
138
+
139
+ //#endregion
140
+ exports.pRetry = pRetry;
141
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["isNetworkError"],"sources":["../../../src/utils/p-retry/index.js"],"sourcesContent":["/* eslint-disable */\nimport isNetworkError from \"../is-network-error/index.js\";\n\nfunction validateRetries(retries) {\n if (typeof retries === \"number\") {\n if (retries < 0) {\n throw new TypeError(\"Expected `retries` to be a non-negative number.\");\n }\n\n if (Number.isNaN(retries)) {\n throw new TypeError(\n \"Expected `retries` to be a valid number or Infinity, got NaN.\"\n );\n }\n } else if (retries !== undefined) {\n throw new TypeError(\"Expected `retries` to be a number or Infinity.\");\n }\n}\n\nfunction validateNumberOption(\n name,\n value,\n { min = 0, allowInfinity = false } = {}\n) {\n if (value === undefined) {\n return;\n }\n\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new TypeError(\n `Expected \\`${name}\\` to be a number${\n allowInfinity ? \" or Infinity\" : \"\"\n }.`\n );\n }\n\n if (!allowInfinity && !Number.isFinite(value)) {\n throw new TypeError(`Expected \\`${name}\\` to be a finite number.`);\n }\n\n if (value < min) {\n throw new TypeError(`Expected \\`${name}\\` to be \\u2265 ${min}.`);\n }\n}\n\nexport class AbortError extends Error {\n constructor(message) {\n super();\n\n if (message instanceof Error) {\n this.originalError = message;\n ({ message } = message);\n } else {\n this.originalError = new Error(message);\n this.originalError.stack = this.stack;\n }\n\n this.name = \"AbortError\";\n this.message = message;\n }\n}\n\nfunction calculateDelay(retriesConsumed, options) {\n const attempt = Math.max(1, retriesConsumed + 1);\n const random = options.randomize ? Math.random() + 1 : 1;\n\n let timeout = Math.round(\n random * options.minTimeout * options.factor ** (attempt - 1)\n );\n timeout = Math.min(timeout, options.maxTimeout);\n\n return timeout;\n}\n\nfunction calculateRemainingTime(start, max) {\n if (!Number.isFinite(max)) {\n return max;\n }\n\n return max - (performance.now() - start);\n}\n\nasync function onAttemptFailure({\n error,\n attemptNumber,\n retriesConsumed,\n startTime,\n options,\n}) {\n const normalizedError =\n error instanceof Error\n ? error\n : new TypeError(\n `Non-error was thrown: \"${error}\". You should only throw errors.`\n );\n\n if (normalizedError instanceof AbortError) {\n throw normalizedError.originalError;\n }\n\n const retriesLeft = Number.isFinite(options.retries)\n ? Math.max(0, options.retries - retriesConsumed)\n : options.retries;\n\n const maxRetryTime = options.maxRetryTime ?? Number.POSITIVE_INFINITY;\n\n const context = Object.freeze({\n error: normalizedError,\n attemptNumber,\n retriesLeft,\n retriesConsumed,\n });\n\n await options.onFailedAttempt(context);\n\n if (calculateRemainingTime(startTime, maxRetryTime) <= 0) {\n throw normalizedError;\n }\n\n const consumeRetry = await options.shouldConsumeRetry(context);\n\n const remainingTime = calculateRemainingTime(startTime, maxRetryTime);\n\n if (remainingTime <= 0 || retriesLeft <= 0) {\n throw normalizedError;\n }\n\n if (\n normalizedError instanceof TypeError &&\n !isNetworkError(normalizedError)\n ) {\n if (consumeRetry) {\n throw normalizedError;\n }\n\n options.signal?.throwIfAborted();\n return false;\n }\n\n if (!(await options.shouldRetry(context))) {\n throw normalizedError;\n }\n\n if (!consumeRetry) {\n options.signal?.throwIfAborted();\n return false;\n }\n\n const delayTime = calculateDelay(retriesConsumed, options);\n const finalDelay = Math.min(delayTime, remainingTime);\n\n if (finalDelay > 0) {\n await new Promise((resolve, reject) => {\n const onAbort = () => {\n clearTimeout(timeoutToken);\n options.signal?.removeEventListener(\"abort\", onAbort);\n reject(options.signal.reason);\n };\n\n const timeoutToken = setTimeout(() => {\n options.signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, finalDelay);\n\n if (options.unref) {\n timeoutToken.unref?.();\n }\n\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n }\n\n options.signal?.throwIfAborted();\n\n return true;\n}\n\nexport default async function pRetry(input, options = {}) {\n options = { ...options };\n\n validateRetries(options.retries);\n\n if (Object.hasOwn(options, \"forever\")) {\n throw new Error(\n \"The `forever` option is no longer supported. For many use-cases, you can set `retries: Infinity` instead.\"\n );\n }\n\n options.retries ??= 10;\n options.factor ??= 2;\n options.minTimeout ??= 1000;\n options.maxTimeout ??= Number.POSITIVE_INFINITY;\n options.maxRetryTime ??= Number.POSITIVE_INFINITY;\n options.randomize ??= false;\n options.onFailedAttempt ??= () => {};\n options.shouldRetry ??= () => true;\n options.shouldConsumeRetry ??= () => true;\n\n // Validate numeric options and normalize edge cases\n validateNumberOption(\"factor\", options.factor, {\n min: 0,\n allowInfinity: false,\n });\n validateNumberOption(\"minTimeout\", options.minTimeout, {\n min: 0,\n allowInfinity: false,\n });\n validateNumberOption(\"maxTimeout\", options.maxTimeout, {\n min: 0,\n allowInfinity: true,\n });\n validateNumberOption(\"maxRetryTime\", options.maxRetryTime, {\n min: 0,\n allowInfinity: true,\n });\n\n // Treat non-positive factor as 1 to avoid zero backoff or negative behavior\n if (!(options.factor > 0)) {\n options.factor = 1;\n }\n\n options.signal?.throwIfAborted();\n\n let attemptNumber = 0;\n let retriesConsumed = 0;\n const startTime = performance.now();\n\n while (\n Number.isFinite(options.retries) ? retriesConsumed <= options.retries : true\n ) {\n attemptNumber++;\n\n try {\n options.signal?.throwIfAborted();\n\n const result = await input(attemptNumber);\n\n options.signal?.throwIfAborted();\n\n return result;\n } catch (error) {\n if (\n await onAttemptFailure({\n error,\n attemptNumber,\n retriesConsumed,\n startTime,\n options,\n })\n ) {\n retriesConsumed++;\n }\n }\n }\n\n // Should not reach here, but in case it does, throw an error\n throw new Error(\"Retry attempts exhausted without throwing an error.\");\n}\n\nexport function makeRetriable(function_, options) {\n return function (...arguments_) {\n return pRetry(() => function_.apply(this, arguments_), options);\n };\n}\n"],"mappings":"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"}