@ts-utilities/core 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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=>typeof e==`number`&&Number.isFinite(e),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){return d(e)}function d(e){if(e!==null){if(typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(d);if(c(e)){let t={};for(let n in e)t[n]=d(e[n]);return t}return e}}function f(e,t,n){if(Array.isArray(t))return t.map(t=>f(e,t,n));if(typeof t==`object`&&t&&!Array.isArray(t)){let r={};for(let i in t)t.hasOwnProperty(i)&&(r[i]=f(e,t[i],n));return r}if(typeof t!=`string`||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 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}async function w(e,{interval:t=5e3,timeout:n=300*1e3,jitter:r=!0,signal:i}={}){let a=Date.now(),o=i?.aborted??!1,s=()=>{o=!0};i?.addEventListener(`abort`,s,{once:!0});try{for(let s=0;;s++){if(o)throw Error(`Polling aborted`);let s=await e();if(s)return s;if(Date.now()-a>=n)throw Error(`Polling timed out`,{cause:`Polling timed out after ${n}ms`});await v(r?t+(Math.random()-.5)*t*.2:t,i)}}catch(e){throw e}finally{i?.removeEventListener(`abort`,s)}}async function T(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 E(e,t={}){let{retry:n=0,delay:r=0}=t,i=Date.now(),a=async t=>{try{await e();let t=Date.now()-i;console.log(`⚡[schedule.ts] Completed in ${t}ms`)}catch(e){if(console.log(`⚡[schedule.ts] err:`,e),t>0)console.log(`⚡[schedule.ts] Retrying in ${r}ms...`),setTimeout(()=>a(t-1),r);else{let e=Date.now()-i;console.log(`⚡[schedule.ts] Failed after ${e}ms`)}}};setTimeout(()=>a(n),0)}function D(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=f,exports.hydrate=u,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=w,exports.printf=x,exports.schedule=E,exports.shield=D,exports.sleep=v,exports.throttle=b,exports.withConcurrency=T;
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){let r=n?.defaultValue;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 r;let i=(()=>t===``?[]:t.split(`.`).filter(e=>e!==``))(),a=e;for(let e of i){if(a==null)return r;let t=typeof e==`string`&&Array.isArray(a)&&/^\d+$/.test(e)?Number.parseInt(e,10):e;a=a[t]}return a===void 0?r:a}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}async function w(e,{interval:t=5e3,timeout:n=300*1e3,jitter:r=!0,signal:i}={}){let a=Date.now(),o=i?.aborted??!1,s=()=>{o=!0};i?.addEventListener(`abort`,s,{once:!0});try{for(let s=0;;s++){if(o)throw Error(`Polling aborted`);let s=await e();if(s)return s;if(Date.now()-a>=n)throw Error(`Polling timed out`,{cause:`Polling timed out after ${n}ms`});await v(r?t+(Math.random()-.5)*t*.2:t,i)}}catch(e){throw e}finally{i?.removeEventListener(`abort`,s)}}async function T(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 E(e,t={}){let{retry:n=0,delay:r=0}=t,i=Date.now(),a=async t=>{try{await e();let t=Date.now()-i;console.log(`⚡[schedule.ts] Completed in ${t}ms`)}catch(e){if(console.log(`⚡[schedule.ts] err:`,e),t>0)console.log(`⚡[schedule.ts] Retrying in ${r}ms...`),setTimeout(()=>a(t-1),r);else{let e=Date.now()-i;console.log(`⚡[schedule.ts] Failed after ${e}ms`)}}};setTimeout(()=>a(n),0)}function D(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=w,exports.printf=x,exports.schedule=E,exports.shield=D,exports.sleep=v,exports.throttle=b,exports.withConcurrency=T;
package/dist/index.d.cts CHANGED
@@ -94,54 +94,6 @@ type TMerged<T> = [T] extends [Array<any>] ? { [K in keyof T]: TMerged<T[K]> } :
94
94
  declare function deepmerge<T extends Record<string, any>, S$1 extends Record<string, any>[]>(target: T, ...sources: S$1): TMerged<T | S$1[number]>;
95
95
  declare function deepmerge<T extends Record<string, any>, S$1 extends Record<string, any>[]>(target: T, sources: S$1, options?: DeepMergeOptions): TMerged<T | S$1[number]>;
96
96
  //#endregion
97
- //#region src/functions/hydrate.d.ts
98
- type Hydrate<T> = T extends null ? undefined : T extends (infer U)[] ? Hydrate<U>[] : T extends object ? { [K in keyof T]: Hydrate<T[K]> } : T;
99
- /**
100
- * Converts all `null` values to `undefined` in the data structure recursively.
101
- *
102
- * @param data - Any input data (object, array, primitive)
103
- * @returns Same type as input, but with all nulls replaced by undefined
104
- *
105
- * @example
106
- * ```ts
107
- * // Basic object hydration
108
- * hydrate({ name: null, age: 25 }) // { name: undefined, age: 25 }
109
- *
110
- * // Nested object hydration
111
- * hydrate({
112
- * user: { email: null, profile: { avatar: null } },
113
- * settings: { theme: 'dark' }
114
- * })
115
- * // { user: { email: undefined, profile: { avatar: undefined } }, settings: { theme: 'dark' } }
116
- *
117
- * // Array hydration
118
- * hydrate([null, 'hello', null, 42]) // [undefined, 'hello', undefined, 42]
119
- *
120
- * // Mixed data structures
121
- * hydrate({
122
- * posts: [null, { title: 'Hello', content: null }],
123
- * metadata: { published: null, tags: ['react', null] }
124
- * })
125
- * ```
126
- *
127
- * @example
128
- * ```ts
129
- * // API response normalization
130
- * const apiResponse = await fetch('/api/user');
131
- * const rawData = await apiResponse.json(); // May contain null values
132
- * const normalizedData = hydrate(rawData); // Convert nulls to undefined
133
- *
134
- * // Database result processing
135
- * const dbResult = query('SELECT * FROM users'); // Some fields may be NULL
136
- * const cleanData = hydrate(dbResult); // Normalize for consistent handling
137
- *
138
- * // Form data sanitization
139
- * const formData = getFormValues(); // May have null values from empty fields
140
- * const sanitizedData = hydrate(formData); // Prepare for validation/state
141
- * ```
142
- */
143
- declare function hydrate<T>(data: T): Hydrate<T>;
144
- //#endregion
145
97
  //#region src/types/utilities.d.ts
146
98
  /**
147
99
  * Extracts the keys of an object type as a union type.
@@ -757,19 +709,22 @@ declare const isBoolean: (val: unknown) => val is boolean;
757
709
  */
758
710
  declare const isString: (val: unknown) => val is string;
759
711
  /**
760
- * Type guard that checks whether a value is a finite number.
712
+ * Checks whether a value represents a finite number.
761
713
  *
762
714
  * This excludes `NaN`, `Infinity`, and `-Infinity`.
715
+ * Accepts numbers or strings that can be parsed to finite numbers.
763
716
  *
764
717
  * @param val - The value to check
765
- * @returns `true` if the value is a finite number
718
+ * @returns `true` if the value represents a finite number
766
719
  *
767
720
  * @example
768
721
  * isFiniteNumber(42); // true
722
+ * isFiniteNumber('42'); // true
769
723
  * isFiniteNumber(NaN); // false
770
724
  * isFiniteNumber(Infinity); // false
725
+ * isFiniteNumber('abc'); // false
771
726
  */
772
- declare const isFiniteNumber: (val: unknown) => val is number;
727
+ declare const isFiniteNumber: (val: unknown) => boolean;
773
728
  /**
774
729
  * Type guard that checks if a value is an array.
775
730
  *
@@ -819,98 +774,71 @@ declare const isPrimitive: (val: unknown) => val is Primitive;
819
774
  */
820
775
  declare function isPlainObject(value: unknown): value is Record<string, any>;
821
776
  //#endregion
822
- //#region src/functions/object.d.ts
823
- /**
824
- * Type representing a path split into segments
825
- * @template S - The original path string type
826
- */
827
- type SplitPath<S$1 extends string> = S$1 extends `${infer First}.${infer Rest}` ? [First, ...SplitPath<Rest>] : [S$1];
828
- /**
829
- * Recursive type to resolve nested object types based on path
830
- * @template T - Current object type
831
- * @template K - Array of path segments
832
- */
777
+ //#region src/functions/extract.d.ts
778
+ type SplitPath<P$1 extends string> = P$1 extends `${infer First}.${infer Rest}` ? [First, ...SplitPath<Rest>] : [P$1];
833
779
  type GetValue<T, K$1 extends Array<string | number>> = K$1 extends [infer First, ...infer Rest] ? First extends keyof T ? GetValue<T[First], Rest extends Array<string | number> ? Rest : []> : First extends `${number}` ? T extends any[] ? GetValue<T[number], Rest extends Array<string | number> ? Rest : []> : undefined : undefined : T;
780
+ interface ExtractOptions<D = never> {
781
+ defaultValue?: D;
782
+ }
783
+ type ExtractSinglePath<T, P$1 extends string, D> = Exclude<GetValue<T, SplitPath<P$1>>, undefined> | D;
784
+ type ExtractSingle<T, P$1 extends string> = GetValue<T, SplitPath<P$1>> | undefined;
785
+ type IsString<T> = T extends string ? (string extends T ? true : false) : false;
786
+ declare function extract<const T extends object, P$1 extends string, D>(obj: T, path: P$1, opts?: ExtractOptions<D>): IsString<P$1> extends true ? P$1 extends NestedKeyOf<T> ? ExtractSinglePath<T, P$1, D> : unknown : never;
787
+ declare function extract<const T extends object, P$1 extends string>(obj: T, path: P$1): IsString<P$1> extends true ? P$1 extends NestedKeyOf<T> ? ExtractSingle<T, P$1> : unknown : never;
788
+ declare function extract<T, D>(obj: T, paths: readonly string[], opts?: ExtractOptions<D>): unknown[];
789
+ declare function extract<T>(obj: T, paths: readonly string[]): unknown[];
790
+ declare function extract<T, D>(obj: T, paths: Record<string, string>, opts?: ExtractOptions<D>): { readonly [K in keyof typeof paths]: unknown };
791
+ declare function extract<T>(obj: T, paths: Record<string, string>): { readonly [K in keyof typeof paths]: unknown };
792
+ //#endregion
793
+ //#region src/functions/hydrate.d.ts
794
+ type Hydrate<T> = T extends null ? undefined : T extends (infer U)[] ? Hydrate<U>[] : T extends object ? { [K in keyof T]: Hydrate<T[K]> } : T;
834
795
  /**
835
- * Get a nested value from an object using dot notation path
836
- * @template T - Object type
837
- * @template S - Valid path string type constrained by object structure
838
- * @template D - Default value type
839
- * @param obj - Source object
840
- * @param path - Dot-separated path string (constrained to valid paths)
841
- * @param defaultValue - Fallback value if path not found
842
- * @returns Value at path or default value
796
+ * Converts all `null` values to `undefined` in the data structure recursively.
843
797
  *
844
- * @example
845
- * // use as const for better type safety for arrays
846
- * extract({a: [{b: 1}]} as const, 'a.0.b', 2) // 1
847
- * extract({a: {b: 1}}, 'a.b', 2) // 1
848
- */
849
- declare function extract<const T extends object, S$1 extends NestedKeyOf<T>, D>(obj: T, path: S$1, defaultValue: D): Exclude<GetValue<T, SplitPath<S$1>>, undefined> | D;
850
- /**
851
- * Get a nested value from an object using dot notation path
852
- * @template T - Object type
853
- * @template S - Valid path string type constrained by object structure
854
- * @param obj - Source object
855
- * @param path - Dot-separated path string (constrained to valid paths)
856
- * @returns Value at path or undefined
798
+ * @param data - Any input data (object, array, primitive)
799
+ * @returns Same type as input, but with all nulls replaced by undefined
857
800
  *
858
801
  * @example
859
- * extract({a: [{b: 1}]}, 'a.0.b') // 1
860
- */
861
- declare function extract<const T extends object, S$1 extends NestedKeyOf<T>>(obj: T, path: S$1): GetValue<T, SplitPath<S$1>> | undefined;
862
- /**
863
- * Get multiple nested values from an object using dot notation paths
864
- * @template T - Object type
865
- * @template S - Array of path strings
866
- * @template D - Default value type
867
- * @param obj - Source object
868
- * @param paths - Array of dot-separated path strings
869
- * @param defaultValue - Fallback value if any path not found
870
- * @returns Array of values at paths or default values
802
+ * ```ts
803
+ * // Basic object hydration
804
+ * hydrate({ name: null, age: 25 }) // { name: undefined, age: 25 }
871
805
  *
872
- * @example
873
- * extract({a: [{b: 1}, {b: 2}]}, ['a.0.b', 'a.1.b'], 0) // [1, 2]
874
- */
875
- declare function extract<const T extends object, const S$1 extends readonly string[], D>(obj: T, paths: S$1, defaultValue: D): { readonly [K in keyof S$1]: GetValue<T, SplitPath<S$1[K] & string>> | D };
876
- /**
877
- * Get multiple nested values from an object using dot notation paths
878
- * @template T - Object type
879
- * @template S - Array of path strings
880
- * @param obj - Source object
881
- * @param paths - Array of dot-separated path strings
882
- * @returns Array of values at paths or undefined
806
+ * // Nested object hydration
807
+ * hydrate({
808
+ * user: { email: null, profile: { avatar: null } },
809
+ * settings: { theme: 'dark' }
810
+ * })
811
+ * // { user: { email: undefined, profile: { avatar: undefined } }, settings: { theme: 'dark' } }
883
812
  *
884
- * @example
885
- * extract({a: [{b: 1}, {b: 2}]}, ['a.0.b', 'a.1.b']) // [1, 2]
886
- */
887
- declare function extract<const T extends object, const S$1 extends readonly string[]>(obj: T, paths: S$1): { readonly [K in keyof S$1]: GetValue<T, SplitPath<S$1[K] & string>> | undefined };
888
- /**
889
- * Get multiple nested values from an object using dot notation paths mapped to keys
890
- * @template T - Object type
891
- * @template S - Record mapping keys to path strings
892
- * @template D - Default value type
893
- * @param obj - Source object
894
- * @param paths - Record with keys as output keys and values as dot-separated path strings
895
- * @param defaultValue - Fallback value if any path not found
896
- * @returns Object with the same keys as paths, values at paths or default values
813
+ * // Array hydration
814
+ * hydrate([null, 'hello', null, 42]) // [undefined, 'hello', undefined, 42]
897
815
  *
898
- * @example
899
- * extract({a: [{b: 1}, {b: 2}]}, {first: 'a.0.b', second: 'a.1.b'}, 0) // {first: 1, second: 2}
900
- */
901
- declare function extract<const T extends object, const S$1 extends Record<string, string>, D>(obj: T, paths: S$1, defaultValue: D): { readonly [K in keyof S$1]: GetValue<T, SplitPath<S$1[K]>> | D };
902
- /**
903
- * Get multiple nested values from an object using dot notation paths mapped to keys
904
- * @template T - Object type
905
- * @template S - Record mapping keys to path strings
906
- * @param obj - Source object
907
- * @param paths - Record with keys as output keys and values as dot-separated path strings
908
- * @returns Object with the same keys as paths, values at paths or undefined
816
+ * // Mixed data structures
817
+ * hydrate({
818
+ * posts: [null, { title: 'Hello', content: null }],
819
+ * metadata: { published: null, tags: ['react', null] }
820
+ * })
821
+ * ```
909
822
  *
910
823
  * @example
911
- * extract({a: [{b: 1}, {b: 2}]}, {first: 'a.0.b', second: 'a.1.b'}) // {first: 1, second: 2}
824
+ * ```ts
825
+ * // API response normalization
826
+ * const apiResponse = await fetch('/api/user');
827
+ * const rawData = await apiResponse.json(); // May contain null values
828
+ * const normalizedData = hydrate(rawData); // Convert nulls to undefined
829
+ *
830
+ * // Database result processing
831
+ * const dbResult = query('SELECT * FROM users'); // Some fields may be NULL
832
+ * const cleanData = hydrate(dbResult); // Normalize for consistent handling
833
+ *
834
+ * // Form data sanitization
835
+ * const formData = getFormValues(); // May have null values from empty fields
836
+ * const sanitizedData = hydrate(formData); // Prepare for validation/state
837
+ * ```
912
838
  */
913
- declare function extract<const T extends object, const S$1 extends Record<string, string>>(obj: T, paths: S$1): { readonly [K in keyof S$1]: GetValue<T, SplitPath<S$1[K]>> | undefined };
839
+ declare function hydrate<T>(data: T): Hydrate<T>;
840
+ //#endregion
841
+ //#region src/functions/object.d.ts
914
842
  /**
915
843
  * Extend an object or function with additional properties while
916
844
  * preserving the original type information.
@@ -1404,4 +1332,4 @@ declare function normalizeText(str?: string | null, options?: {
1404
1332
  removeNonAlphanumeric?: boolean;
1405
1333
  }): string;
1406
1334
  //#endregion
1407
- export { AND, AllOrNone, BUFFER, ConcurrenceOptions, ConcurrenceResult, DeepMergeOptions, DeepPartial, DeepReadonly, DeepRequired, Diff, Falsy, IMPLIES, Intersection, Keys, KeysOfType, Maybe, Merge, Mutable, NAND, NOR, NOT, NestedKeyOf, Never, Nullable, Nullish, OR, OmitByType, OneOf, Optional, Prettify, Primitive, RequiredKeys, ScheduleOpts, SelectivePartial, SelectiveRequired, Substract, Task, TwoOf, Values, Without, XNOR, XNOR_Binary, XOR, XOR_Binary, convertToNormalCase, convertToSlug, debounce, deepmerge, escapeRegExp, extendProps, extract, hydrate, isArray, isBoolean, isFalsy, isFiniteNumber, isFunction, isNullish, isPlainObject, isPrimitive, isString, normalizeText, poll, printf, schedule, shield, sleep, throttle, withConcurrency };
1335
+ export { AND, AllOrNone, BUFFER, ConcurrenceOptions, ConcurrenceResult, DeepMergeOptions, DeepPartial, DeepReadonly, DeepRequired, Diff, ExtractOptions, Falsy, IMPLIES, Intersection, Keys, KeysOfType, Maybe, Merge, Mutable, NAND, NOR, NOT, NestedKeyOf, Never, Nullable, Nullish, OR, OmitByType, OneOf, Optional, Prettify, Primitive, RequiredKeys, ScheduleOpts, SelectivePartial, SelectiveRequired, Substract, Task, TwoOf, Values, Without, XNOR, XNOR_Binary, XOR, XOR_Binary, convertToNormalCase, convertToSlug, debounce, deepmerge, escapeRegExp, extendProps, extract, hydrate, isArray, isBoolean, isFalsy, isFiniteNumber, isFunction, isNullish, isPlainObject, isPrimitive, isString, normalizeText, poll, printf, schedule, shield, sleep, throttle, withConcurrency };
package/dist/index.d.ts CHANGED
@@ -94,54 +94,6 @@ type TMerged<T> = [T] extends [Array<any>] ? { [K in keyof T]: TMerged<T[K]> } :
94
94
  declare function deepmerge<T extends Record<string, any>, S$1 extends Record<string, any>[]>(target: T, ...sources: S$1): TMerged<T | S$1[number]>;
95
95
  declare function deepmerge<T extends Record<string, any>, S$1 extends Record<string, any>[]>(target: T, sources: S$1, options?: DeepMergeOptions): TMerged<T | S$1[number]>;
96
96
  //#endregion
97
- //#region src/functions/hydrate.d.ts
98
- type Hydrate<T> = T extends null ? undefined : T extends (infer U)[] ? Hydrate<U>[] : T extends object ? { [K in keyof T]: Hydrate<T[K]> } : T;
99
- /**
100
- * Converts all `null` values to `undefined` in the data structure recursively.
101
- *
102
- * @param data - Any input data (object, array, primitive)
103
- * @returns Same type as input, but with all nulls replaced by undefined
104
- *
105
- * @example
106
- * ```ts
107
- * // Basic object hydration
108
- * hydrate({ name: null, age: 25 }) // { name: undefined, age: 25 }
109
- *
110
- * // Nested object hydration
111
- * hydrate({
112
- * user: { email: null, profile: { avatar: null } },
113
- * settings: { theme: 'dark' }
114
- * })
115
- * // { user: { email: undefined, profile: { avatar: undefined } }, settings: { theme: 'dark' } }
116
- *
117
- * // Array hydration
118
- * hydrate([null, 'hello', null, 42]) // [undefined, 'hello', undefined, 42]
119
- *
120
- * // Mixed data structures
121
- * hydrate({
122
- * posts: [null, { title: 'Hello', content: null }],
123
- * metadata: { published: null, tags: ['react', null] }
124
- * })
125
- * ```
126
- *
127
- * @example
128
- * ```ts
129
- * // API response normalization
130
- * const apiResponse = await fetch('/api/user');
131
- * const rawData = await apiResponse.json(); // May contain null values
132
- * const normalizedData = hydrate(rawData); // Convert nulls to undefined
133
- *
134
- * // Database result processing
135
- * const dbResult = query('SELECT * FROM users'); // Some fields may be NULL
136
- * const cleanData = hydrate(dbResult); // Normalize for consistent handling
137
- *
138
- * // Form data sanitization
139
- * const formData = getFormValues(); // May have null values from empty fields
140
- * const sanitizedData = hydrate(formData); // Prepare for validation/state
141
- * ```
142
- */
143
- declare function hydrate<T>(data: T): Hydrate<T>;
144
- //#endregion
145
97
  //#region src/types/utilities.d.ts
146
98
  /**
147
99
  * Extracts the keys of an object type as a union type.
@@ -757,19 +709,22 @@ declare const isBoolean: (val: unknown) => val is boolean;
757
709
  */
758
710
  declare const isString: (val: unknown) => val is string;
759
711
  /**
760
- * Type guard that checks whether a value is a finite number.
712
+ * Checks whether a value represents a finite number.
761
713
  *
762
714
  * This excludes `NaN`, `Infinity`, and `-Infinity`.
715
+ * Accepts numbers or strings that can be parsed to finite numbers.
763
716
  *
764
717
  * @param val - The value to check
765
- * @returns `true` if the value is a finite number
718
+ * @returns `true` if the value represents a finite number
766
719
  *
767
720
  * @example
768
721
  * isFiniteNumber(42); // true
722
+ * isFiniteNumber('42'); // true
769
723
  * isFiniteNumber(NaN); // false
770
724
  * isFiniteNumber(Infinity); // false
725
+ * isFiniteNumber('abc'); // false
771
726
  */
772
- declare const isFiniteNumber: (val: unknown) => val is number;
727
+ declare const isFiniteNumber: (val: unknown) => boolean;
773
728
  /**
774
729
  * Type guard that checks if a value is an array.
775
730
  *
@@ -819,98 +774,71 @@ declare const isPrimitive: (val: unknown) => val is Primitive;
819
774
  */
820
775
  declare function isPlainObject(value: unknown): value is Record<string, any>;
821
776
  //#endregion
822
- //#region src/functions/object.d.ts
823
- /**
824
- * Type representing a path split into segments
825
- * @template S - The original path string type
826
- */
827
- type SplitPath<S$1 extends string> = S$1 extends `${infer First}.${infer Rest}` ? [First, ...SplitPath<Rest>] : [S$1];
828
- /**
829
- * Recursive type to resolve nested object types based on path
830
- * @template T - Current object type
831
- * @template K - Array of path segments
832
- */
777
+ //#region src/functions/extract.d.ts
778
+ type SplitPath<P$1 extends string> = P$1 extends `${infer First}.${infer Rest}` ? [First, ...SplitPath<Rest>] : [P$1];
833
779
  type GetValue<T, K$1 extends Array<string | number>> = K$1 extends [infer First, ...infer Rest] ? First extends keyof T ? GetValue<T[First], Rest extends Array<string | number> ? Rest : []> : First extends `${number}` ? T extends any[] ? GetValue<T[number], Rest extends Array<string | number> ? Rest : []> : undefined : undefined : T;
780
+ interface ExtractOptions<D = never> {
781
+ defaultValue?: D;
782
+ }
783
+ type ExtractSinglePath<T, P$1 extends string, D> = Exclude<GetValue<T, SplitPath<P$1>>, undefined> | D;
784
+ type ExtractSingle<T, P$1 extends string> = GetValue<T, SplitPath<P$1>> | undefined;
785
+ type IsString<T> = T extends string ? (string extends T ? true : false) : false;
786
+ declare function extract<const T extends object, P$1 extends string, D>(obj: T, path: P$1, opts?: ExtractOptions<D>): IsString<P$1> extends true ? P$1 extends NestedKeyOf<T> ? ExtractSinglePath<T, P$1, D> : unknown : never;
787
+ declare function extract<const T extends object, P$1 extends string>(obj: T, path: P$1): IsString<P$1> extends true ? P$1 extends NestedKeyOf<T> ? ExtractSingle<T, P$1> : unknown : never;
788
+ declare function extract<T, D>(obj: T, paths: readonly string[], opts?: ExtractOptions<D>): unknown[];
789
+ declare function extract<T>(obj: T, paths: readonly string[]): unknown[];
790
+ declare function extract<T, D>(obj: T, paths: Record<string, string>, opts?: ExtractOptions<D>): { readonly [K in keyof typeof paths]: unknown };
791
+ declare function extract<T>(obj: T, paths: Record<string, string>): { readonly [K in keyof typeof paths]: unknown };
792
+ //#endregion
793
+ //#region src/functions/hydrate.d.ts
794
+ type Hydrate<T> = T extends null ? undefined : T extends (infer U)[] ? Hydrate<U>[] : T extends object ? { [K in keyof T]: Hydrate<T[K]> } : T;
834
795
  /**
835
- * Get a nested value from an object using dot notation path
836
- * @template T - Object type
837
- * @template S - Valid path string type constrained by object structure
838
- * @template D - Default value type
839
- * @param obj - Source object
840
- * @param path - Dot-separated path string (constrained to valid paths)
841
- * @param defaultValue - Fallback value if path not found
842
- * @returns Value at path or default value
796
+ * Converts all `null` values to `undefined` in the data structure recursively.
843
797
  *
844
- * @example
845
- * // use as const for better type safety for arrays
846
- * extract({a: [{b: 1}]} as const, 'a.0.b', 2) // 1
847
- * extract({a: {b: 1}}, 'a.b', 2) // 1
848
- */
849
- declare function extract<const T extends object, S$1 extends NestedKeyOf<T>, D>(obj: T, path: S$1, defaultValue: D): Exclude<GetValue<T, SplitPath<S$1>>, undefined> | D;
850
- /**
851
- * Get a nested value from an object using dot notation path
852
- * @template T - Object type
853
- * @template S - Valid path string type constrained by object structure
854
- * @param obj - Source object
855
- * @param path - Dot-separated path string (constrained to valid paths)
856
- * @returns Value at path or undefined
798
+ * @param data - Any input data (object, array, primitive)
799
+ * @returns Same type as input, but with all nulls replaced by undefined
857
800
  *
858
801
  * @example
859
- * extract({a: [{b: 1}]}, 'a.0.b') // 1
860
- */
861
- declare function extract<const T extends object, S$1 extends NestedKeyOf<T>>(obj: T, path: S$1): GetValue<T, SplitPath<S$1>> | undefined;
862
- /**
863
- * Get multiple nested values from an object using dot notation paths
864
- * @template T - Object type
865
- * @template S - Array of path strings
866
- * @template D - Default value type
867
- * @param obj - Source object
868
- * @param paths - Array of dot-separated path strings
869
- * @param defaultValue - Fallback value if any path not found
870
- * @returns Array of values at paths or default values
802
+ * ```ts
803
+ * // Basic object hydration
804
+ * hydrate({ name: null, age: 25 }) // { name: undefined, age: 25 }
871
805
  *
872
- * @example
873
- * extract({a: [{b: 1}, {b: 2}]}, ['a.0.b', 'a.1.b'], 0) // [1, 2]
874
- */
875
- declare function extract<const T extends object, const S$1 extends readonly string[], D>(obj: T, paths: S$1, defaultValue: D): { readonly [K in keyof S$1]: GetValue<T, SplitPath<S$1[K] & string>> | D };
876
- /**
877
- * Get multiple nested values from an object using dot notation paths
878
- * @template T - Object type
879
- * @template S - Array of path strings
880
- * @param obj - Source object
881
- * @param paths - Array of dot-separated path strings
882
- * @returns Array of values at paths or undefined
806
+ * // Nested object hydration
807
+ * hydrate({
808
+ * user: { email: null, profile: { avatar: null } },
809
+ * settings: { theme: 'dark' }
810
+ * })
811
+ * // { user: { email: undefined, profile: { avatar: undefined } }, settings: { theme: 'dark' } }
883
812
  *
884
- * @example
885
- * extract({a: [{b: 1}, {b: 2}]}, ['a.0.b', 'a.1.b']) // [1, 2]
886
- */
887
- declare function extract<const T extends object, const S$1 extends readonly string[]>(obj: T, paths: S$1): { readonly [K in keyof S$1]: GetValue<T, SplitPath<S$1[K] & string>> | undefined };
888
- /**
889
- * Get multiple nested values from an object using dot notation paths mapped to keys
890
- * @template T - Object type
891
- * @template S - Record mapping keys to path strings
892
- * @template D - Default value type
893
- * @param obj - Source object
894
- * @param paths - Record with keys as output keys and values as dot-separated path strings
895
- * @param defaultValue - Fallback value if any path not found
896
- * @returns Object with the same keys as paths, values at paths or default values
813
+ * // Array hydration
814
+ * hydrate([null, 'hello', null, 42]) // [undefined, 'hello', undefined, 42]
897
815
  *
898
- * @example
899
- * extract({a: [{b: 1}, {b: 2}]}, {first: 'a.0.b', second: 'a.1.b'}, 0) // {first: 1, second: 2}
900
- */
901
- declare function extract<const T extends object, const S$1 extends Record<string, string>, D>(obj: T, paths: S$1, defaultValue: D): { readonly [K in keyof S$1]: GetValue<T, SplitPath<S$1[K]>> | D };
902
- /**
903
- * Get multiple nested values from an object using dot notation paths mapped to keys
904
- * @template T - Object type
905
- * @template S - Record mapping keys to path strings
906
- * @param obj - Source object
907
- * @param paths - Record with keys as output keys and values as dot-separated path strings
908
- * @returns Object with the same keys as paths, values at paths or undefined
816
+ * // Mixed data structures
817
+ * hydrate({
818
+ * posts: [null, { title: 'Hello', content: null }],
819
+ * metadata: { published: null, tags: ['react', null] }
820
+ * })
821
+ * ```
909
822
  *
910
823
  * @example
911
- * extract({a: [{b: 1}, {b: 2}]}, {first: 'a.0.b', second: 'a.1.b'}) // {first: 1, second: 2}
824
+ * ```ts
825
+ * // API response normalization
826
+ * const apiResponse = await fetch('/api/user');
827
+ * const rawData = await apiResponse.json(); // May contain null values
828
+ * const normalizedData = hydrate(rawData); // Convert nulls to undefined
829
+ *
830
+ * // Database result processing
831
+ * const dbResult = query('SELECT * FROM users'); // Some fields may be NULL
832
+ * const cleanData = hydrate(dbResult); // Normalize for consistent handling
833
+ *
834
+ * // Form data sanitization
835
+ * const formData = getFormValues(); // May have null values from empty fields
836
+ * const sanitizedData = hydrate(formData); // Prepare for validation/state
837
+ * ```
912
838
  */
913
- declare function extract<const T extends object, const S$1 extends Record<string, string>>(obj: T, paths: S$1): { readonly [K in keyof S$1]: GetValue<T, SplitPath<S$1[K]>> | undefined };
839
+ declare function hydrate<T>(data: T): Hydrate<T>;
840
+ //#endregion
841
+ //#region src/functions/object.d.ts
914
842
  /**
915
843
  * Extend an object or function with additional properties while
916
844
  * preserving the original type information.
@@ -1404,4 +1332,4 @@ declare function normalizeText(str?: string | null, options?: {
1404
1332
  removeNonAlphanumeric?: boolean;
1405
1333
  }): string;
1406
1334
  //#endregion
1407
- export { AND, AllOrNone, BUFFER, ConcurrenceOptions, ConcurrenceResult, DeepMergeOptions, DeepPartial, DeepReadonly, DeepRequired, Diff, Falsy, IMPLIES, Intersection, Keys, KeysOfType, Maybe, Merge, Mutable, NAND, NOR, NOT, NestedKeyOf, Never, Nullable, Nullish, OR, OmitByType, OneOf, Optional, Prettify, Primitive, RequiredKeys, ScheduleOpts, SelectivePartial, SelectiveRequired, Substract, Task, TwoOf, Values, Without, XNOR, XNOR_Binary, XOR, XOR_Binary, convertToNormalCase, convertToSlug, debounce, deepmerge, escapeRegExp, extendProps, extract, hydrate, isArray, isBoolean, isFalsy, isFiniteNumber, isFunction, isNullish, isPlainObject, isPrimitive, isString, normalizeText, poll, printf, schedule, shield, sleep, throttle, withConcurrency };
1335
+ export { AND, AllOrNone, BUFFER, ConcurrenceOptions, ConcurrenceResult, DeepMergeOptions, DeepPartial, DeepReadonly, DeepRequired, Diff, ExtractOptions, Falsy, IMPLIES, Intersection, Keys, KeysOfType, Maybe, Merge, Mutable, NAND, NOR, NOT, NestedKeyOf, Never, Nullable, Nullish, OR, OmitByType, OneOf, Optional, Prettify, Primitive, RequiredKeys, ScheduleOpts, SelectivePartial, SelectiveRequired, Substract, Task, TwoOf, Values, Without, XNOR, XNOR_Binary, XOR, XOR_Binary, convertToNormalCase, convertToSlug, debounce, deepmerge, escapeRegExp, extendProps, extract, hydrate, isArray, isBoolean, isFalsy, isFiniteNumber, isFunction, isNullish, isPlainObject, isPrimitive, isString, normalizeText, poll, printf, schedule, shield, sleep, throttle, withConcurrency };
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=>typeof e==`number`&&Number.isFinite(e),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){return d(e)}function d(e){if(e!==null){if(typeof e!=`object`||!e)return e;if(Array.isArray(e))return e.map(d);if(c(e)){let t={};for(let n in e)t[n]=d(e[n]);return t}return e}}function f(e,t,n){if(Array.isArray(t))return t.map(t=>f(e,t,n));if(typeof t==`object`&&t&&!Array.isArray(t)){let r={};for(let i in t)t.hasOwnProperty(i)&&(r[i]=f(e,t[i],n));return r}if(typeof t!=`string`||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 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}async function C(e,{interval:t=5e3,timeout:n=300*1e3,jitter:r=!0,signal:i}={}){let a=Date.now(),o=i?.aborted??!1,s=()=>{o=!0};i?.addEventListener(`abort`,s,{once:!0});try{for(let s=0;;s++){if(o)throw Error(`Polling aborted`);let s=await e();if(s)return s;if(Date.now()-a>=n)throw Error(`Polling timed out`,{cause:`Polling timed out after ${n}ms`});await _(r?t+(Math.random()-.5)*t*.2:t,i)}}catch(e){throw e}finally{i?.removeEventListener(`abort`,s)}}async function w(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 T(e,t={}){let{retry:n=0,delay:r=0}=t,i=Date.now(),a=async t=>{try{await e();let t=Date.now()-i;console.log(`⚡[schedule.ts] Completed in ${t}ms`)}catch(e){if(console.log(`⚡[schedule.ts] err:`,e),t>0)console.log(`⚡[schedule.ts] Retrying in ${r}ms...`),setTimeout(()=>a(t-1),r);else{let e=Date.now()-i;console.log(`⚡[schedule.ts] Failed after ${e}ms`)}}};setTimeout(()=>a(n),0)}function E(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,f as extract,u 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,C as poll,b as printf,T as schedule,E as shield,_ as sleep,y as throttle,w as withConcurrency};
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){let r=n?.defaultValue;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 r;let i=(()=>t===``?[]:t.split(`.`).filter(e=>e!==``))(),a=e;for(let e of i){if(a==null)return r;let t=typeof e==`string`&&Array.isArray(a)&&/^\d+$/.test(e)?Number.parseInt(e,10):e;a=a[t]}return a===void 0?r:a}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}async function C(e,{interval:t=5e3,timeout:n=300*1e3,jitter:r=!0,signal:i}={}){let a=Date.now(),o=i?.aborted??!1,s=()=>{o=!0};i?.addEventListener(`abort`,s,{once:!0});try{for(let s=0;;s++){if(o)throw Error(`Polling aborted`);let s=await e();if(s)return s;if(Date.now()-a>=n)throw Error(`Polling timed out`,{cause:`Polling timed out after ${n}ms`});await _(r?t+(Math.random()-.5)*t*.2:t,i)}}catch(e){throw e}finally{i?.removeEventListener(`abort`,s)}}async function w(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 T(e,t={}){let{retry:n=0,delay:r=0}=t,i=Date.now(),a=async t=>{try{await e();let t=Date.now()-i;console.log(`⚡[schedule.ts] Completed in ${t}ms`)}catch(e){if(console.log(`⚡[schedule.ts] err:`,e),t>0)console.log(`⚡[schedule.ts] Retrying in ${r}ms...`),setTimeout(()=>a(t-1),r);else{let e=Date.now()-i;console.log(`⚡[schedule.ts] Failed after ${e}ms`)}}};setTimeout(()=>a(n),0)}function E(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,C as poll,b as printf,T as schedule,E as shield,_ as sleep,y as throttle,w as withConcurrency};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ts-utilities/core",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "author": "Sohan Emon <sohanemon@outlook.com>",
5
5
  "description": "Core utilities for JavaScript/TypeScript projects",
6
6
  "type": "module",