@take-out/helpers 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/package.json +2 -1
  2. package/types/array/getRandomItem.d.ts.map +2 -2
  3. package/types/array/takeLast.d.ts.map +2 -2
  4. package/types/array/uniqBy.d.ts.map +2 -2
  5. package/types/assert.d.ts.map +2 -2
  6. package/types/async/abortable.d.ts.map +2 -2
  7. package/types/async/asyncContext.d.ts.map +4 -4
  8. package/types/async/asyncContext.native.d.ts.map +2 -2
  9. package/types/async/idle.d.ts.map +2 -2
  10. package/types/async/interval.d.ts.map +2 -2
  11. package/types/async/isAborted.d.ts.map +2 -2
  12. package/types/async/sleep.d.ts.map +2 -2
  13. package/types/async/useAsync.d.ts.map +2 -2
  14. package/types/async/useAsyncEffect.d.ts.map +4 -4
  15. package/types/async/useLazyMount.d.ts +1 -1
  16. package/types/async/useLazyMount.d.ts.map +3 -3
  17. package/types/async/useLazyValue.d.ts +1 -1
  18. package/types/async/useLazyValue.d.ts.map +3 -3
  19. package/types/browser/clearIndexedDB.d.ts.map +2 -2
  20. package/types/browser/isActiveElementFormField.d.ts.map +2 -2
  21. package/types/browser/openPopup.d.ts.map +2 -2
  22. package/types/client-only.d.ts.map +2 -2
  23. package/types/clipboard/clipboard.d.ts.map +2 -2
  24. package/types/clipboard/clipboard.native.d.ts.map +2 -2
  25. package/types/color/extractOpacityFromColor.d.ts.map +2 -2
  26. package/types/color/generateColors.d.ts.map +2 -2
  27. package/types/color/lum.d.ts.map +2 -2
  28. package/types/color/toHex.d.ts.map +2 -2
  29. package/types/constants.d.ts +1 -1
  30. package/types/constants.d.ts.map +5 -11
  31. package/types/debug/debugLog.d.ts.map +2 -2
  32. package/types/debug/debugUseState.d.ts +1 -1
  33. package/types/debug/debugUseState.d.ts.map +3 -3
  34. package/types/emitter.d.ts.map +4 -4
  35. package/types/ensure/ensure.d.ts.map +2 -2
  36. package/types/ensure/ensureOne.d.ts.map +2 -2
  37. package/types/error/errors.d.ts +16 -0
  38. package/types/error/errors.d.ts.map +4 -4
  39. package/types/function/emptyFn.d.ts.map +2 -2
  40. package/types/function/identityFn.d.ts.map +2 -2
  41. package/types/function/throttle.d.ts.map +2 -2
  42. package/types/global/globalEffect.d.ts.map +2 -2
  43. package/types/global/globalValue.d.ts.map +2 -2
  44. package/types/index.d.ts +1 -0
  45. package/types/index.d.ts.map +4 -4
  46. package/types/number/formatNumber.d.ts.map +2 -2
  47. package/types/object/decorateObject.d.ts.map +2 -2
  48. package/types/object/isEqualDeep.d.ts.map +4 -7
  49. package/types/object/isEqualIdentity.d.ts.map +2 -2
  50. package/types/object/isEqualJSON.d.ts.map +2 -2
  51. package/types/object/isEqualNever.d.ts.map +2 -2
  52. package/types/object/mapObject.d.ts.map +2 -2
  53. package/types/object/object.d.ts.map +2 -2
  54. package/types/object/objectUniqueKey.d.ts.map +2 -2
  55. package/types/react/createGlobalContext.d.ts.map +2 -2
  56. package/types/react/getCurrentComponentStack.d.ts.map +3 -3
  57. package/types/server/ensureEnv.d.ts.map +2 -2
  58. package/types/server/getHeaders.d.ts.map +2 -2
  59. package/types/server/isServerRuntime.d.ts +3 -0
  60. package/types/server/isServerRuntime.d.ts.map +11 -0
  61. package/types/server/prettyPrintRequest.d.ts.map +2 -2
  62. package/types/server/prettyPrintResponse.d.ts.map +2 -2
  63. package/types/server/streamToString.d.ts.map +2 -2
  64. package/types/server-only.d.ts.map +2 -2
  65. package/types/storage/createStorage.d.ts +2 -2
  66. package/types/storage/createStorage.d.ts.map +4 -4
  67. package/types/storage/driver.d.ts.map +2 -2
  68. package/types/storage/storage.test.d.ts.map +2 -2
  69. package/types/storage/types.d.ts.map +2 -2
  70. package/types/string/dedent.d.ts.map +2 -2
  71. package/types/string/ellipsis.d.ts.map +2 -2
  72. package/types/string/hash.d.ts.map +2 -2
  73. package/types/string/insertAtIndex.d.ts.map +2 -2
  74. package/types/string/nbspLastWord.d.ts.map +2 -2
  75. package/types/string/pickLast.d.ts.map +2 -2
  76. package/types/string/pluralize.d.ts.map +2 -2
  77. package/types/string/pluralize.native.d.ts.map +4 -6
  78. package/types/string/randomId.d.ts.map +2 -2
  79. package/types/string/slugify.d.ts.map +2 -2
  80. package/types/string/truncateList.d.ts.map +2 -2
  81. package/types/time/formatDate.d.ts.map +2 -2
  82. package/types/time/formatDateRelative.d.ts.map +2 -2
  83. package/types/time/formatDistanceToNow.d.ts.map +2 -2
  84. package/types/time/time.d.ts.map +4 -6
  85. package/types/time/useTimer.d.ts.map +2 -2
  86. package/types/types/NullToOptional.d.ts.map +2 -2
  87. package/types/types/object.d.ts.map +2 -2
  88. package/types/types/react.d.ts.map +2 -2
  89. package/types/types/timer.d.ts.map +2 -2
  90. package/types/types/tuple.d.ts.map +2 -2
  91. package/types/url/urlSanitize.d.ts.map +2 -2
  92. package/types/url/urlValidate.d.ts.map +2 -2
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/string/randomId.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "export const randomId = (): string => Math.random().toString(36).slice(2)\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/string/slugify.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "export const slugify = (input: string): string =>\n input\n .toLowerCase()\n .replace(/[\\s_]+/g, '-') // convert spaces and underscores to dashes\n .replace(/[^a-z0-9-]/g, '') // remove all non-alphanumeric except dashes\n .replace(/-+/g, '-') // replace multiple dashes with single dash\n .replace(/^-|-$/g, '') // remove leading/trailing dashes\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/string/truncateList.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "/**\n * Truncates a list of strings to show only the first N items,\n * with a \"+X\" indicator for any remaining items.\n *\n * @param items - Array of strings to truncate\n * @param maxItems - Maximum number of items to show before truncating\n * @param separator - String to use between items (default: ', ')\n * @returns Formatted string with truncation indicator if needed\n *\n * @example\n * truncateList(['jon', 'sal', 'bob', 'ted'], 3) // \"jon, sal, bob +1\"\n * truncateList(['alice', 'bob'], 3) // \"alice, bob\"\n * truncateList(['a', 'b', 'c', 'd', 'e'], 2) // \"a, b +3\"\n */\nexport const truncateList = (\n items: string[],\n maxItems: number,\n separator: string = ', '\n): string => {\n if (items.length <= maxItems) {\n return items.join(separator)\n }\n\n const visibleItems = items.slice(0, maxItems)\n const remainingCount = items.length - maxItems\n\n return `${visibleItems.join(separator)} +${remainingCount}`\n}\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/time/formatDate.tsx"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "const currentYear = new Date().getFullYear()\n\nexport function formatDate(\n date: Date,\n options?: { daySuffix?: boolean }\n): [string, string] | [string, string, string] {\n const months = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ]\n\n const day = date.getDate()\n const month = months[date.getMonth()]\n const year = date.getFullYear()\n\n const dayString = options?.daySuffix ? getOrdinalSuffix(day) : `${day}`\n\n if (year === currentYear) {\n return [`${month}`, dayString]\n }\n\n return [`${month}`, dayString, `${year}`]\n}\n\nconst getOrdinalSuffix = (n: number) => {\n if (n >= 11 && n <= 13) return 'th'\n switch (n % 10) {\n case 1:\n return 'st'\n case 2:\n return 'nd'\n case 3:\n return 'rd'\n default:\n return 'th'\n }\n}\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/time/formatDateRelative.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "/**\n * Formats a date relative to the current time:\n * - If within the last month: just show time (e.g., \"5:50pm\")\n * - If this year but older than a month: show \"Jun 2, 5:50pm\"\n * - If before this year: show \"Jun 2, 2025, 5:50pm\"\n */\n\nfunction lowerCaseTime(formatted: string): string {\n return formatted.replace(/\\s?(AM|PM)/g, (_, ampm) => ampm.toLowerCase())\n}\n\nexport function formatDateRelative(date: Date | string | number): string {\n const messageDate = new Date(date)\n const now = new Date()\n\n // if it's today\n const isToday =\n messageDate.getFullYear() === now.getFullYear() &&\n messageDate.getMonth() === now.getMonth() &&\n messageDate.getDate() === now.getDate()\n\n // check if it's within the last month\n const oneMonthAgo = new Date(now)\n oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1)\n const isWithinLastMonth = messageDate >= oneMonthAgo\n\n // if it's this year\n const isThisYear = messageDate.getFullYear() === now.getFullYear()\n\n if (isToday) {\n // just time for today\n return lowerCaseTime(\n new Intl.DateTimeFormat('en', {\n hour: 'numeric',\n minute: 'numeric',\n }).format(messageDate)\n )\n }\n\n if (isWithinLastMonth) {\n // just time for dates within the last month\n return lowerCaseTime(\n new Intl.DateTimeFormat('en', {\n hour: 'numeric',\n minute: 'numeric',\n }).format(messageDate)\n )\n }\n\n if (isThisYear) {\n // Show \"Jun 2, 5:50pm\" for this year\n return lowerCaseTime(\n new Intl.DateTimeFormat('en', {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n }).format(messageDate)\n )\n }\n\n // Show \"Jun 2, 2025, 5:50pm\" for previous years\n return lowerCaseTime(\n new Intl.DateTimeFormat('en', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n }).format(messageDate)\n )\n}\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/time/formatDistanceToNow.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "export function formatDistanceToNow(timestamp: number): string {\n const now = Date.now()\n const diff = now - timestamp\n\n const minutes = Math.floor(diff / 60000)\n const hours = Math.floor(diff / 3600000)\n const days = Math.floor(diff / 86400000)\n\n if (minutes < 1) return 'just now'\n if (minutes < 60) return `${minutes}m`\n if (hours < 24) return `${hours}h`\n if (days < 7) return `${days}d`\n if (days < 30) return `${Math.floor(days / 7)}w`\n if (days < 365) return `${Math.floor(days / 30)}mo`\n\n return `${Math.floor(days / 365)}y`\n}\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -1,13 +1,11 @@
1
1
  {
2
- "mappings": "UAAU,WAAW;EAClB;CACD,UAAU;CACV,UAAU;CACV,QAAQ;CACR,OAAO;CACP,QAAQ;;UAGA,eAAe;EACtB;CACD,UAAU;CACV,QAAQ;CACR,OAAO;CACP,QAAQ;;UAGA,eAAe;EACtB;CACD,QAAQ;CACR,OAAO;CACP,QAAQ;;AAqBV,OAAO,cAAMA,MAAM;CACjB,IAAI;CACJ,QAAQ;CACR,QAAQ",
3
- "names": [
4
- "time: {\n ms: MsFunction\n second: SecondFunction\n minute: MinuteFunction\n}"
5
- ],
2
+ "mappings": "UAAU,WAAW;EAClB;CACD,UAAU;CACV,UAAU;CACV,QAAQ;CACR,OAAO;CACP,QAAQ;;UAGA,eAAe;EACtB;CACD,UAAU;CACV,QAAQ;CACR,OAAO;CACP,QAAQ;;UAGA,eAAe;EACtB;CACD,QAAQ;CACR,OAAO;CACP,QAAQ;;AAqBV,OAAO,cAAM,MAAM;CACjB,IAAI;CACJ,QAAQ;CACR,QAAQ",
3
+ "names": [],
6
4
  "sources": [
7
5
  "src/time/time.ts"
8
6
  ],
7
+ "version": 3,
9
8
  "sourcesContent": [
10
9
  "interface MsFunction {\n (n: number): number\n seconds: (n: number) => number\n minutes: (n: number) => number\n hours: (n: number) => number\n days: (n: number) => number\n weeks: (n: number) => number\n}\n\ninterface SecondFunction {\n (n: number): number\n minutes: (n: number) => number\n hours: (n: number) => number\n days: (n: number) => number\n weeks: (n: number) => number\n}\n\ninterface MinuteFunction {\n (n: number): number\n hours: (n: number) => number\n days: (n: number) => number\n weeks: (n: number) => number\n}\n\nconst ms = ((n: number) => n) as MsFunction\nms.seconds = (n: number) => n * 1000\nms.minutes = (n: number) => ms.seconds(n * 60)\nms.hours = (n: number) => ms.minutes(n * 60)\nms.days = (n: number) => ms.hours(n * 24)\nms.weeks = (n: number) => ms.days(n * 7)\n\nconst second = ((n: number) => n) as SecondFunction\nsecond.minutes = (n: number) => n * 60\nsecond.hours = (n: number) => second.minutes(n * 60)\nsecond.days = (n: number) => second.hours(n * 24)\nsecond.weeks = (n: number) => second.days(n * 7)\n\nconst minute = ((n: number) => n * 60) as MinuteFunction\nminute.hours = (n: number) => minute(n * 60)\nminute.days = (n: number) => minute.hours(n * 24)\nminute.weeks = (n: number) => minute.days(n * 7)\n\nexport const time: {\n ms: MsFunction\n second: SecondFunction\n minute: MinuteFunction\n} = {\n ms,\n second,\n minute,\n}\n"
11
- ],
12
- "version": 3
10
+ ]
13
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/time/useTimer.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "import { useState, useEffect, useRef, useMemo, useCallback } from 'react'\n\ntype UseTimerReturn = {\n count: number\n start: (time: number, start: boolean) => void\n pause: () => void\n resume: () => void\n clear: () => void\n}\n\nexport const useTimer = (): UseTimerReturn => {\n const [timerCount, setTimer] = useState<number>(30)\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n const clearTimer = useCallback(() => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current)\n intervalRef.current = null\n }\n }, [])\n\n const resetTimer = useCallback(\n (time: number, start: boolean) => {\n setTimer(time)\n clearTimer()\n if (start) {\n intervalRef.current = setInterval(() => {\n setTimer((lastTimerCount) => {\n if (lastTimerCount <= 1) {\n clearInterval(intervalRef.current!)\n intervalRef.current = null\n return 0\n }\n return lastTimerCount - 1\n })\n }, 1000)\n }\n },\n [clearTimer]\n )\n\n const pauseTimer = useCallback(() => {\n clearTimer()\n }, [clearTimer])\n\n const resumeTimer = useCallback(() => {\n if (!intervalRef.current) {\n intervalRef.current = setInterval(() => {\n setTimer((lastTimerCount) => {\n if (lastTimerCount <= 1) {\n clearInterval(intervalRef.current!)\n intervalRef.current = null\n return 0\n }\n return lastTimerCount - 1\n })\n }, 1000)\n }\n }, [])\n\n useEffect(() => {\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current)\n intervalRef.current = null\n }\n }\n }, [])\n\n return useMemo(\n () => ({\n count: timerCount,\n start: resetTimer,\n pause: pauseTimer,\n resume: resumeTimer,\n clear: clearTimer,\n }),\n [timerCount, clearTimer, pauseTimer, resetTimer, resumeTimer]\n )\n}\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/types/NullToOptional.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "export type NullToOptional<T> = {\n [K in keyof T as null extends T[K] ? K : never]?: Exclude<T[K], null> | undefined | null\n} & {\n [K in keyof T as null extends T[K] ? never : K]: T[K]\n}\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/types/object.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "// note - TS doesn't support higher kinded types, so this doesn't work well\n\n// --- utils ---\n\nexport type Mutable<T> = {\n -readonly [K in keyof T]: T[K] // the ‘-readonly’ mapped-type modifier\n}\n\nexport type EntriesType =\n | [PropertyKey, unknown][]\n | ReadonlyArray<readonly [PropertyKey, unknown]>\n\ntype DeepWritable<OBJ_T> = { -readonly [P in keyof OBJ_T]: DeepWritable<OBJ_T[P]> }\ntype UnionToIntersection<UNION_T> = // From https://stackoverflow.com/a/50375286\n (UNION_T extends any ? (k: UNION_T) => void : never) extends (k: infer I) => void\n ? I\n : never\n\ntype UnionObjectFromArrayOfPairs<ARR_T extends EntriesType> =\n DeepWritable<ARR_T> extends (infer R)[]\n ? R extends [infer key, infer val]\n ? { [prop in key & PropertyKey]: val }\n : never\n : never\n\ntype MergeIntersectingObjects<ObjT> = { [key in keyof ObjT]: ObjT[key] }\n\nexport type EntriesToObject<ARR_T extends EntriesType> = MergeIntersectingObjects<\n UnionToIntersection<UnionObjectFromArrayOfPairs<ARR_T>>\n>\n\nexport type ObjectType = Record<PropertyKey, unknown>\n\ntype PickByValue<OBJ_T, VALUE_T> = // From https://stackoverflow.com/a/55153000\n Pick<OBJ_T, { [K in keyof OBJ_T]: OBJ_T[K] extends VALUE_T ? K : never }[keyof OBJ_T]>\n\nexport type ObjectEntries<OBJ_T> = // From https://stackoverflow.com/a/60142095\n { [K in keyof OBJ_T]: [keyof PickByValue<OBJ_T, OBJ_T[K]>, OBJ_T[K]] }[keyof OBJ_T][]\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/types/react.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "export type RefProp<T> = React.RefObject<T> | React.RefCallback<T>\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/types/timer.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "export type Timer = ReturnType<typeof setTimeout>\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/types/tuple.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "export type TupleToUnion<T extends any[]> = T[number]\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/url/urlSanitize.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\nconst protocols = new Set(['http:', 'https:', 'mailto:', 'tel:', 'sms:'])\n\nexport function urlSanitize(url: string): string {\n try {\n const parsedUrl = new URL(url)\n if (!protocols.has(parsedUrl.protocol)) {\n return 'about:blank'\n }\n } catch {\n return url\n }\n return url\n}\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }
@@ -4,8 +4,8 @@
4
4
  "sources": [
5
5
  "src/url/urlValidate.ts"
6
6
  ],
7
+ "version": 3,
7
8
  "sourcesContent": [
8
9
  "// Source: https://stackoverflow.com/a/8234912/2013580\n\nconst urlRegExp = new RegExp(\n /((([A-Za-z]{3,9}:(?:\\/\\/)?)(?:[-;:&=+$,\\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\\w]+@)[A-Za-z0-9.-]+)((?:\\/[+~%/.\\w-_]*)?\\??(?:[-+=&;%@.\\w_]*)#?(?:[\\w]*))?)/\n)\n\nexport function urlValidate(url: string): boolean {\n // TODO Fix UI for link insertion; it should never default to an invalid URL such as https://.\n // Maybe show a dialog where they user can type the URL before inserting it.\n return url === 'https://' || urlRegExp.test(url)\n}\n"
9
- ],
10
- "version": 3
10
+ ]
11
11
  }