@ts-utilities/core 1.3.4 → 1.3.6
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.cjs +1 -1
- package/dist/index.d.cts +106 -40
- package/dist/index.d.ts +106 -40
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=e=>!e,t=e=>e==null,n=e=>typeof e==`boolean`,r=e=>typeof e==`string`,i=e=>{if(typeof e==`number`)return Number.isFinite(e);if(typeof e==`string`){let t=Number(e);return Number.isFinite(t)}return!1},a=e=>Array.isArray(e),o=e=>typeof e==`function`,s=e=>{if(e==null)return!0;switch(typeof e){case`string`:case`number`:case`bigint`:case`boolean`:case`symbol`:return!0;default:return!1}};function c(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}function l(e,...t){let n,r={},i=t[t.length-1];i&&typeof i==`object`&&!Array.isArray(i)&&(i.arrayMerge!==void 0||i.clone!==void 0||i.customMerge!==void 0||i.functionMerge!==void 0||i.maxDepth!==void 0)?(r={...r,...i},n=t.slice(0,-1)):n=t;let{arrayMerge:a=`replace`,clone:o=!0,functionMerge:s=`replace`,maxDepth:l=100,customMerge:u}=r,d=new WeakMap;return f(e,n,0);function f(e,t,n){if(n>=l)return console.warn(`[deepmerge] Maximum depth ${l} exceeded. Returning target as-is.`),e;if(!c(e)&&!Array.isArray(e)){for(let n of t)if(n!==void 0){if(u){let t=u(``,e,n);if(t!==void 0)return t}return typeof e==`function`&&typeof n==`function`&&s===`compose`?(...t)=>{e(...t),n(...t)}:n}return e}let r=o?Array.isArray(e)?[...e]:{...e}:e;for(let e of t)if(e!=null&&!d.has(e))if(d.set(e,r),Array.isArray(r)&&Array.isArray(e))r=p(r,e,a);else if(c(r)&&c(e)){let t=new Set([...Object.keys(r),...Object.keys(e),...Object.getOwnPropertySymbols(r),...Object.getOwnPropertySymbols(e)]);for(let i of t){let t=r[i],o=e[i];u&&u(i,t,o)!==void 0?r[i]=u(i,t,o):typeof t==`function`&&typeof o==`function`?s===`compose`?r[i]=(...e)=>{t(...e),o(...e)}:r[i]=o:c(t)&&c(o)?r[i]=f(t,[o],n+1):Array.isArray(t)&&Array.isArray(o)?r[i]=p(t,o,a):o!==void 0&&(r[i]=o)}}else r=e;return r}function p(e,t,n){if(typeof n==`function`)return n(e,t);switch(n){case`concat`:return[...e,...t];case`merge`:let n=Math.max(e.length,t.length),r=[];for(let i=0;i<n;i++)i<e.length&&i<t.length?c(e[i])&&c(t[i])?r[i]=f(e[i],[t[i]],0):r[i]=t[i]:i<e.length?r[i]=e[i]:r[i]=t[i];return r;case`replace`:default:return[...t]}}}function u(e,t,n){if(Array.isArray(t))return t.map(t=>u(e,t,n));if(typeof t==`object`&&t&&!Array.isArray(t)){let r={};for(let i in t)t.hasOwnProperty(i)&&(r[i]=u(e,t[i],n));return r}if(typeof t!=`string`)return n;let r=(()=>t===``?[]:t.split(`.`).filter(e=>e!==``))(),i=e;for(let e of r){if(i==null)return n;let t=typeof e==`string`&&Array.isArray(i)&&/^\d+$/.test(e)?Number.parseInt(e,10):e;i=i[t]}return i===void 0?n:i}function d(e){return f(e)}function f(e){if(e!==null){if(typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(f);if(c(e)){let t={};for(let n in e)t[n]=f(e[n]);return t}return e}}function p(e,t){return e==null?e:Object.assign(e,t)}function m(e){return(e.split(`.`).pop()||e).replace(/([a-z])([A-Z])/g,`$1 $2`).split(/[-_|�\s]+/).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}const h=`àáãäâèéëêìíïîòóöôùúüûñç·/_,:;`,g=`aaaaaeeeeiiiioooouuuunc------`,_=e=>{if(typeof e!=`string`)throw TypeError(`Input must be a string`);let t=e.trim().toLowerCase(),n={};for(let e=0;e<29;e++)n[h.charAt(e)]=`aaaaaeeeeiiiioooouuuunc------`.charAt(e);return t=t.replace(RegExp(`[${h}]`,`g`),e=>n[e]||e),t.replace(/[^a-z0-9 -]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-+/,``).replace(/-+$/,``)||``},v=(e=1e3,t)=>new Promise(n=>{if(t?.aborted)return n();let r=setTimeout(()=>{a(),n()},e);function i(){clearTimeout(r),a(),n()}function a(){t?.removeEventListener(`abort`,i)}t&&t.addEventListener(`abort`,i,{once:!0})});function y(e,t=100,n){if(typeof e!=`function`)throw TypeError(`Expected the first parameter to be a function, got \`${typeof e}\`.`);if(t<0)throw RangeError("`wait` must not be negative.");let r=n?.immediate??!1,i,a,o,s;function c(){return s=e.apply(o,a),a=void 0,o=void 0,s}let l=function(...e){return a=e,o=this,i===void 0&&r&&(s=c.call(this)),i!==void 0&&clearTimeout(i),i=setTimeout(c.bind(this),t),s};return Object.defineProperty(l,`isPending`,{get(){return i!==void 0}}),l}function b(e,t=100,n){if(typeof e!=`function`)throw TypeError(`Expected the first parameter to be a function, got \`${typeof e}\`.`);if(t<0)throw RangeError("`wait` must not be negative.");let r=n?.leading??!0,i=n?.trailing??!0,a,o,s,c,l;function u(){c=Date.now(),l=e.apply(s,o),o=void 0,s=void 0}function d(){a=void 0,i&&o&&u()}let f=function(...e){let n=c?Date.now()-c:1/0;return o=e,s=this,n>=t?r?u():a=setTimeout(d,t):!a&&i&&(a=setTimeout(d,t-n)),l};return Object.defineProperty(f,`isPending`,{get(){return a!==void 0}}),f}function x(e,...t){let n=t.length===1&&Array.isArray(t[0])?t[0]:t,r=0;return e.replace(/%s/g,()=>{let e=n[r++];return e===void 0?``:String(e)})}function S(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function C(e,t={}){if(!e)return``;let{lowercase:n=!0,removeAccents:r=!0,removeNonAlphanumeric:i=!0}=t,a=e.normalize(`NFC`);return r&&(a=a.normalize(`NFD`).replace(/\p{M}/gu,``)),i&&(a=a.replace(/^[^\p{L}\p{N}]*|[^\p{L}\p{N}]*$/gu,``)),n&&(a=a.toLocaleLowerCase()),a}function w(e,...t){return typeof e==`function`?e(...t):e}async function
|
|
1
|
+
const e=e=>!e,t=e=>e==null,n=e=>typeof e==`boolean`,r=e=>typeof e==`string`,i=e=>{if(typeof e==`number`)return Number.isFinite(e);if(typeof e==`string`){let t=Number(e);return Number.isFinite(t)}return!1},a=e=>Array.isArray(e),o=e=>typeof e==`function`,s=e=>{if(e==null)return!0;switch(typeof e){case`string`:case`number`:case`bigint`:case`boolean`:case`symbol`:return!0;default:return!1}};function c(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}function l(e,...t){let n,r={},i=t[t.length-1];i&&typeof i==`object`&&!Array.isArray(i)&&(i.arrayMerge!==void 0||i.clone!==void 0||i.customMerge!==void 0||i.functionMerge!==void 0||i.maxDepth!==void 0)?(r={...r,...i},n=t.slice(0,-1)):n=t;let{arrayMerge:a=`replace`,clone:o=!0,functionMerge:s=`replace`,maxDepth:l=100,customMerge:u}=r,d=new WeakMap;return f(e,n,0);function f(e,t,n){if(n>=l)return console.warn(`[deepmerge] Maximum depth ${l} exceeded. Returning target as-is.`),e;if(!c(e)&&!Array.isArray(e)){for(let n of t)if(n!==void 0){if(u){let t=u(``,e,n);if(t!==void 0)return t}return typeof e==`function`&&typeof n==`function`&&s===`compose`?(...t)=>{e(...t),n(...t)}:n}return e}let r=o?Array.isArray(e)?[...e]:{...e}:e;for(let e of t)if(e!=null&&!d.has(e))if(d.set(e,r),Array.isArray(r)&&Array.isArray(e))r=p(r,e,a);else if(c(r)&&c(e)){let t=new Set([...Object.keys(r),...Object.keys(e),...Object.getOwnPropertySymbols(r),...Object.getOwnPropertySymbols(e)]);for(let i of t){let t=r[i],o=e[i];u&&u(i,t,o)!==void 0?r[i]=u(i,t,o):typeof t==`function`&&typeof o==`function`?s===`compose`?r[i]=(...e)=>{t(...e),o(...e)}:r[i]=o:c(t)&&c(o)?r[i]=f(t,[o],n+1):Array.isArray(t)&&Array.isArray(o)?r[i]=p(t,o,a):o!==void 0&&(r[i]=o)}}else r=e;return r}function p(e,t,n){if(typeof n==`function`)return n(e,t);switch(n){case`concat`:return[...e,...t];case`merge`:let n=Math.max(e.length,t.length),r=[];for(let i=0;i<n;i++)i<e.length&&i<t.length?c(e[i])&&c(t[i])?r[i]=f(e[i],[t[i]],0):r[i]=t[i]:i<e.length?r[i]=e[i]:r[i]=t[i];return r;case`replace`:default:return[...t]}}}function u(e,t,n){if(Array.isArray(t))return t.map(t=>u(e,t,n));if(typeof t==`object`&&t&&!Array.isArray(t)){let r={};for(let i in t)t.hasOwnProperty(i)&&(r[i]=u(e,t[i],n));return r}if(typeof t!=`string`)return n;let r=(()=>t===``?[]:t.split(`.`).filter(e=>e!==``))(),i=e;for(let e of r){if(i==null)return n;let t=typeof e==`string`&&Array.isArray(i)&&/^\d+$/.test(e)?Number.parseInt(e,10):e;i=i[t]}return i===void 0?n:i}function d(e){return f(e)}function f(e){if(e!==null){if(typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(f);if(c(e)){let t={};for(let n in e)t[n]=f(e[n]);return t}return e}}function p(e,t){return e==null?e:Object.assign(e,t)}function m(e){return(e.split(`.`).pop()||e).replace(/([a-z])([A-Z])/g,`$1 $2`).split(/[-_|�\s]+/).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}const h=`àáãäâèéëêìíïîòóöôùúüûñç·/_,:;`,g=`aaaaaeeeeiiiioooouuuunc------`,_=e=>{if(typeof e!=`string`)throw TypeError(`Input must be a string`);let t=e.trim().toLowerCase(),n={};for(let e=0;e<29;e++)n[h.charAt(e)]=`aaaaaeeeeiiiioooouuuunc------`.charAt(e);return t=t.replace(RegExp(`[${h}]`,`g`),e=>n[e]||e),t.replace(/[^a-z0-9 -]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-+/,``).replace(/-+$/,``)||``},v=(e=1e3,t)=>new Promise(n=>{if(t?.aborted)return n();let r=setTimeout(()=>{a(),n()},e);function i(){clearTimeout(r),a(),n()}function a(){t?.removeEventListener(`abort`,i)}t&&t.addEventListener(`abort`,i,{once:!0})});function y(e,t=100,n){if(typeof e!=`function`)throw TypeError(`Expected the first parameter to be a function, got \`${typeof e}\`.`);if(t<0)throw RangeError("`wait` must not be negative.");let r=n?.immediate??!1,i,a,o,s;function c(){return s=e.apply(o,a),a=void 0,o=void 0,s}let l=function(...e){return a=e,o=this,i===void 0&&r&&(s=c.call(this)),i!==void 0&&clearTimeout(i),i=setTimeout(c.bind(this),t),s};return Object.defineProperty(l,`isPending`,{get(){return i!==void 0}}),l}function b(e,t=100,n){if(typeof e!=`function`)throw TypeError(`Expected the first parameter to be a function, got \`${typeof e}\`.`);if(t<0)throw RangeError("`wait` must not be negative.");let r=n?.leading??!0,i=n?.trailing??!0,a,o,s,c,l;function u(){c=Date.now(),l=e.apply(s,o),o=void 0,s=void 0}function d(){a=void 0,i&&o&&u()}let f=function(...e){let n=c?Date.now()-c:1/0;return o=e,s=this,n>=t?r?u():a=setTimeout(d,t):!a&&i&&(a=setTimeout(d,t-n)),l};return Object.defineProperty(f,`isPending`,{get(){return a!==void 0}}),f}function x(e,...t){let n=t.length===1&&Array.isArray(t[0])?t[0]:t,r=0;return e.replace(/%s/g,()=>{let e=n[r++];return e===void 0?``:String(e)})}function S(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function C(e,t={}){if(!e)return``;let{lowercase:n=!0,removeAccents:r=!0,removeNonAlphanumeric:i=!0}=t,a=e.normalize(`NFC`);return r&&(a=a.normalize(`NFD`).replace(/\p{M}/gu,``)),i&&(a=a.replace(/^[^\p{L}\p{N}]*|[^\p{L}\p{N}]*$/gu,``)),n&&(a=a.toLocaleLowerCase()),a}function w(e,...t){return typeof e==`function`?e(...t):e}const T=Symbol(`poll.signal.abort`),E=Symbol(`poll.signal.retry`);async function*D(e,{interval:t=5e3,timeout:n=300*1e3,jitter:r=!0,signal:i}={}){let a=Date.now();for(;;){if(i?.aborted)throw new DOMException(`Polling aborted`,`AbortError`);let o=await e();if(o===T)return;if(o===E){await v(r?t+(Math.random()-.5)*t*.2:t,i);continue}if(o){yield o;return}if(Date.now()-a>=n)throw Error(`Polling timed out after ${n}ms`);yield null,await v(r?t+(Math.random()-.5)*t*.2:t,i)}}async function O(e,t={}){for await(let n of D(e,t))if(n)return n}const k={wait:O,watch:D,signal:{abort:T,retry:E}};async function A(e,t={}){let{concurrency:n=1/0,timeout:r=1/0,signal:i,retry:a=0,retryDelay:o=0,throwOnFirstError:s=!1,ignoreErrors:c=!1}=t,l=Array.isArray(e),u={};l?e.forEach((e,t)=>{u[t.toString()]=e}):Object.entries(e).forEach(([e,t])=>{u[e]=t});let d=Object.keys(u);if(d.length===0)return{results:l?[]:{},errors:[],succeeded:0,failed:0,duration:0};let f=Date.now(),p=[],m=[],h=0,g=0,_=0,y=!1,b=s?null:void 0,x=async e=>{let t=0;for(;t<=a&&!y;)try{let t=u[e],n=await(typeof t==`function`?t():t);p.push([e,n]),g++;return}catch(e){if(t===a){let t=e instanceof Error?e:Error(String(e));m.push(t),_++,!c&&s&&!b&&(b=t,y=!0);return}t++,o>0&&await v(o,i)}},S=Array.from({length:Math.min(n,d.length)},async()=>{for(;!y;){let e=h++;if(e>=d.length)return;if(i?.aborted){y=!0;return}await x(d[e])}}),C=Promise.all(S);if(r===1/0?await C:await Promise.race([C,v(r,i).then(()=>{throw y=!0,Error(`Concurrence timed out after ${r}ms`)})]),b&&s)throw b;return l?{results:p.sort((e,t)=>Number(e[0])-Number(t[0])).map(([,e])=>e),errors:m,succeeded:g,failed:_,duration:Date.now()-f}:{results:Object.fromEntries(p),errors:m,succeeded:g,failed:_,duration:Date.now()-f}}function j(e,t={}){let{retry:n=0,delay:r=0,debug:i=!1}=t,a=Date.now(),o=async t=>{try{if(await e(),i){let e=Date.now()-a;console.log(`⚡[schedule.ts] Completed in ${e}ms`)}}catch(e){if(i&&console.log(`⚡[schedule.ts] err:`,e),t>0)i&&console.log(`⚡[schedule.ts] Retrying in ${r}ms...`),setTimeout(()=>o(t-1),r);else if(i){let e=Date.now()-a;console.log(`⚡[schedule.ts] Failed after ${e}ms`)}}};setTimeout(()=>o(n),0)}function M(e){if(e instanceof Promise)return e.then(e=>[null,e]).catch(e=>[e,null]);try{return[null,e()]}catch(t){return console.log(`\x1b[31m🛡 [shield]\x1b[0m ${e.name} failed →`,t),[t,null]}}exports.convertToNormalCase=m,exports.convertToSlug=_,exports.debounce=y,exports.deepmerge=l,exports.escapeRegExp=S,exports.extendProps=p,exports.extract=u,exports.hydrate=d,exports.isArray=a,exports.isBoolean=n,exports.isFalsy=e,exports.isFiniteNumber=i,exports.isFunction=o,exports.isNullish=t,exports.isPlainObject=c,exports.isPrimitive=s,exports.isString=r,exports.normalizeText=C,exports.poll=k,exports.printf=x,exports.schedule=j,exports.shield=M,exports.sleep=v,exports.throttle=b,exports.unwrap=w,exports.withConcurrency=A;
|
package/dist/index.d.cts
CHANGED
|
@@ -994,17 +994,93 @@ declare function hydrate<T>(data: T): Hydrate<T>;
|
|
|
994
994
|
declare function extendProps<T, P$1 extends object>(base: T, props: P$1): T extends null | undefined ? T : T & P$1;
|
|
995
995
|
//#endregion
|
|
996
996
|
//#region src/functions/poll.d.ts
|
|
997
|
+
type PollOptions = Partial<{
|
|
998
|
+
interval: number;
|
|
999
|
+
timeout: number;
|
|
1000
|
+
signal: AbortSignal;
|
|
1001
|
+
jitter: boolean;
|
|
1002
|
+
}>;
|
|
1003
|
+
declare const ABORT: unique symbol;
|
|
1004
|
+
declare const RETRY: unique symbol;
|
|
1005
|
+
type PollControl = typeof ABORT | typeof RETRY;
|
|
1006
|
+
/**
|
|
1007
|
+
* Streams an async `cond` function, yielding `null` while waiting and the
|
|
1008
|
+
* final truthy value `T` when resolved.
|
|
1009
|
+
*
|
|
1010
|
+
* Designed for use in tRPC subscriptions or any async generator context where
|
|
1011
|
+
* you want to stream progress to the client instead of blocking.
|
|
1012
|
+
*
|
|
1013
|
+
* Keeps SSE/WebSocket connections alive on edge runtimes (e.g. Vercel) by
|
|
1014
|
+
* continuously emitting values rather than holding a silent open connection.
|
|
1015
|
+
*
|
|
1016
|
+
* @template T The type of the successful result.
|
|
1017
|
+
*
|
|
1018
|
+
* @param cond
|
|
1019
|
+
* A function returning a Promise that resolves to:
|
|
1020
|
+
* - a truthy value `T` → stop polling and yield it
|
|
1021
|
+
* - `poll.signal.abort` → stop polling cleanly with no error
|
|
1022
|
+
* - `poll.signal.retry` → skip this tick silently, no null emitted
|
|
1023
|
+
* - falsy/null/undefined → yield `null` and continue polling
|
|
1024
|
+
*
|
|
1025
|
+
* @param options
|
|
1026
|
+
* Configuration options:
|
|
1027
|
+
* - `interval` (number) — Time between polls in ms (default: 5000 ms)
|
|
1028
|
+
* - `timeout` (number) — Max total duration before failing (default: 5 min)
|
|
1029
|
+
* - `jitter` (boolean) — Add small random offset (±10%) to intervals to avoid sync bursts (default: true)
|
|
1030
|
+
* - `signal` (AbortSignal) — Optional abort signal to cancel polling
|
|
1031
|
+
*
|
|
1032
|
+
* @throws `AbortError` if aborted via signal
|
|
1033
|
+
* @throws `Error` if timed out
|
|
1034
|
+
*
|
|
1035
|
+
* @example
|
|
1036
|
+
* ```ts
|
|
1037
|
+
* // tRPC subscription — stream null while job is pending, emit result when done
|
|
1038
|
+
* syncImageJob: privateProcedure
|
|
1039
|
+
* .input(z.object({ id: z.coerce.number() }))
|
|
1040
|
+
* .subscription(async function* ({ ctx, input, signal }) {
|
|
1041
|
+
* yield* poll.watch(
|
|
1042
|
+
* async () => {
|
|
1043
|
+
* const job = await getJob(input.id);
|
|
1044
|
+
* if (job?.is_cancelled) return poll.signal.abort; // stop cleanly
|
|
1045
|
+
* if (job?.is_paused) return poll.signal.retry; // skip this tick
|
|
1046
|
+
* return job?.is_finished ? job : null;
|
|
1047
|
+
* },
|
|
1048
|
+
* { interval: 15000, signal },
|
|
1049
|
+
* );
|
|
1050
|
+
* }),
|
|
1051
|
+
* ```
|
|
1052
|
+
*
|
|
1053
|
+
* @example
|
|
1054
|
+
* ```ts
|
|
1055
|
+
* // Manually iterate
|
|
1056
|
+
* for await (const result of poll.watch(() => getJobStatus(), { interval: 3000 })) {
|
|
1057
|
+
* if (result === null) console.log('still waiting...');
|
|
1058
|
+
* else console.log('done!', result);
|
|
1059
|
+
* }
|
|
1060
|
+
* ```
|
|
1061
|
+
*/
|
|
1062
|
+
declare function watch<T>(cond: () => Promise<T | null | false | undefined | PollControl>, {
|
|
1063
|
+
interval,
|
|
1064
|
+
timeout,
|
|
1065
|
+
jitter,
|
|
1066
|
+
signal
|
|
1067
|
+
}?: PollOptions): AsyncGenerator<T | null>;
|
|
997
1068
|
/**
|
|
998
1069
|
* Repeatedly polls an async `cond` function UNTIL it returns a TRUTHY value,
|
|
999
1070
|
* or until the operation times out or is aborted.
|
|
1000
1071
|
*
|
|
1001
|
-
* Designed for waiting on async jobs, external state, or delayed availability
|
|
1072
|
+
* Designed for waiting on async jobs, external state, or delayed availability
|
|
1073
|
+
* where you only care about the final result and not intermediate states.
|
|
1074
|
+
*
|
|
1075
|
+
* Use `poll.watch` instead if you need to stream progress (e.g. tRPC subscriptions).
|
|
1002
1076
|
*
|
|
1003
1077
|
* @template T The type of the successful result.
|
|
1004
1078
|
*
|
|
1005
1079
|
* @param cond
|
|
1006
1080
|
* A function returning a Promise that resolves to:
|
|
1007
1081
|
* - a truthy value `T` → stop polling and return it
|
|
1082
|
+
* - `poll.signal.abort` → stop polling cleanly, resolves with undefined
|
|
1083
|
+
* - `poll.signal.retry` → skip this tick silently
|
|
1008
1084
|
* - falsy/null/undefined → continue polling
|
|
1009
1085
|
*
|
|
1010
1086
|
* @param options
|
|
@@ -1014,14 +1090,14 @@ declare function extendProps<T, P$1 extends object>(base: T, props: P$1): T exte
|
|
|
1014
1090
|
* - `jitter` (boolean) — Add small random offset (±10%) to intervals to avoid sync bursts (default: true)
|
|
1015
1091
|
* - `signal` (AbortSignal) — Optional abort signal to cancel polling
|
|
1016
1092
|
*
|
|
1017
|
-
* @returns
|
|
1018
|
-
*
|
|
1019
|
-
*
|
|
1093
|
+
* @returns Resolves with the truthy value `T` when successful.
|
|
1094
|
+
* @throws `AbortError` if aborted via signal
|
|
1095
|
+
* @throws `Error` if timed out
|
|
1020
1096
|
*
|
|
1021
1097
|
* @example
|
|
1022
1098
|
* ```ts
|
|
1023
|
-
* //
|
|
1024
|
-
* const job = await poll(async () => {
|
|
1099
|
+
* // Wait for a job to complete
|
|
1100
|
+
* const job = await poll.wait(async () => {
|
|
1025
1101
|
* const status = await getJobStatus();
|
|
1026
1102
|
* return status === 'done' ? status : null;
|
|
1027
1103
|
* }, { interval: 3000, timeout: 60000 });
|
|
@@ -1029,27 +1105,24 @@ declare function extendProps<T, P$1 extends object>(base: T, props: P$1): T exte
|
|
|
1029
1105
|
*
|
|
1030
1106
|
* @example
|
|
1031
1107
|
* ```ts
|
|
1032
|
-
* //
|
|
1033
|
-
* const
|
|
1034
|
-
*
|
|
1035
|
-
*
|
|
1036
|
-
*
|
|
1037
|
-
*
|
|
1038
|
-
* return null;
|
|
1039
|
-
* }
|
|
1040
|
-
* }, { interval: 1000, timeout: 30000 });
|
|
1108
|
+
* // Abort early based on domain logic
|
|
1109
|
+
* const job = await poll.wait(async () => {
|
|
1110
|
+
* const job = await getJob(id);
|
|
1111
|
+
* if (job?.is_cancelled) return poll.signal.abort;
|
|
1112
|
+
* return job?.is_finished ? job : null;
|
|
1113
|
+
* }, { timeout: 60000 });
|
|
1041
1114
|
* ```
|
|
1042
1115
|
*
|
|
1043
1116
|
* @example
|
|
1044
1117
|
* ```ts
|
|
1045
|
-
* //
|
|
1118
|
+
* // Cancel polling with an AbortSignal
|
|
1046
1119
|
* const controller = new AbortController();
|
|
1047
|
-
* setTimeout(() => controller.abort(), 10000);
|
|
1120
|
+
* setTimeout(() => controller.abort(), 10000);
|
|
1048
1121
|
*
|
|
1049
1122
|
* try {
|
|
1050
|
-
* const result = await poll(
|
|
1123
|
+
* const result = await poll.wait(
|
|
1051
1124
|
* () => checkExternalService(),
|
|
1052
|
-
* { interval: 2000, signal: controller.signal }
|
|
1125
|
+
* { interval: 2000, signal: controller.signal },
|
|
1053
1126
|
* );
|
|
1054
1127
|
* } catch (err) {
|
|
1055
1128
|
* if (err.name === 'AbortError') {
|
|
@@ -1057,29 +1130,20 @@ declare function extendProps<T, P$1 extends object>(base: T, props: P$1): T exte
|
|
|
1057
1130
|
* }
|
|
1058
1131
|
* }
|
|
1059
1132
|
* ```
|
|
1060
|
-
*
|
|
1061
|
-
* @example
|
|
1062
|
-
* ```ts
|
|
1063
|
-
* // Poll for user action completion
|
|
1064
|
-
* const userConfirmed = await poll(async () => {
|
|
1065
|
-
* const confirmations = await getPendingConfirmations();
|
|
1066
|
-
* return confirmations.length > 0 ? confirmations[0] : null;
|
|
1067
|
-
* }, { interval: 5000, timeout: 300000 }); // 5 min timeout
|
|
1068
|
-
* ```
|
|
1069
1133
|
*/
|
|
1070
|
-
declare function
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
signal
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
}
|
|
1134
|
+
declare function wait<T>(cond: () => Promise<T | null | false | undefined | PollControl>, options?: PollOptions): Promise<T | undefined>;
|
|
1135
|
+
declare const poll: {
|
|
1136
|
+
readonly wait: typeof wait;
|
|
1137
|
+
readonly watch: typeof watch;
|
|
1138
|
+
readonly signal: {
|
|
1139
|
+
/** Stop polling cleanly with no error */
|
|
1140
|
+
readonly abort: typeof ABORT;
|
|
1141
|
+
/** Skip this tick silently without emitting null */
|
|
1142
|
+
readonly retry: typeof RETRY;
|
|
1143
|
+
};
|
|
1144
|
+
};
|
|
1081
1145
|
//#endregion
|
|
1082
|
-
//#region src/functions/
|
|
1146
|
+
//#region src/functions/concurrency.d.ts
|
|
1083
1147
|
type TaskType<T> = Promise<T> | (() => Promise<T>);
|
|
1084
1148
|
type AwaitedTuple<T extends readonly TaskType<any>[] | []> = { -readonly [P in keyof T]: Awaited<T[P] extends (() => Promise<infer R>) ? R : T[P]> };
|
|
1085
1149
|
type ObjectValues<T extends Record<string, TaskType<any>>> = { [K in keyof T]: Awaited<T[K] extends (() => Promise<infer R>) ? R : T[K]> };
|
|
@@ -1117,6 +1181,8 @@ interface ScheduleOpts {
|
|
|
1117
1181
|
delay?: number;
|
|
1118
1182
|
/** Maximum time in milliseconds to wait for the task to complete. */
|
|
1119
1183
|
timeout?: number;
|
|
1184
|
+
/** Enable debug logging. Defaults to false. */
|
|
1185
|
+
debug?: boolean;
|
|
1120
1186
|
}
|
|
1121
1187
|
/**
|
|
1122
1188
|
* Runs a function asynchronously in the background without blocking the main thread.
|
package/dist/index.d.ts
CHANGED
|
@@ -994,17 +994,93 @@ declare function hydrate<T>(data: T): Hydrate<T>;
|
|
|
994
994
|
declare function extendProps<T, P$1 extends object>(base: T, props: P$1): T extends null | undefined ? T : T & P$1;
|
|
995
995
|
//#endregion
|
|
996
996
|
//#region src/functions/poll.d.ts
|
|
997
|
+
type PollOptions = Partial<{
|
|
998
|
+
interval: number;
|
|
999
|
+
timeout: number;
|
|
1000
|
+
signal: AbortSignal;
|
|
1001
|
+
jitter: boolean;
|
|
1002
|
+
}>;
|
|
1003
|
+
declare const ABORT: unique symbol;
|
|
1004
|
+
declare const RETRY: unique symbol;
|
|
1005
|
+
type PollControl = typeof ABORT | typeof RETRY;
|
|
1006
|
+
/**
|
|
1007
|
+
* Streams an async `cond` function, yielding `null` while waiting and the
|
|
1008
|
+
* final truthy value `T` when resolved.
|
|
1009
|
+
*
|
|
1010
|
+
* Designed for use in tRPC subscriptions or any async generator context where
|
|
1011
|
+
* you want to stream progress to the client instead of blocking.
|
|
1012
|
+
*
|
|
1013
|
+
* Keeps SSE/WebSocket connections alive on edge runtimes (e.g. Vercel) by
|
|
1014
|
+
* continuously emitting values rather than holding a silent open connection.
|
|
1015
|
+
*
|
|
1016
|
+
* @template T The type of the successful result.
|
|
1017
|
+
*
|
|
1018
|
+
* @param cond
|
|
1019
|
+
* A function returning a Promise that resolves to:
|
|
1020
|
+
* - a truthy value `T` → stop polling and yield it
|
|
1021
|
+
* - `poll.signal.abort` → stop polling cleanly with no error
|
|
1022
|
+
* - `poll.signal.retry` → skip this tick silently, no null emitted
|
|
1023
|
+
* - falsy/null/undefined → yield `null` and continue polling
|
|
1024
|
+
*
|
|
1025
|
+
* @param options
|
|
1026
|
+
* Configuration options:
|
|
1027
|
+
* - `interval` (number) — Time between polls in ms (default: 5000 ms)
|
|
1028
|
+
* - `timeout` (number) — Max total duration before failing (default: 5 min)
|
|
1029
|
+
* - `jitter` (boolean) — Add small random offset (±10%) to intervals to avoid sync bursts (default: true)
|
|
1030
|
+
* - `signal` (AbortSignal) — Optional abort signal to cancel polling
|
|
1031
|
+
*
|
|
1032
|
+
* @throws `AbortError` if aborted via signal
|
|
1033
|
+
* @throws `Error` if timed out
|
|
1034
|
+
*
|
|
1035
|
+
* @example
|
|
1036
|
+
* ```ts
|
|
1037
|
+
* // tRPC subscription — stream null while job is pending, emit result when done
|
|
1038
|
+
* syncImageJob: privateProcedure
|
|
1039
|
+
* .input(z.object({ id: z.coerce.number() }))
|
|
1040
|
+
* .subscription(async function* ({ ctx, input, signal }) {
|
|
1041
|
+
* yield* poll.watch(
|
|
1042
|
+
* async () => {
|
|
1043
|
+
* const job = await getJob(input.id);
|
|
1044
|
+
* if (job?.is_cancelled) return poll.signal.abort; // stop cleanly
|
|
1045
|
+
* if (job?.is_paused) return poll.signal.retry; // skip this tick
|
|
1046
|
+
* return job?.is_finished ? job : null;
|
|
1047
|
+
* },
|
|
1048
|
+
* { interval: 15000, signal },
|
|
1049
|
+
* );
|
|
1050
|
+
* }),
|
|
1051
|
+
* ```
|
|
1052
|
+
*
|
|
1053
|
+
* @example
|
|
1054
|
+
* ```ts
|
|
1055
|
+
* // Manually iterate
|
|
1056
|
+
* for await (const result of poll.watch(() => getJobStatus(), { interval: 3000 })) {
|
|
1057
|
+
* if (result === null) console.log('still waiting...');
|
|
1058
|
+
* else console.log('done!', result);
|
|
1059
|
+
* }
|
|
1060
|
+
* ```
|
|
1061
|
+
*/
|
|
1062
|
+
declare function watch<T>(cond: () => Promise<T | null | false | undefined | PollControl>, {
|
|
1063
|
+
interval,
|
|
1064
|
+
timeout,
|
|
1065
|
+
jitter,
|
|
1066
|
+
signal
|
|
1067
|
+
}?: PollOptions): AsyncGenerator<T | null>;
|
|
997
1068
|
/**
|
|
998
1069
|
* Repeatedly polls an async `cond` function UNTIL it returns a TRUTHY value,
|
|
999
1070
|
* or until the operation times out or is aborted.
|
|
1000
1071
|
*
|
|
1001
|
-
* Designed for waiting on async jobs, external state, or delayed availability
|
|
1072
|
+
* Designed for waiting on async jobs, external state, or delayed availability
|
|
1073
|
+
* where you only care about the final result and not intermediate states.
|
|
1074
|
+
*
|
|
1075
|
+
* Use `poll.watch` instead if you need to stream progress (e.g. tRPC subscriptions).
|
|
1002
1076
|
*
|
|
1003
1077
|
* @template T The type of the successful result.
|
|
1004
1078
|
*
|
|
1005
1079
|
* @param cond
|
|
1006
1080
|
* A function returning a Promise that resolves to:
|
|
1007
1081
|
* - a truthy value `T` → stop polling and return it
|
|
1082
|
+
* - `poll.signal.abort` → stop polling cleanly, resolves with undefined
|
|
1083
|
+
* - `poll.signal.retry` → skip this tick silently
|
|
1008
1084
|
* - falsy/null/undefined → continue polling
|
|
1009
1085
|
*
|
|
1010
1086
|
* @param options
|
|
@@ -1014,14 +1090,14 @@ declare function extendProps<T, P$1 extends object>(base: T, props: P$1): T exte
|
|
|
1014
1090
|
* - `jitter` (boolean) — Add small random offset (±10%) to intervals to avoid sync bursts (default: true)
|
|
1015
1091
|
* - `signal` (AbortSignal) — Optional abort signal to cancel polling
|
|
1016
1092
|
*
|
|
1017
|
-
* @returns
|
|
1018
|
-
*
|
|
1019
|
-
*
|
|
1093
|
+
* @returns Resolves with the truthy value `T` when successful.
|
|
1094
|
+
* @throws `AbortError` if aborted via signal
|
|
1095
|
+
* @throws `Error` if timed out
|
|
1020
1096
|
*
|
|
1021
1097
|
* @example
|
|
1022
1098
|
* ```ts
|
|
1023
|
-
* //
|
|
1024
|
-
* const job = await poll(async () => {
|
|
1099
|
+
* // Wait for a job to complete
|
|
1100
|
+
* const job = await poll.wait(async () => {
|
|
1025
1101
|
* const status = await getJobStatus();
|
|
1026
1102
|
* return status === 'done' ? status : null;
|
|
1027
1103
|
* }, { interval: 3000, timeout: 60000 });
|
|
@@ -1029,27 +1105,24 @@ declare function extendProps<T, P$1 extends object>(base: T, props: P$1): T exte
|
|
|
1029
1105
|
*
|
|
1030
1106
|
* @example
|
|
1031
1107
|
* ```ts
|
|
1032
|
-
* //
|
|
1033
|
-
* const
|
|
1034
|
-
*
|
|
1035
|
-
*
|
|
1036
|
-
*
|
|
1037
|
-
*
|
|
1038
|
-
* return null;
|
|
1039
|
-
* }
|
|
1040
|
-
* }, { interval: 1000, timeout: 30000 });
|
|
1108
|
+
* // Abort early based on domain logic
|
|
1109
|
+
* const job = await poll.wait(async () => {
|
|
1110
|
+
* const job = await getJob(id);
|
|
1111
|
+
* if (job?.is_cancelled) return poll.signal.abort;
|
|
1112
|
+
* return job?.is_finished ? job : null;
|
|
1113
|
+
* }, { timeout: 60000 });
|
|
1041
1114
|
* ```
|
|
1042
1115
|
*
|
|
1043
1116
|
* @example
|
|
1044
1117
|
* ```ts
|
|
1045
|
-
* //
|
|
1118
|
+
* // Cancel polling with an AbortSignal
|
|
1046
1119
|
* const controller = new AbortController();
|
|
1047
|
-
* setTimeout(() => controller.abort(), 10000);
|
|
1120
|
+
* setTimeout(() => controller.abort(), 10000);
|
|
1048
1121
|
*
|
|
1049
1122
|
* try {
|
|
1050
|
-
* const result = await poll(
|
|
1123
|
+
* const result = await poll.wait(
|
|
1051
1124
|
* () => checkExternalService(),
|
|
1052
|
-
* { interval: 2000, signal: controller.signal }
|
|
1125
|
+
* { interval: 2000, signal: controller.signal },
|
|
1053
1126
|
* );
|
|
1054
1127
|
* } catch (err) {
|
|
1055
1128
|
* if (err.name === 'AbortError') {
|
|
@@ -1057,29 +1130,20 @@ declare function extendProps<T, P$1 extends object>(base: T, props: P$1): T exte
|
|
|
1057
1130
|
* }
|
|
1058
1131
|
* }
|
|
1059
1132
|
* ```
|
|
1060
|
-
*
|
|
1061
|
-
* @example
|
|
1062
|
-
* ```ts
|
|
1063
|
-
* // Poll for user action completion
|
|
1064
|
-
* const userConfirmed = await poll(async () => {
|
|
1065
|
-
* const confirmations = await getPendingConfirmations();
|
|
1066
|
-
* return confirmations.length > 0 ? confirmations[0] : null;
|
|
1067
|
-
* }, { interval: 5000, timeout: 300000 }); // 5 min timeout
|
|
1068
|
-
* ```
|
|
1069
1133
|
*/
|
|
1070
|
-
declare function
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
signal
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
}
|
|
1134
|
+
declare function wait<T>(cond: () => Promise<T | null | false | undefined | PollControl>, options?: PollOptions): Promise<T | undefined>;
|
|
1135
|
+
declare const poll: {
|
|
1136
|
+
readonly wait: typeof wait;
|
|
1137
|
+
readonly watch: typeof watch;
|
|
1138
|
+
readonly signal: {
|
|
1139
|
+
/** Stop polling cleanly with no error */
|
|
1140
|
+
readonly abort: typeof ABORT;
|
|
1141
|
+
/** Skip this tick silently without emitting null */
|
|
1142
|
+
readonly retry: typeof RETRY;
|
|
1143
|
+
};
|
|
1144
|
+
};
|
|
1081
1145
|
//#endregion
|
|
1082
|
-
//#region src/functions/
|
|
1146
|
+
//#region src/functions/concurrency.d.ts
|
|
1083
1147
|
type TaskType<T> = Promise<T> | (() => Promise<T>);
|
|
1084
1148
|
type AwaitedTuple<T extends readonly TaskType<any>[] | []> = { -readonly [P in keyof T]: Awaited<T[P] extends (() => Promise<infer R>) ? R : T[P]> };
|
|
1085
1149
|
type ObjectValues<T extends Record<string, TaskType<any>>> = { [K in keyof T]: Awaited<T[K] extends (() => Promise<infer R>) ? R : T[K]> };
|
|
@@ -1117,6 +1181,8 @@ interface ScheduleOpts {
|
|
|
1117
1181
|
delay?: number;
|
|
1118
1182
|
/** Maximum time in milliseconds to wait for the task to complete. */
|
|
1119
1183
|
timeout?: number;
|
|
1184
|
+
/** Enable debug logging. Defaults to false. */
|
|
1185
|
+
debug?: boolean;
|
|
1120
1186
|
}
|
|
1121
1187
|
/**
|
|
1122
1188
|
* Runs a function asynchronously in the background without blocking the main thread.
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=e=>!e,t=e=>e==null,n=e=>typeof e==`boolean`,r=e=>typeof e==`string`,i=e=>{if(typeof e==`number`)return Number.isFinite(e);if(typeof e==`string`){let t=Number(e);return Number.isFinite(t)}return!1},a=e=>Array.isArray(e),o=e=>typeof e==`function`,s=e=>{if(e==null)return!0;switch(typeof e){case`string`:case`number`:case`bigint`:case`boolean`:case`symbol`:return!0;default:return!1}};function c(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}function l(e,...t){let n,r={},i=t[t.length-1];i&&typeof i==`object`&&!Array.isArray(i)&&(i.arrayMerge!==void 0||i.clone!==void 0||i.customMerge!==void 0||i.functionMerge!==void 0||i.maxDepth!==void 0)?(r={...r,...i},n=t.slice(0,-1)):n=t;let{arrayMerge:a=`replace`,clone:o=!0,functionMerge:s=`replace`,maxDepth:l=100,customMerge:u}=r,d=new WeakMap;return f(e,n,0);function f(e,t,n){if(n>=l)return console.warn(`[deepmerge] Maximum depth ${l} exceeded. Returning target as-is.`),e;if(!c(e)&&!Array.isArray(e)){for(let n of t)if(n!==void 0){if(u){let t=u(``,e,n);if(t!==void 0)return t}return typeof e==`function`&&typeof n==`function`&&s===`compose`?(...t)=>{e(...t),n(...t)}:n}return e}let r=o?Array.isArray(e)?[...e]:{...e}:e;for(let e of t)if(e!=null&&!d.has(e))if(d.set(e,r),Array.isArray(r)&&Array.isArray(e))r=p(r,e,a);else if(c(r)&&c(e)){let t=new Set([...Object.keys(r),...Object.keys(e),...Object.getOwnPropertySymbols(r),...Object.getOwnPropertySymbols(e)]);for(let i of t){let t=r[i],o=e[i];u&&u(i,t,o)!==void 0?r[i]=u(i,t,o):typeof t==`function`&&typeof o==`function`?s===`compose`?r[i]=(...e)=>{t(...e),o(...e)}:r[i]=o:c(t)&&c(o)?r[i]=f(t,[o],n+1):Array.isArray(t)&&Array.isArray(o)?r[i]=p(t,o,a):o!==void 0&&(r[i]=o)}}else r=e;return r}function p(e,t,n){if(typeof n==`function`)return n(e,t);switch(n){case`concat`:return[...e,...t];case`merge`:let n=Math.max(e.length,t.length),r=[];for(let i=0;i<n;i++)i<e.length&&i<t.length?c(e[i])&&c(t[i])?r[i]=f(e[i],[t[i]],0):r[i]=t[i]:i<e.length?r[i]=e[i]:r[i]=t[i];return r;case`replace`:default:return[...t]}}}function u(e,t,n){if(Array.isArray(t))return t.map(t=>u(e,t,n));if(typeof t==`object`&&t&&!Array.isArray(t)){let r={};for(let i in t)t.hasOwnProperty(i)&&(r[i]=u(e,t[i],n));return r}if(typeof t!=`string`)return n;let r=(()=>t===``?[]:t.split(`.`).filter(e=>e!==``))(),i=e;for(let e of r){if(i==null)return n;let t=typeof e==`string`&&Array.isArray(i)&&/^\d+$/.test(e)?Number.parseInt(e,10):e;i=i[t]}return i===void 0?n:i}function d(e){return f(e)}function f(e){if(e!==null){if(typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(f);if(c(e)){let t={};for(let n in e)t[n]=f(e[n]);return t}return e}}function p(e,t){return e==null?e:Object.assign(e,t)}function m(e){return(e.split(`.`).pop()||e).replace(/([a-z])([A-Z])/g,`$1 $2`).split(/[-_|�\s]+/).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}const h=`àáãäâèéëêìíïîòóöôùúüûñç·/_,:;`,g=e=>{if(typeof e!=`string`)throw TypeError(`Input must be a string`);let t=e.trim().toLowerCase(),n={};for(let e=0;e<29;e++)n[h.charAt(e)]=`aaaaaeeeeiiiioooouuuunc------`.charAt(e);return t=t.replace(RegExp(`[${h}]`,`g`),e=>n[e]||e),t.replace(/[^a-z0-9 -]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-+/,``).replace(/-+$/,``)||``},_=(e=1e3,t)=>new Promise(n=>{if(t?.aborted)return n();let r=setTimeout(()=>{a(),n()},e);function i(){clearTimeout(r),a(),n()}function a(){t?.removeEventListener(`abort`,i)}t&&t.addEventListener(`abort`,i,{once:!0})});function v(e,t=100,n){if(typeof e!=`function`)throw TypeError(`Expected the first parameter to be a function, got \`${typeof e}\`.`);if(t<0)throw RangeError("`wait` must not be negative.");let r=n?.immediate??!1,i,a,o,s;function c(){return s=e.apply(o,a),a=void 0,o=void 0,s}let l=function(...e){return a=e,o=this,i===void 0&&r&&(s=c.call(this)),i!==void 0&&clearTimeout(i),i=setTimeout(c.bind(this),t),s};return Object.defineProperty(l,`isPending`,{get(){return i!==void 0}}),l}function y(e,t=100,n){if(typeof e!=`function`)throw TypeError(`Expected the first parameter to be a function, got \`${typeof e}\`.`);if(t<0)throw RangeError("`wait` must not be negative.");let r=n?.leading??!0,i=n?.trailing??!0,a,o,s,c,l;function u(){c=Date.now(),l=e.apply(s,o),o=void 0,s=void 0}function d(){a=void 0,i&&o&&u()}let f=function(...e){let n=c?Date.now()-c:1/0;return o=e,s=this,n>=t?r?u():a=setTimeout(d,t):!a&&i&&(a=setTimeout(d,t-n)),l};return Object.defineProperty(f,`isPending`,{get(){return a!==void 0}}),f}function b(e,...t){let n=t.length===1&&Array.isArray(t[0])?t[0]:t,r=0;return e.replace(/%s/g,()=>{let e=n[r++];return e===void 0?``:String(e)})}function x(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function S(e,t={}){if(!e)return``;let{lowercase:n=!0,removeAccents:r=!0,removeNonAlphanumeric:i=!0}=t,a=e.normalize(`NFC`);return r&&(a=a.normalize(`NFD`).replace(/\p{M}/gu,``)),i&&(a=a.replace(/^[^\p{L}\p{N}]*|[^\p{L}\p{N}]*$/gu,``)),n&&(a=a.toLocaleLowerCase()),a}function C(e,...t){return typeof e==`function`?e(...t):e}async function
|
|
1
|
+
const e=e=>!e,t=e=>e==null,n=e=>typeof e==`boolean`,r=e=>typeof e==`string`,i=e=>{if(typeof e==`number`)return Number.isFinite(e);if(typeof e==`string`){let t=Number(e);return Number.isFinite(t)}return!1},a=e=>Array.isArray(e),o=e=>typeof e==`function`,s=e=>{if(e==null)return!0;switch(typeof e){case`string`:case`number`:case`bigint`:case`boolean`:case`symbol`:return!0;default:return!1}};function c(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}function l(e,...t){let n,r={},i=t[t.length-1];i&&typeof i==`object`&&!Array.isArray(i)&&(i.arrayMerge!==void 0||i.clone!==void 0||i.customMerge!==void 0||i.functionMerge!==void 0||i.maxDepth!==void 0)?(r={...r,...i},n=t.slice(0,-1)):n=t;let{arrayMerge:a=`replace`,clone:o=!0,functionMerge:s=`replace`,maxDepth:l=100,customMerge:u}=r,d=new WeakMap;return f(e,n,0);function f(e,t,n){if(n>=l)return console.warn(`[deepmerge] Maximum depth ${l} exceeded. Returning target as-is.`),e;if(!c(e)&&!Array.isArray(e)){for(let n of t)if(n!==void 0){if(u){let t=u(``,e,n);if(t!==void 0)return t}return typeof e==`function`&&typeof n==`function`&&s===`compose`?(...t)=>{e(...t),n(...t)}:n}return e}let r=o?Array.isArray(e)?[...e]:{...e}:e;for(let e of t)if(e!=null&&!d.has(e))if(d.set(e,r),Array.isArray(r)&&Array.isArray(e))r=p(r,e,a);else if(c(r)&&c(e)){let t=new Set([...Object.keys(r),...Object.keys(e),...Object.getOwnPropertySymbols(r),...Object.getOwnPropertySymbols(e)]);for(let i of t){let t=r[i],o=e[i];u&&u(i,t,o)!==void 0?r[i]=u(i,t,o):typeof t==`function`&&typeof o==`function`?s===`compose`?r[i]=(...e)=>{t(...e),o(...e)}:r[i]=o:c(t)&&c(o)?r[i]=f(t,[o],n+1):Array.isArray(t)&&Array.isArray(o)?r[i]=p(t,o,a):o!==void 0&&(r[i]=o)}}else r=e;return r}function p(e,t,n){if(typeof n==`function`)return n(e,t);switch(n){case`concat`:return[...e,...t];case`merge`:let n=Math.max(e.length,t.length),r=[];for(let i=0;i<n;i++)i<e.length&&i<t.length?c(e[i])&&c(t[i])?r[i]=f(e[i],[t[i]],0):r[i]=t[i]:i<e.length?r[i]=e[i]:r[i]=t[i];return r;case`replace`:default:return[...t]}}}function u(e,t,n){if(Array.isArray(t))return t.map(t=>u(e,t,n));if(typeof t==`object`&&t&&!Array.isArray(t)){let r={};for(let i in t)t.hasOwnProperty(i)&&(r[i]=u(e,t[i],n));return r}if(typeof t!=`string`)return n;let r=(()=>t===``?[]:t.split(`.`).filter(e=>e!==``))(),i=e;for(let e of r){if(i==null)return n;let t=typeof e==`string`&&Array.isArray(i)&&/^\d+$/.test(e)?Number.parseInt(e,10):e;i=i[t]}return i===void 0?n:i}function d(e){return f(e)}function f(e){if(e!==null){if(typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(f);if(c(e)){let t={};for(let n in e)t[n]=f(e[n]);return t}return e}}function p(e,t){return e==null?e:Object.assign(e,t)}function m(e){return(e.split(`.`).pop()||e).replace(/([a-z])([A-Z])/g,`$1 $2`).split(/[-_|�\s]+/).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}const h=`àáãäâèéëêìíïîòóöôùúüûñç·/_,:;`,g=e=>{if(typeof e!=`string`)throw TypeError(`Input must be a string`);let t=e.trim().toLowerCase(),n={};for(let e=0;e<29;e++)n[h.charAt(e)]=`aaaaaeeeeiiiioooouuuunc------`.charAt(e);return t=t.replace(RegExp(`[${h}]`,`g`),e=>n[e]||e),t.replace(/[^a-z0-9 -]/g,``).replace(/\s+/g,`-`).replace(/-+/g,`-`).replace(/^-+/,``).replace(/-+$/,``)||``},_=(e=1e3,t)=>new Promise(n=>{if(t?.aborted)return n();let r=setTimeout(()=>{a(),n()},e);function i(){clearTimeout(r),a(),n()}function a(){t?.removeEventListener(`abort`,i)}t&&t.addEventListener(`abort`,i,{once:!0})});function v(e,t=100,n){if(typeof e!=`function`)throw TypeError(`Expected the first parameter to be a function, got \`${typeof e}\`.`);if(t<0)throw RangeError("`wait` must not be negative.");let r=n?.immediate??!1,i,a,o,s;function c(){return s=e.apply(o,a),a=void 0,o=void 0,s}let l=function(...e){return a=e,o=this,i===void 0&&r&&(s=c.call(this)),i!==void 0&&clearTimeout(i),i=setTimeout(c.bind(this),t),s};return Object.defineProperty(l,`isPending`,{get(){return i!==void 0}}),l}function y(e,t=100,n){if(typeof e!=`function`)throw TypeError(`Expected the first parameter to be a function, got \`${typeof e}\`.`);if(t<0)throw RangeError("`wait` must not be negative.");let r=n?.leading??!0,i=n?.trailing??!0,a,o,s,c,l;function u(){c=Date.now(),l=e.apply(s,o),o=void 0,s=void 0}function d(){a=void 0,i&&o&&u()}let f=function(...e){let n=c?Date.now()-c:1/0;return o=e,s=this,n>=t?r?u():a=setTimeout(d,t):!a&&i&&(a=setTimeout(d,t-n)),l};return Object.defineProperty(f,`isPending`,{get(){return a!==void 0}}),f}function b(e,...t){let n=t.length===1&&Array.isArray(t[0])?t[0]:t,r=0;return e.replace(/%s/g,()=>{let e=n[r++];return e===void 0?``:String(e)})}function x(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function S(e,t={}){if(!e)return``;let{lowercase:n=!0,removeAccents:r=!0,removeNonAlphanumeric:i=!0}=t,a=e.normalize(`NFC`);return r&&(a=a.normalize(`NFD`).replace(/\p{M}/gu,``)),i&&(a=a.replace(/^[^\p{L}\p{N}]*|[^\p{L}\p{N}]*$/gu,``)),n&&(a=a.toLocaleLowerCase()),a}function C(e,...t){return typeof e==`function`?e(...t):e}const w=Symbol(`poll.signal.abort`),T=Symbol(`poll.signal.retry`);async function*E(e,{interval:t=5e3,timeout:n=300*1e3,jitter:r=!0,signal:i}={}){let a=Date.now();for(;;){if(i?.aborted)throw new DOMException(`Polling aborted`,`AbortError`);let o=await e();if(o===w)return;if(o===T){await _(r?t+(Math.random()-.5)*t*.2:t,i);continue}if(o){yield o;return}if(Date.now()-a>=n)throw Error(`Polling timed out after ${n}ms`);yield null,await _(r?t+(Math.random()-.5)*t*.2:t,i)}}async function D(e,t={}){for await(let n of E(e,t))if(n)return n}const O={wait:D,watch:E,signal:{abort:w,retry:T}};async function k(e,t={}){let{concurrency:n=1/0,timeout:r=1/0,signal:i,retry:a=0,retryDelay:o=0,throwOnFirstError:s=!1,ignoreErrors:c=!1}=t,l=Array.isArray(e),u={};l?e.forEach((e,t)=>{u[t.toString()]=e}):Object.entries(e).forEach(([e,t])=>{u[e]=t});let d=Object.keys(u);if(d.length===0)return{results:l?[]:{},errors:[],succeeded:0,failed:0,duration:0};let f=Date.now(),p=[],m=[],h=0,g=0,v=0,y=!1,b=s?null:void 0,x=async e=>{let t=0;for(;t<=a&&!y;)try{let t=u[e],n=await(typeof t==`function`?t():t);p.push([e,n]),g++;return}catch(e){if(t===a){let t=e instanceof Error?e:Error(String(e));m.push(t),v++,!c&&s&&!b&&(b=t,y=!0);return}t++,o>0&&await _(o,i)}},S=Array.from({length:Math.min(n,d.length)},async()=>{for(;!y;){let e=h++;if(e>=d.length)return;if(i?.aborted){y=!0;return}await x(d[e])}}),C=Promise.all(S);if(r===1/0?await C:await Promise.race([C,_(r,i).then(()=>{throw y=!0,Error(`Concurrence timed out after ${r}ms`)})]),b&&s)throw b;return l?{results:p.sort((e,t)=>Number(e[0])-Number(t[0])).map(([,e])=>e),errors:m,succeeded:g,failed:v,duration:Date.now()-f}:{results:Object.fromEntries(p),errors:m,succeeded:g,failed:v,duration:Date.now()-f}}function A(e,t={}){let{retry:n=0,delay:r=0,debug:i=!1}=t,a=Date.now(),o=async t=>{try{if(await e(),i){let e=Date.now()-a;console.log(`⚡[schedule.ts] Completed in ${e}ms`)}}catch(e){if(i&&console.log(`⚡[schedule.ts] err:`,e),t>0)i&&console.log(`⚡[schedule.ts] Retrying in ${r}ms...`),setTimeout(()=>o(t-1),r);else if(i){let e=Date.now()-a;console.log(`⚡[schedule.ts] Failed after ${e}ms`)}}};setTimeout(()=>o(n),0)}function j(e){if(e instanceof Promise)return e.then(e=>[null,e]).catch(e=>[e,null]);try{return[null,e()]}catch(t){return console.log(`\x1b[31m🛡 [shield]\x1b[0m ${e.name} failed →`,t),[t,null]}}export{m as convertToNormalCase,g as convertToSlug,v as debounce,l as deepmerge,x as escapeRegExp,p as extendProps,u as extract,d as hydrate,a as isArray,n as isBoolean,e as isFalsy,i as isFiniteNumber,o as isFunction,t as isNullish,c as isPlainObject,s as isPrimitive,r as isString,S as normalizeText,O as poll,b as printf,A as schedule,j as shield,_ as sleep,y as throttle,C as unwrap,k as withConcurrency};
|