@nickyzj2023/utils 1.0.67 → 1.0.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -2,7 +2,7 @@
2
2
  declare namespace ChatCompletions {
3
3
  type Model = {
4
4
  /** 模型名称(如果不传,会尝试从 /models 读取模型) */model?: string; /** API 基础地址 */
5
- baseURL: string; /** API 密钥(本地模型可不传) */
5
+ baseUrl: string; /** API 密钥(本地模型可不传) */
6
6
  apiKey?: string;
7
7
  };
8
8
  type TextContent = {
@@ -15,9 +15,23 @@ declare namespace ChatCompletions {
15
15
  url: string;
16
16
  };
17
17
  };
18
- type ContentPart = TextContent | ImageContent;
18
+ type AudioContent = {
19
+ type: "input_audio";
20
+ audio_url: {
21
+ url: string;
22
+ };
23
+ };
24
+ type VideoContent = {
25
+ type: "video_url";
26
+ video_url: {
27
+ url: string;
28
+ };
29
+ };
30
+ type ContentPart = TextContent | ImageContent | AudioContent | VideoContent;
19
31
  type Message = {
20
- role: "system" | "user" | "assistant" | "tool" | "function";
32
+ role: "system" | "user" | "assistant" | "tool" | "function"; /** 字节的思考字段 */
33
+ reasoning_content?: string | null; /** OpenRouter的思考字段 */
34
+ reasoning?: string | null;
21
35
  content: string | ContentPart[];
22
36
  name?: string;
23
37
  tool_calls?: ToolCall[];
@@ -78,7 +92,9 @@ declare namespace ChatCompletions {
78
92
  index: number;
79
93
  delta: {
80
94
  role?: Message["role"];
81
- content?: string | null;
95
+ content?: string | null; /** 字节的思考字段 */
96
+ reasoning_content?: string | null; /** OpenRouter的思考字段 */
97
+ reasoning?: string | null;
82
98
  tool_calls?: Array<{
83
99
  index: number;
84
100
  id?: string;
@@ -95,7 +111,8 @@ declare namespace ChatCompletions {
95
111
  };
96
112
  /** 流式调用 chatCompletions 时迭代器产出的数据块 */
97
113
  type StreamChunk = {
98
- /** 模型流式返回的内容增量(仅在生成过程中出现) */content?: string; /** Token 消耗情况(仅在最后一帧出现) */
114
+ /** 模型流式返回的思考内容增量(仅在生成过程中出现) */reasoningContent?: string; /** 模型流式返回的内容增量(仅在生成过程中出现) */
115
+ content?: string; /** Token 消耗情况(仅在最后一帧出现) */
99
116
  usage?: Usage;
100
117
  };
101
118
  }
@@ -106,7 +123,7 @@ declare namespace ChatCompletions {
106
123
  * - 自动处理工具调用
107
124
  * - 同时支持普通响应和流式响应
108
125
  *
109
- * @param model 模型配置,包含 model、baseURL、apiKey
126
+ * @param model 模型配置,包含 model、baseUrl、apiKey
110
127
  * @param messages OpenAI API 兼容的消息数组
111
128
  * @param extraBody 可选的额外参数,如 tools、toolHandlers、temperature、stream 等
112
129
  * @returns 普通模式下返回 `{ content, usage, ... }`;`stream: true` 时返回异步迭代器
@@ -115,7 +132,7 @@ declare namespace ChatCompletions {
115
132
  * // 最简调用
116
133
  * // 未填写模型名,会自动使用/v1/models的第一个模型
117
134
  * const { content, usage } = await chatCompletions(
118
- * { baseURL: "http://127.0.0.1:11434/v1" },
135
+ * { baseUrl: "http://127.0.0.1:11434/v1" },
119
136
  * [{ role: "user", content: "你好" }],
120
137
  * );
121
138
  * console.log(content); // "你好!有什么我可以帮你的吗?"
@@ -124,7 +141,7 @@ declare namespace ChatCompletions {
124
141
  * @example
125
142
  * // 工具调用
126
143
  * const { content, usage } = await chatCompletions(
127
- * { baseURL: "http://127.0.0.1:11434/v1", model: "model.gguf", apiKey: "sk-local-no-need-key" },
144
+ * { baseUrl: "http://127.0.0.1:11434/v1", model: "model.gguf", apiKey: "sk-local-no-need-key" },
128
145
  * [{ role: "user", content: "查询上海天气" }],
129
146
  * {
130
147
  * tools: [{
@@ -144,7 +161,7 @@ declare namespace ChatCompletions {
144
161
  * @example
145
162
  * // 流式传输
146
163
  * const result = await chatCompletions(
147
- * { baseURL: "http://127.0.0.1:11434/v1" },
164
+ * { baseUrl: "http://127.0.0.1:11434/v1" },
148
165
  * [{ role: "user", content: "你好" }],
149
166
  * { stream: true },
150
167
  * );
@@ -160,6 +177,10 @@ declare function chatCompletions(model: ChatCompletions.Model, messages: ChatCom
160
177
  stream: true;
161
178
  }): Promise<AsyncGenerator<ChatCompletions.StreamChunk>>;
162
179
  declare function chatCompletions(model: ChatCompletions.Model, messages: ChatCompletions.Message[], extraBody?: ChatCompletions.ExtraBody): Promise<ChatCompletions.Result>;
180
+ /**
181
+ * 辅助定义一个 chatCompletions 支持的模型配置
182
+ */
183
+ declare const defineModel: (config: ChatCompletions.Model) => ChatCompletions.Model;
163
184
  //#endregion
164
185
  //#region src/dom/log.d.ts
165
186
  /**
@@ -317,7 +338,7 @@ type RequestInit = globalThis.RequestInit & {
317
338
  };
318
339
  /**
319
340
  * 基于 Fetch API 的请求实例
320
- * @param baseURL 接口前缀
341
+ * @param baseUrl 接口前缀
321
342
  * @param baseOptions 应用于整个实例的请求体,后续请求都会带上
322
343
  *
323
344
  * @remarks
@@ -357,7 +378,7 @@ type RequestInit = globalThis.RequestInit & {
357
378
  * await getBlogs("/blogs");
358
379
  * await getBlogs("/blogs"); // 不发请求,使用缓存
359
380
  */
360
- declare const fetcher: (baseURL?: string, baseOptions?: RequestInit) => {
381
+ declare const fetcher: (baseUrl?: string, baseOptions?: RequestInit) => {
361
382
  get: <T>(url: string, options?: Omit<RequestInit, "method">) => Promise<T>;
362
383
  post: <T>(url: string, body: any, options?: Omit<RequestInit, "method" | "body">) => Promise<T>;
363
384
  put: <T>(url: string, body: any, options?: Omit<RequestInit, "method" | "body">) => Promise<T>;
@@ -761,4 +782,4 @@ declare const sleep: (time?: number) => Promise<unknown>;
761
782
  */
762
783
  declare const throttle: <T extends (...args: any[]) => any>(fn: T, delay?: number) => (this: any, ...args: Parameters<T>) => void;
763
784
  //#endregion
764
- export { CamelToSnake, Capitalize, type ChatCompletions, Decapitalize, DeepMapKeys, DeepMapValues, ImageCompressionOptions, LockQueue, LogOptions, Primitive, RequestInit, SetTtl, SnakeToCamel, camelToSnake, capitalize, chatCompletions, compactStr, debounce, decapitalize, extractErrorMessage, fetcher, getRealURL, imageUrlToBase64, isNil, isObject, isPrimitive, log, loopUntil, mapKeys, mapValues, mergeObjects, omit, omitBy, pick, pickBy, qs, randomInt, sleep, snakeToCamel, throttle, to, withCache };
785
+ export { CamelToSnake, Capitalize, type ChatCompletions, Decapitalize, DeepMapKeys, DeepMapValues, ImageCompressionOptions, LockQueue, LogOptions, Primitive, RequestInit, SetTtl, SnakeToCamel, camelToSnake, capitalize, chatCompletions, compactStr, debounce, decapitalize, defineModel, extractErrorMessage, fetcher, getRealURL, imageUrlToBase64, isNil, isObject, isPrimitive, log, loopUntil, mapKeys, mapValues, mergeObjects, omit, omitBy, pick, pickBy, qs, randomInt, sleep, snakeToCamel, throttle, to, withCache };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  const e=e=>e==null,t=e=>e?.constructor===Object,n=e=>e==null||typeof e!=`object`&&typeof e!=`function`,r=(e,n)=>Array.isArray(e)?e.map(e=>r(e,n)):t(e)?Object.keys(e).reduce((t,i)=>{let a=n(i),o=e[i];return t[a]=r(o,n),t},{}):e,i=(e,n,r)=>{let{filter:a}=r??{};if(Array.isArray(e)){let o=e.map((e,a)=>t(e)?i(e,n,r):n(e,a));return a?o.filter((e,t)=>a(e,t)):o}return t(e)?Object.keys(e).reduce((o,s)=>{let c=e[s],l;return l=t(c)||Array.isArray(c)?i(c,n,r):n(c,s),(!a||a(l,s))&&(o[s]=l),o},{}):e},a=(e,r)=>{let i={...e};for(let e of Object.keys(r)){let o=i[e],s=r[e];if(n(o)&&n(s)){i[e]=s;continue}if(Array.isArray(o)&&Array.isArray(s)){i[e]=o.concat(s);continue}if(t(o)&&t(s)){i[e]=a(o,s);continue}i[e]=s}return i},o=(e,t)=>{let n={...e};for(let e of t)delete n[e];return n},s=(e,t)=>{let n={};for(let[r,i]of Object.entries(e))t(r,i)||(n[r]=i);return n},c=(e,t)=>t.reduce((t,n)=>(Object.hasOwn(e,n)&&(t[n]=e[n]),t),{}),l=(e,t)=>{let n={};for(let[r,i]of Object.entries(e))t(r,i)&&(n[r]=i);return n},u=(n=``,r={})=>{let i=async(i,o={})=>{let s=new URL(n?`${n}${i}`:i),{params:c,parser:l,...u}=a(r,o);t(c)&&Object.entries(c).forEach(([t,n])=>{e(n)||s.searchParams.append(t,n.toString())}),(t(u.body)||Array.isArray(u.body))&&(u.body=JSON.stringify(u.body),u.headers={...u.headers,"Content-Type":`application/json`});let d=await fetch(s,u);if(!d.ok){if(d.headers.get(`Content-Type`)?.startsWith(`application/json`)){let e=await d.json(),t=Error(e.error?.message||d.statusText);throw t.data=e,t}throw Error(d.statusText)}return await(l?.(d)??d.json())};return{get:(e,t)=>i(e,{...t,method:`GET`}),post:(e,t,n)=>i(e,{...n,method:`POST`,body:t}),put:(e,t,n)=>i(e,{...n,method:`PUT`,body:t}),delete:(e,t)=>i(e,{...t,method:`DELETE`})}},d=async e=>{try{return[null,await e]}catch(e){return[e,void 0]}},f=async e=>{let[t,n]=await d(fetch(e,{method:`HEAD`,redirect:`manual`}));return t?e:n.headers.get(`location`)||e},p=e=>{let t=new Uint8Array(e),n=``;for(let e=0;e<t.byteLength;e++)n+=String.fromCharCode(t[e]);return btoa(n)},m=async(e,t={})=>{let{quality:n=.92,compressor:r,fetcher:i=fetch}=t;if(!e.startsWith(`http`))throw Error(`图片地址必须以http或https开头`);let a=await i(e);if(!a.ok)throw Error(`获取图片失败: ${a.statusText}`);let o=a.headers.get(`Content-Type`)||`image/jpeg`,s=await a.arrayBuffer();if(o!==`image/jpeg`&&o!==`image/png`)return`data:${o};base64,${p(s)}`;if(r)return await r(s,o,n);if(typeof OffscreenCanvas<`u`){let e=null;try{let t=new Blob([s],{type:o});e=await createImageBitmap(t);let r=new OffscreenCanvas(e.width,e.height),i=r.getContext(`2d`);if(!i)throw Error(`无法获取 OffscreenCanvas context`);return i.drawImage(e,0,0),e.close(),e=null,`data:${o};base64,${p(await(await r.convertToBlob({type:o,quality:n})).arrayBuffer())}`}catch{return e?.close(),`data:${o};base64,${p(s)}`}}return`data:${o};base64,${p(s)}`},h=e=>e.replace(/_([a-zA-Z])/g,(e,t)=>t.toUpperCase()),g=e=>e.replace(/([A-Z])/g,(e,t)=>`_${t.toLowerCase()}`),_=e=>e.charAt(0).toUpperCase()+e.slice(1),v=e=>e.charAt(0).toLowerCase()+e.slice(1),y=(e=``,t)=>{if(!e)return``;let{maxLength:n=1/0,disableNewLineReplace:r=!1,disableCollapse:i=!1}=t??{},a=e;return i||(a=a.replace(/[\n\t]+/g,`
2
- `)),a=r?a.replace(/\r?\n/g,` `):a.replace(/\r?\n/g,`\\n`),a=a.replace(/\s+/g,` `).trim(),n>0&&a.length>n?`${a.slice(0,n)}...`:a},b=e=>{if(e instanceof Error)return e.message;if(typeof e==`string`)return e;if(t(e)){let t=e.message||e.msg;if(t)return t;for(let t of Object.values(e)){let e=b(t);if(e)return e}}return JSON.stringify(e,null,2)},x={parse:e=>{let t=new URLSearchParams(e),n={};for(let[e,r]of t)Number.isNaN(Number(r))?n[e]=r:n[e]=Number(r);return n},stringify:(e,t)=>{let{addQueryPrefix:n=!1}=t??{},r=new URLSearchParams(e).toString();return r?n?`?${r}`:r:``}},S=async e=>{let t=(await e.get(`/models`)).data[0]?.id;if(!t)throw Error(`无法从 /models 获取模型名称`);return t},C=async(e,t,n={})=>{let{model:r,baseURL:i,apiKey:a=``}=e,o=u(i,{headers:{Authorization:`Bearer ${a}`}}),s={model:r??await S(o),messages:t,...n};return o.post(`/chat/completions`,s)},w=async function*(e,t,n={}){let{model:r,baseURL:i,apiKey:a=``}=e,o=u(i,{headers:{Authorization:`Bearer ${a}`}}),s={model:r??await S(o),messages:t,...n,stream:!0,stream_options:{include_usage:!0,...n.stream_options??{}}},c=await o.post(`/chat/completions`,s,{parser:async e=>e});if(!c.body)throw Error(`响应没有 body,无法读取流式数据`);let l=c.body.getReader(),d=new TextDecoder,f=``;try{for(;;){let{done:e,value:t}=await l.read();if(e)break;f+=d.decode(t,{stream:!0});let n=f.split(`
2
+ `)),a=r?a.replace(/\r?\n/g,` `):a.replace(/\r?\n/g,`\\n`),a=a.replace(/\s+/g,` `).trim(),n>0&&a.length>n?`${a.slice(0,n)}...`:a},b=e=>{if(e instanceof Error)return e.message;if(typeof e==`string`)return e;if(t(e)){let t=e.message||e.msg;if(t)return t;for(let t of Object.values(e)){let e=b(t);if(e)return e}}return JSON.stringify(e,null,2)},x={parse:e=>{let t=new URLSearchParams(e),n={};for(let[e,r]of t)Number.isNaN(Number(r))?n[e]=r:n[e]=Number(r);return n},stringify:(e,t)=>{let{addQueryPrefix:n=!1}=t??{},r=new URLSearchParams(e).toString();return r?n?`?${r}`:r:``}},S=async e=>{let t=(await e.get(`/models`)).data[0]?.id;if(!t)throw Error(`无法从 /models 获取模型名称`);return t},C=async(e,t,n={})=>{let{model:r,baseUrl:i,apiKey:a=``}=e,o=u(i,{headers:{Authorization:`Bearer ${a}`}}),s={model:r??await S(o),messages:t,...n};return o.post(`/chat/completions`,s)},w=async function*(e,t,n={}){let{model:r,baseUrl:i,apiKey:a=``}=e,o=u(i,{headers:{Authorization:`Bearer ${a}`}}),s={model:r??await S(o),messages:t,...n,stream:!0,stream_options:{include_usage:!0,...n.stream_options??{}}},c=await o.post(`/chat/completions`,s,{parser:async e=>e});if(!c.body)throw Error(`响应没有 body,无法读取流式数据`);let l=c.body.getReader(),d=new TextDecoder,f=``;try{for(;;){let{done:e,value:t}=await l.read();if(e)break;f+=d.decode(t,{stream:!0});let n=f.split(`
3
3
  `);f=n.pop()??``;for(let e of n){let t=e.trim();if(!t.startsWith(`data:`))continue;let n=t.slice(5).trim();if(n===`[DONE]`)return;try{yield JSON.parse(n)}catch{}}}}finally{l.releaseLock()}},T=async(e,t)=>{let n=t[e.function.name];if(!n)return`没有找到工具“${e.function.name}”的处理函数`;try{let t=await n(JSON.parse(e.function.arguments));return typeof t==`string`?t:JSON.stringify(t)}catch(t){return`工具“${e.function.name}”处理失败:${b(t)}`}},E=e=>typeof e==`string`?e:e.filter(e=>e.type===`text`).map(e=>e.text).join(`
4
- `),D=async(e,t,n,r)=>{for(;;){let{choices:i,usage:a,...o}=await C(e,t,r),{message:s}=i[0]??{};if(!s)throw Error(`模型没有回复任何内容`);t.push(s);let{content:c=``,tool_calls:l=[],...u}=s;if(l.length>0&&Object.keys(n).length>0){for(let e of l){let r=await T(e,n);t.push({role:`tool`,content:r,tool_call_id:e.id})}continue}return{content:E(c),usage:a,...o,...u}}},O=async function*(e,t,n,r){for(;;){let i=``,a=new Map,o=null,s;for await(let n of w(e,t,r)){n.usage&&(s=n.usage);let e=n.choices?.[0];if(!e)continue;let{delta:t}=e,{content:r,tool_calls:c}=t;if(r&&(i+=r,yield{content:r}),c)for(let e of c){let t=a.get(e.index)??{id:``,type:`function`,function:{name:``,arguments:``}};e.id&&(t.id=e.id),e.function?.name&&(t.function.name+=e.function.name),e.function?.arguments&&(t.function.arguments+=e.function.arguments),a.set(e.index,t)}e.finish_reason&&(o=e.finish_reason)}let c=Array.from(a.values());if(o===`tool_calls`&&c.length>0&&Object.keys(n).length>0){t.push({role:`assistant`,content:i,tool_calls:c});for(let e of c){let r=await T(e,n);t.push({role:`tool`,content:r,tool_call_id:e.id})}continue}s&&(yield{usage:s});return}};async function k(e,t,n={}){let{stream:r,toolHandlers:i={},...a}=n;return r?O(e,t,i,a):D(e,t,i,a)}const A=(e,t)=>{let{time:n=!0,fileName:r=!0}=t??{},i=[];if(n&&i.push(`[${new Date().toLocaleTimeString()}]`),r){let{stack:e}=Error(),t=(e?.split(`
5
- `)[2]?.trim())?.match(/at\s+(.*):(\d+)/);if(t?.[1]){let e=t[1].split(/[/\\]/).pop();i.push(`[${e}:${t[2]}]`)}}Array.isArray(e)?i.push(...e):i.push(e),console.log(...i)},j=async(e,t)=>{let{maxRetries:n=5,shouldStop:r}=t??{},i;for(let t=0;t<n;t++)if(i=await e(t),r?.(i)===!0)return i;if(!r)return i;throw Error(`超过了最大循环次数(${n})且未满足停止执行条件`)},M=(e,t=-1)=>{let n=new Map,r=(...r)=>{let i=JSON.stringify(r),a=Date.now(),o=n.get(i);if(o&&a<o.expiresAt)return o.value;let s=t===-1?1/0:a+t*1e3,c=e.apply({setTtl:e=>{s=a+e*1e3}},r);if(c instanceof Promise){let e=c.then(e=>(n.set(i,{value:e,expiresAt:s}),e));return n.set(i,{value:e,expiresAt:s}),e}return n.set(i,{value:c,expiresAt:s}),c};return r.clear=()=>n.clear(),r.updateTtl=e=>{t=e;let r=Date.now(),i=r+e*1e3;for(let[e,t]of n.entries())t.expiresAt>r&&(t.expiresAt=i,n.set(e,t))},r},N=(e,t)=>Math.floor(Math.random()*(t-e+1))+e,P=(e,t=300)=>{let n=null;return(...r)=>{n&&clearTimeout(n),n=setTimeout(()=>{e(...r)},t)}};var F=class{queue;constructor(){this.queue=Promise.resolve()}waitInQueue(){let e,t=new Promise(t=>{e=t}),n=this.queue.then(()=>e);return this.queue=t,n}};const I=async(e=150)=>new Promise(t=>{setTimeout(t,e)}),L=(e,t=300)=>{let n=null;return function(...r){n||=setTimeout(()=>{n=null,e.apply(this,r)},t)}};export{F as LockQueue,g as camelToSnake,_ as capitalize,k as chatCompletions,y as compactStr,P as debounce,v as decapitalize,b as extractErrorMessage,u as fetcher,f as getRealURL,m as imageUrlToBase64,e as isNil,t as isObject,n as isPrimitive,A as log,j as loopUntil,r as mapKeys,i as mapValues,a as mergeObjects,o as omit,s as omitBy,c as pick,l as pickBy,x as qs,N as randomInt,I as sleep,h as snakeToCamel,L as throttle,d as to,M as withCache};
4
+ `),D=async(e,t,n,r)=>{for(;;){let i=await C(e,t,r),{choices:a,usage:o,...s}=i,{message:c}=a?.[0]??{};if(console.log(i),!c)throw Error(`模型没有回复任何内容`);t.push(c);let{content:l=``,tool_calls:u=[],...d}=c,f=d?.reasoning_content||d?.reasoning;if(u.length>0&&Object.keys(n).length>0){for(let e of u){let r=await T(e,n);t.push({role:`tool`,content:r,tool_call_id:e.id})}continue}return{reasoningContent:f,content:E(l),usage:o,...s,...d}}},O=async function*(e,t,n,r){for(;;){let i=``,a=new Map,o=null,s;for await(let n of w(e,t,r)){n.usage&&(s=n.usage);let e=n.choices?.[0];if(!e)continue;let{delta:t}=e,{content:r,tool_calls:c}=t,l=t.reasoning_content||t.reasoning;if(l&&(yield{reasoningContent:l}),r&&(i+=r,yield{content:r}),c)for(let e of c){let t=a.get(e.index)??{id:``,type:`function`,function:{name:``,arguments:``}};e.id&&(t.id=e.id),e.function?.name&&(t.function.name+=e.function.name),e.function?.arguments&&(t.function.arguments+=e.function.arguments),a.set(e.index,t)}e.finish_reason&&(o=e.finish_reason)}let c=Array.from(a.values());if(o===`tool_calls`&&c.length>0&&Object.keys(n).length>0){t.push({role:`assistant`,content:i,tool_calls:c});for(let e of c){let r=await T(e,n);t.push({role:`tool`,content:r,tool_call_id:e.id})}continue}s&&(yield{usage:s});return}};async function k(e,t,n={}){let{stream:r,toolHandlers:i={},...a}=n;return r?O(e,t,i,a):D(e,t,i,a)}const A=e=>e,j=(e,t)=>{let{time:n=!0,fileName:r=!0}=t??{},i=[];if(n&&i.push(`[${new Date().toLocaleTimeString()}]`),r){let{stack:e}=Error(),t=(e?.split(`
5
+ `)[2]?.trim())?.match(/at\s+(.*):(\d+)/);if(t?.[1]){let e=t[1].split(/[/\\]/).pop();i.push(`[${e}:${t[2]}]`)}}Array.isArray(e)?i.push(...e):i.push(e),console.log(...i)},M=async(e,t)=>{let{maxRetries:n=5,shouldStop:r}=t??{},i;for(let t=0;t<n;t++)if(i=await e(t),r?.(i)===!0)return i;if(!r)return i;throw Error(`超过了最大循环次数(${n})且未满足停止执行条件`)},N=(e,t=-1)=>{let n=new Map,r=(...r)=>{let i=JSON.stringify(r),a=Date.now(),o=n.get(i);if(o&&a<o.expiresAt)return o.value;let s=t===-1?1/0:a+t*1e3,c=e.apply({setTtl:e=>{s=a+e*1e3}},r);if(c instanceof Promise){let e=c.then(e=>(n.set(i,{value:e,expiresAt:s}),e));return n.set(i,{value:e,expiresAt:s}),e}return n.set(i,{value:c,expiresAt:s}),c};return r.clear=()=>n.clear(),r.updateTtl=e=>{t=e;let r=Date.now(),i=r+e*1e3;for(let[e,t]of n.entries())t.expiresAt>r&&(t.expiresAt=i,n.set(e,t))},r},P=(e,t)=>Math.floor(Math.random()*(t-e+1))+e,F=(e,t=300)=>{let n=null;return(...r)=>{n&&clearTimeout(n),n=setTimeout(()=>{e(...r)},t)}};var I=class{queue;constructor(){this.queue=Promise.resolve()}waitInQueue(){let e,t=new Promise(t=>{e=t}),n=this.queue.then(()=>e);return this.queue=t,n}};const L=async(e=150)=>new Promise(t=>{setTimeout(t,e)}),R=(e,t=300)=>{let n=null;return function(...r){n||=setTimeout(()=>{n=null,e.apply(this,r)},t)}};export{I as LockQueue,g as camelToSnake,_ as capitalize,k as chatCompletions,y as compactStr,F as debounce,v as decapitalize,A as defineModel,b as extractErrorMessage,u as fetcher,f as getRealURL,m as imageUrlToBase64,e as isNil,t as isObject,n as isPrimitive,j as log,M as loopUntil,r as mapKeys,i as mapValues,a as mergeObjects,o as omit,s as omitBy,c as pick,l as pickBy,x as qs,P as randomInt,L as sleep,h as snakeToCamel,R as throttle,d as to,N as withCache};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nickyzj2023/utils",
3
- "version": "1.0.67",
3
+ "version": "1.0.69",
4
4
  "type": "module",
5
5
  "main": "dist/index.mjs",
6
6
  "module": "dist/index.mjs",