diff --git a/404.html b/404.html new file mode 100644 index 00000000..31a82c22 --- /dev/null +++ b/404.html @@ -0,0 +1,80 @@ +
Discover which browsers and versions Radashi supports.
Browser support is a crucial factor to consider when choosing a utility library +like Radashi. It determines which browsers and versions your application will be compatible with, +potentially affecting your user base and the features you can utilize.
+While Radashi aims to strike a balance between modern functionality and broad compatibility, it’s +important to note that you may need to compile your application bundle using tools like:
+@babel/preset-env
…to ensure compatibility with browsers older than we officially support (like IE 11).
+Radashi currently uses the following Browserslist query:
+ +If you’d like to understand Browserslist better, check out this exceptional article by Alexander Morse.
+To ensure that Radashi keeps its promise of broad compatibility, we use ESLint with only the eslint-plugin-compat
plugin by Amila Welihinda.
When you run pnpm lint
in the Radashi repository, ESLint will check that all the functions in Radashi are compatible with the browsers specified in the browserlist
query in our package.json
file.
”Coverage” refers to audience coverage, which is an estimated percentage of users likely to be using devices that Radashi officially supports. This estimate is based on Browserslist data and is not intended to reflect the actual usage rate of your specific website or application.
+This coverage data is automatically updated whenever the Radashi docs are rebuilt and re-deployed. This page was generated on August 6, 2024.
+Region | Coverage |
---|---|
Global | 92.62% |
USA | 91.83% |
Europe | 92.60% |
China | 79.78% |
China’s lower coverage is mainly due to a lack of support for IE 11 on Radashi’s part. Radashi does not intend to support IE 11.
+Browser | Version | Coverage |
---|---|---|
Chrome for Android | ≥ 127 | 44.10% |
Chrome | ≥ 79 | 19.72% |
Safari on iOS | ≥ 11.0 | 13.88% |
Edge | ≥ 125 | 4.58% |
Safari | ≥ 15.6 | 2.54% |
Firefox | ≥ 115 | 1.89% |
Samsung Internet | ≥ 25 | 1.66% |
Opera Mobile | ≥ 80 | 1.12% |
UC Browser for Android | ≥ 15.5 | 1.05% |
Android Browser | ≥ 127 | 0.81% |
Opera | ≥ 109 | 0.60% |
Firefox for Android | ≥ 127 | 0.35% |
QQ Browser | ≥ 14.9 | 0.34% |
Node | ≥ 16.0.0 | – |
All notable changes to this project will be documented in this file.
+The format is based on Keep a Changelog, +and this project adheres to Semantic Versioning.
+Add isIntString
function by @aleclarson in fa500d3
Add isPlainObject
type guard by @aleclarson in #16
Add round
function by @shan-shaji in #53
Add mapify
function by @cimbraien in #58
Add unzip
function by @aleclarson in #64
Add flip
function by @aleclarson in #35
Add once
function by @aleclarson in #80
Add lerp
function by @aleclarson in #86
Add isMap
function by @aleclarson in 4f2e48c
Add isRegExp
function by @aleclarson in 58e7d96
Add isSet
function by @aleclarson in 73e70c1
Add isWeakSet
function by @aleclarson in aacd5be
Add isWeakMap
function by @aleclarson in f32cfd5
Add traverse
function by @aleclarson in #59
Add cloneDeep
function by @aleclarson in #81
Add castMapping
function by @aleclarson in #43
Add clamp
function by @aleclarson in #106
Add castArray
and castArrayIfExists
by @aleclarson in #97
Add castComparator
function by @aleclarson in #34
Add reverse argument to castComparator
by @aleclarson in 1d7937e
Add isBoolean
function by @aleclarson in adc419d
Add noop
and always
functions by @aleclarson in eb77c8f
Add similarity
function by @aleclarson in #122
(throttle) Add trigger
method to ThrottleFunction by @aleclarson in #135
(intersects) Let identity
callback return any value by @aleclarson in #11
(unique) Let toKey
return any kind of value by @aleclarson in #10
(select) Let condition
be undefined by @aleclarson in #9
Replace matchKeys
with filterKey
by @aleclarson in #28
(filterKey) Accept null/undefined filter by @aleclarson in b10ad10
+Add selectFirst by @adamhamlin in #52
+(pick) Accept a callback for advanced picking by @aleclarson in #30
+(mapify) Provide an index argument to the callbacks by @aleclarson in #100
+Use native AggregateError if available by @MarlonPassos-git in #116
+(retry) Stop using range()
by @aleclarson in 5d60893
(assign) Remove inefficiencies in loop by @aleclarson in #13
+(set) Avoid false positive of array index in path by @aleclarson in #15
+(shake) Stop using Omit
on return type and give filter
parameter a safer type by @aleclarson in #12
(series) Allow items
param to be a readonly array by @aleclarson in #14
Copy is-plain-obj
implementation by @aleclarson in 08a18e2
Avoid isObject
for internal use by @aleclarson in 3b6a67c
(isArray) Work with readonly T[]
types by @aleclarson in 88c12b6
(keys) Improve perf by avoiding excessive array allocations by @aleclarson in #25
+Ensure mapValues
and group
work together by @aleclarson in #24
Use typeof in isFunction
by @aleclarson in 6ad96f4
toInt
and toFloat
should not throw on symbols by @aleclarson in cafc7fc
(assign) Fix overriding a nested object with null by @aleclarson in #112
+(crush) Fix handling of period-containing property names by @stefaanv in #95
+Avoid excessive array allocation in fork
by @localusercamp in #33
Make template
faster by @aleclarson in #32
(cluster) Avoid an array allocation by @aleclarson in #63
+(replace) Avoid creating 2 intermediate arrays by @aleclarson in #61
+(merge) Avoid arrow function in loop and avoid calling user-provided key generator more than once per item by @aleclarson in #60
+(replaceOrAppend) Avoid creating 2 intermediate arrays by @aleclarson in #62
+Let filterKey
accept key: keyof any
by @aleclarson in 73ac8bb
Add TryitResult<T>
type by @aleclarson in f044364
Add MemoOptions<T>
type by @aleclarson in 877a1e4
Export UppercaseKeys
and LowercaseKeys
types by @aleclarson in 96b28b9
Let zip
accept readonly arrays by @aleclarson in f7d93cc
Improve the isArray
return type for unknown
input type by @aleclarson in #72
select
return type when no condition is defined by @aleclarson in ab76d65
Add FilteredKeys
type by @aleclarson in 6a6f899
Improve the return type of filterKey
by @aleclarson in bc298c6
Handle tuples in isArray
return type by @aleclarson in 9257535
Make select
more option-friendly by @aleclarson in c9cfcd0
We've been waiting for you...
Thank you for investing your time in contributing to Radashi.
+Note that this document explains how to contribute through a fork of Radashi. If you’re looking to contribute through a Radashi template, check out this page instead.
+If you have a general question about Radashi, how to use it, the roadmap, or an idea to chat about you can ask it on the discussions page. Before you do, search to see if it’s been asked before. If a related topic doesn’t exist, you can start a new one.
+If you have an issue with Radashi, you want to report a bug, or you need an improvement you can create an issue on the issues page. Before you do, search to see if it’s already been brought up. If a similar issue doesn’t exist, you can create a new one.
+Before adding new functions or features, please review our design principles. If you’re just fixing some existing code, you can skip this step.
+ +Scan through the existing issues to find one that interests you. As a general rule, we don’t assign issues to anyone. If you find an issue to work on, you are welcome to open a PR with a fix. Feel free to ask questions about the implementation or design in a comment on the issue before diving in.
+pnpm i
in the project’s root directory to install the dependencies.pnpm add-function <group-name>/<function-name>
. This will create the necessary files and open a PR with the new function. Try to use a group-name
that already exists, if possible (check the src
directory). Note that you will need to manually export the function from src/mod.ts
before you can use it.pnpm test
. They require Node v16+. You can run nvm use
in the root directory to change to the correct Node version. Passing tests and 100% code coverage is required.pnpm lint
and format it with pnpm format
. You’ll want to do both before sending a pull request.Once you’ve made your changes on a fork of the Radashi repo, create a pull request to the main
branch of the radashi repository. If you made a breaking change, please target the next
branch instead.
main
branch in the PR. Using main can cause issues.Once you submit your PR, one of Radashi’s maintainers will review it. They might ask questions or request additional information.
+Congratulations! 🥳
+Stable versions of Radashi are published manually. Beta versions are published automatically, every day, at 5:00AM UTC (if a PR has been merged). Your PR will be updated with a comment when your PR is included in a beta release.
A new frontier in TypeScript utility libraries.
Welcome to Radashi! We’re here to make your development life easier with a collection of super handy functions designed for modern JavaScript and TypeScript developers. Think of Radashi as a friendly toolbelt that’s all about simplicity, customization, and community.
+Radashi is made with TypeScript at its core. This means our functions not only help you write better code but also catch errors early, making your development smoother and more reliable.
+ +We pick our functions based on real needs and popular use cases. Our goal is to give you just what you need without the extra fluff, keeping everything straightforward and understandable.
+We keep things simple to ensure your projects stay light and fast. Radashi is fully tree-shakeable, so you only include the functions you use. This means no unnecessary bulk in your code.
+Want to add your own touch? You can easily extend Radashi with your own functions using our template repository. Make it yours and easily contribute your functions back to the community.
+ +Radashi thrives on contributions and new ideas. We welcome everyone to join in, share their knowledge, and help the library evolve. Our open process and regular updates keep us in tune with what developers need.
+ +Radashi is here to solve some big issues in utility libraries:
++
Radashi helps you write cleaner, more efficient code by offering a curated set of TypeScript utility functions. Customize it to fit your needs, contribute your own functions, and collaborate with a community of developers to build a better JavaScript ecosystem.
+Ready to dive in? Choose your next step with Radashi:
+Use Radashi in your project
Install the latest stable version:
+ +Install the latest beta version, which includes merged PRs not yet included in a stable release:
+ + +++With PNPM, all the package files are saved in a single place on the disk. When packages are installed to your project, their files are hard-linked from that single place, consuming no additional disk space. This allows you to share dependencies of the same version across projects.
+
Install the latest stable version:
+ +Install the latest beta version, which includes merged PRs not yet included in a stable release:
+ + +++⚡️ 25x faster — Switch from npm install to bun install in any Node.js project to make your installations up to 25x faster.
+
Install the latest stable version:
+ +Install the latest beta version, which includes merged PRs not yet included in a stable release:
+ +Install the latest stable version:
+ +Install the latest beta version, which includes merged PRs not yet included in a stable release:
+ +The guiding principles of Radashi development and community
Radashi’s ethos is rooted in pragmatism, flexibility, and community-driven development. We aim to provide a modern, customizable utility library that serves the needs of TypeScript developers while maintaining simplicity and reliability. This document serves as a living guide for our development process and community interactions, subject to evolution as our project grows and adapts to the changing landscape of software development.
+Radashi is designed for TypeScript developers who appreciate utility libraries without fully embracing Functional Programming. We aim to provide a modern, TypeScript-first approach to common programming tasks, balancing practicality with advanced features.
+At the heart of Radashi is the priority of customizability, allowing developers to tailor the library to their specific project needs. We provide tools and guidance for creating personalized versions of Radashi, empowering users to shape the library according to their unique requirements.
+Radashi embraces a minimalist design philosophy. Our functions are focused, clear, and predictable, avoiding unnecessary complexity. We carefully consider each addition to the library, prioritizing readability and practical utility to ensure that every feature serves a valuable purpose.
+Built with ESM and TypeScript from the ground up, Radashi leverages modern development practices. We optimize for tree-shaking to keep bundles lean and utilize cutting-edge tools like Biome and Vitest, ensuring that Radashi remains at the forefront of JavaScript development.
+We strive for perfect TypeScript support and maintain comprehensive test coverage across all functions. Performance benchmarks and browser compatibility checks are integral to our development process, ensuring that Radashi remains dependable across various environments.
+We avoid creating internal APIs or functions not exported for client use. Dependencies between Radashi modules are minimized to maintain simplicity and ease of understanding, allowing each function to stand on its own as much as possible.
+Radashi functions are designed to be concise, generally not exceeding ~20 lines of code. Complex implementations that require more extensive code may be better suited for separate packages or libraries, maintaining the library’s focus on simplicity.
+Each function in Radashi is designed to be easily transferable to a user’s project with zero modifications. This approach supports quick customization and integration, allowing developers to use Radashi functions flexibly within their own codebases.
+All contributions to Radashi must include comprehensive tests, aiming for 100% line coverage. We emphasize the importance of considering edge cases carefully in test design, ensuring robust and reliable functionality across various scenarios.
+Clear and accurate documentation is required for all new features and changes in Radashi. We prioritize clarity and grammatical correctness in our documentation, ensuring that users can easily understand and implement Radashi’s features.
+Radashi functions are designed to enable common use cases that are awkward to implement in vanilla JavaScript. We avoid replicating functionality that’s already simple in standard JavaScript, focusing instead on providing valuable abstractions.
+Our functions address common use cases without overcomplicating the library. We err on the side of simplicity to avoid bloat and unused code, ensuring that Radashi remains lean and focused on essential utilities.
+Radashi strives for a balance between performance and code brevity. We prioritize understandability to maintain a low contribution barrier and ease of customization, while still ensuring that our functions perform efficiently.
+We implement popular functions based on usage data, without aiming for full parity with other libraries. This approach allows us to innovate on API design while maintaining familiarity where appropriate, creating a unique and valuable utility library.
+Radashi actively seeks real-world feedback to improve reliability and performance. We value and encourage community contributions, recognizing that diverse perspectives enhance the library’s utility and robustness.
+We openly acknowledge areas for growth and actively work to address them. Regular updates and beta releases keep the community informed and involved, fostering an environment of open collaboration and continuous improvement.
+Major changes to this ethos or the library’s direction are open for community discussion. We welcome amendments and re-drafts of this document through official channels, ensuring that Radashi’s development remains aligned with the needs and values of its user community.
+This document is yet to be amended.
+${i(30)}
+${i(40)}
+Sorts an array of objects alphabetically by a property
Given an array of objects and a callback function used to determine +the property to use for sorting, return a new array with the objects +sorted alphabetically. A third, and optional, argument allows you to +sort in descending order instead of the default ascending order.
+For numerical sorting, see the sort function.
+Reduce a list of items down to one item
Given an array of items return the final item that wins the comparison condition. Useful for more complicated min/max.
+Cast a value into an array
The castArray
function ensures that the input value is always returned as an array. If the input is already an array, it returns a shallow copy of the array. If the input is not an array, it wraps the input in a new array.
Cast a non-nullish value into an array
The castArrayIfExists
function ensures that a non-nullish input value is always returned as an array. If the input is already an array, it returns a shallow copy of the array. If the input is not an array, it wraps the input in a new array. Nullish values (null or undefined) are passed through as is.
Split a list into many lists of the given size
Given an array of items and a desired cluster size (n
), returns an array
+of arrays. Each child array containing n
(cluster size) items
+split as evenly as possible.
Creates an object with counts of occurrences of items
Given an array of objects and an identity callback function to determine +how each object should be identified. Returns an object where the keys +are the id values the callback returned and each value is an integer +telling how many times that id occurred.
+Create an array of differences between two arrays
Given two arrays, returns an array of all items that exist in the first array +but do not exist in the second array.
+Get the first item from a list
Given an array of items return the first item or a default value if no items exists.
+Flatten an array of arrays into a single dimension
Given an array that contains many arrays, return a new array where all items from the children are present at the top level.
+ +Note, _.flat
is not recursive and will not flatten children of children of children … of children. It will only flatten T[][]
an array of arrays.
Split an array into two arrays by a condition
Given an array of items and a condition, returns two arrays where the first contains all items that passed the condition and the second contains all items that failed the condition.
+Sort an array of items into groups
Given an array of items, group
will build up an object where each key is an array of the items that belong in that group. Generally, this can be useful to categorize an array.
Determine if two arrays have a common item
Given two arrays of items, returns true if any item exists in both arrays.
+Iterate over a callback n times
A bit like forEach
meets reduce
. Useful for running a function n
number of times to generate a value. The _.iterate
function takes a count (the number of times to run the callback), a callback function, and an initial value. The callback is run count many times as a reducer and the accumulated value is then returned.
Note, this is NOT zero indexed. If you pass a count
of 5 you will get an index of 1, 2, 3, 4, 5 in the callback function.
Get the last item from a list
Given an array of items return the last item or a default value if no items exists.
+Create a list with specific items
Given a start, end, value, and step size returns a list with values from start to end by step size.
+The interface is identical to range
.
A hat tip to Python’s range
functionality
When givin a single argument, it’s treated as the size
. Returns a list with values from 0 to size
.
When given two arguments, they’re treated as the start
and end
. Returns a list with values from start
to end
When given a third argument it’s treated as the value
to be used in the list. If the value
is a function it will be called, with an index argument, to create every value.
When given a fourth argument it’s treated as the step
size to skip when generating values from start
to end
.
Convert an array to a map
The mapify
function converts an array into a Map
object, allowing you to specify how keys and values are derived from each array item.
array
: The input array to be converted into a Map.getKey
: A function that determines the key for each item in the array. It receives two arguments:
+item
: The current array item.index
: The index of the current item in the array.getValue
(optional): A function that determines the value for each item in the array. If not provided, the original array item is used as the value. It also receives two arguments:
+item
: The current array item.index
: The index of the current item in the array.Returns a new Map
object where keys and values are derived from the input array using the provided mapping functions.
Combine two lists overriding items in the first
Given two arrays of items and an identity function, returns the first +list with all items from the second list where there was a match.
+Convert a list to a dictionary object
Given an array of items, create a dictionary with keys and values mapped by given functions. +First argument is the array to map. The second argument is the function to determine the key +for each item. The third argument is optional and determines the value for each item.
+Replace an item in an array
Given an array of items, replace the one that matches the given condition function. Only replaces the first match. Always returns a copy of the original array.
+Replace item in array or append if no match
Given an array of items, an item and an identity function, returns a new array with the item either replaced at the index of the existing item — if it exists, else it is appended at the end.
+Filter and map an array
Applies a filter and a map operation at once and in one pass. +If the filter is omitted, returns all non-nullish mapped values.
+Find and map the first array element meeting a condition
The selectFirst
function combines the functionality of find
and map
operations on an array. It iterates through the array, applying a mapper function to each element, and returns the first mapped value that satisfies a given condition. If no condition is provided, it returns the first non-nullish mapped value.
This function is particularly useful when you need to find and transform an element in a single operation, potentially saving time and improving code readability.
+Key features:
+undefined
if no element satisfies the condition or if the array is empty/nullishShift array items by n steps
Given a list of items, return an array that shift right n positions.
+Remove all falsy items from list
Given a list of items, return a new list with all items that are not falsy.
+Sort a list of objects by a numerical property
Given an array of objects, return a new array sorted by the numerical property specified in the get function. A third, and optional, argument allows you to sort in descending order instead of the default ascending order.
+This function only supports numerical sorting. For alphabetic sorting, see the alphabetical function.
+Toggles an items existance in an array
If the item matching the condition already exists in the list it will be removed. If it does not it will be added.
+ +You can pass an optional toKey
function to determine the identity of non-primitive values. Helpful when working with more complex data types.
By default, toggle will append the item if it does not exist. If you need to prepend the item instead you can override the strategy
in the options argument.
Remove duplicates from an array
Given an array of items — and optionally, a function to determine their identity — return a new array without any duplicates.
+The function does not preserve the original order of items.
+Group array elements by their index position across the input arrays
Creates an array of ungrouped elements, where each resulting array contains all elements at a specific index from the input arrays. The first array contains all first elements, the second array contains all second elements, and so on.
+Combine multiple arrays in sets
Creates an array of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements of the given arrays, and so on.
+Combine multiple arrays in sets
Creates an object mapping the keys in the first array to their corresponding values in the second array.
+Await many promises
The all
function is similar to the builtin Promise.all or Promise.allSettled
+functions. Given a list (or object) of promises, if any errors are thrown, all
+errors are gathered and thrown in an AggregateError.
Passing an array as an argument will return the resolved promise values as an array in the same order.
+ +Passing an object as an argument will return an object with the same keys and the values as the resolved promise values.
+Run an async function with deferred functions
The _.defer
functions lets you run an async function, registering functions as you go
+that should be deferred until the async function completes, and then executed. This is
+really useful in scripts where failure up to or after a specific point will require some
+cleanup. It’s a bit like a finally
block.
A hat tip to Swift’s defer
for the inspiration.
The function passed to _.defer
is called with a single register
function argument that
+can be used to register the work you want to be called when the function completes. If your function throws an error and then a registered cleanup function throws
+and error it is ignored by default. The register
+function supports an optional second options
argument that lets you configure a rethrow
+strategy so that error in the cleanup function is rethrown.
Have a function return undefined if it errors out
This lets you set a default value if an async function errors out.
+ +You can choose to guard only specific errors too
+Map an array with an async function
A map that handles callback functions that return a promise.
+Run many async function in parallel
Like _.map
but built specifically to run the async callback functions
+in parallel. The first argument is a limit of how many functions should
+be allowed to run at once. Returns an array of results.
When all work is complete parallel will check for errors. If any
+occurred they will all be thrown in a single AggregateError
that
+has an errors
property that is all the errors that were thrown.
Reduce an array with an async function
A reduce that handles callback functions that return a promise.
+Run an async function retrying if it fails
The _.retry
function allows you to run an async function and automagically retry it if it fails. Given the async func to run, an optional max number of retries (r
), and an optional milliseconds to delay between retries (d
), the given async function will be called, retrying r
many times, and waiting d
milliseconds between retries.
The times
option defaults to 3
. The delay
option (defaults to null) can specify milliseconds to sleep between attempts.
The backoff
option is like delay but uses a function to sleep — makes for easy exponential backoff.
Asynchronously wait for time to pass
The _.sleep
function allows you to delay in milliseconds.
Convert a function to an error-first function
Error-first callbacks were cool. Using mutable variables to hoist state when doing try/catch was not cool.
+The tryit
function let’s you wrap a function to convert it to an error-first function. Works for both async and sync functions.
You can curry tryit
if you like.
Create a chain of function to run in order
Chaining functions will cause them to execute one after another, passing the output from each function as the input to the next, returning the final output at the end of the chain.
+ +Create a composition of functions
In a composition of functions, each function is given the next function as an argument and must call it to continue executing.
+ +This can be a little jarring if you haven’t seen it before. Here’s a broken down composition. It’s equivelent to the code above.
+Create a debounced callback function
Debounce accepts an options object with a delay
and a source function to call
+when invoked. When the returned function is invoked it will only call the source
+function after the delay
milliseconds of time has passed. Calls that don’t result
+in invoking the source reset the delay, pushing off the next invocation.
A visual of the debounce behavior when delay
is 100
. The debounce function
+returned by debounce
can be called every millisecond but it will only call
+the given callback after delay
milliseconds have passed.
The function returned by debounce
has a cancel
method that when called will permanently stop the source function from being debounced.
The function returned by debounce
has a flush
method that when called will directly invoke the source function.
The function returned by debounce
has a isPending
method that when called will return if there is any pending invocation the source function.
Swap the only two arguments of a function
Return a new function that swaps the only two arguments of the original function. This is most useful for reversing the order of a “comparator” (i.e. a function used for sorting).
+ +Note that functions with more than two arguments are not supported.
Memoize a function
Wrap a function with memo to get a function back that automagically returns values that have already been calculated.
+ +You can optionally pass a ttl
(time to live) that will expire memoized results. In versions prior to version 10, ttl
had a value of 300 milliseconds if not specified.
You can optionally customize how values are stored when memoized.
+Create a function that runs at most once
Create a wrapper around a given function such that it executes at most once. Subsequent calls to the wrapped function return the result from the first execution, regardless of the arguments provided. This behavior is akin to memoization but specifically designed for single-use functions. The result of the first call is stored internally, allowing for efficient retrieval without recomputation.
+ +The once.reset
function clears the stored result of a function that was previously wrapped with once
. This allows the function to be executed again as if it were never called before, enabling dynamic reuse of the function with fresh computations.
Create a partial a function
Create a partial function by providing some — or all — of the arguments the given function needs.
+Create a partob a function
Modern javascript destructuring means a lot of developers, libraries, and frameworks are all opting for unary functions that take a single object that contains the arguments. The _.partob
function let’s you partob these unary functions.
Create a dynamic proxied a object
Javascript’s Proxy
object is powerful but a bit awkward to use. The _.proxied
function creates the Proxy
for you and handles calling back to your handler when functions on the Proxy
are called or properties are accessed.
Creates a throttled function that limits invocations to a specified interval
The throttle
function creates a new function that, when called, will only execute the original function at most once per specified time interval. This is useful for limiting the rate at which a function can fire, especially for performance-intensive operations like handling scroll or resize events.
The function accepts two parameters:
+interval
: The minimum time (in milliseconds) between function invocationstrailing
(optional): If true, also calls the function after the throttle period if it was invoked during the throttleThe returned throttled function also includes these methods:
+isThrottled(): boolean
: To check if there’s currently an active throttletrigger(...args): void
: To invoke the wrapped function without waiting for the next intervalA visual representation of the throttle behavior when interval
is set to 200ms
:
When the trailing
option is set to true
, an additional invocation occurs after the throttle period if any calls were made during the throttled time:
In this diagram, ‘x’ represents function invocations, and ’-’ represents time passing.
Create a function that always returns the same value
Creates a function that always returns the same value, regardless of any arguments passed to it.
+ +You can avoid using always
if the value is a primitive (use () => true
instead), but it can be useful if you need a function that always returns the same object reference, or if you want to memoize a calculation across multiple calls.
Cast a value into a comparator function
Create a comparator function which can be passed into Array.prototype.sort
. It accepts either a property name or a mapping function. Optionally, you can pass a custom compare function (e.g. for localeCompare
use cases).
The first argument of castComparator
is called the mapping
. This can be either:
mapping
is a function, it maps the input values to a comparable value.mapping
is a property name, it maps the input values to a property of the input values with a comparable value.Optionally, you can pass a custom compare
function that receives the mapped values and returns a number. If not provided, values are compared with the <
and >
built-in operators.
A positive number means the “right value” is greater than the “left value”, a negative number means the “left value” is greater than the “right value”, and 0 means both values are equal.
+Cast a value into a mapping function
Improve your own utility function by adding a flexible value-mapping option, using castMapping
to retrieve a mapping function.
The following types can be casted into a mapping function:
+This is the return type of castMapping
.
As you may have noticed in the previous example, the MappedOutput
type is used to infer the type of the value returned by the mapping function.
You can use the Mapping
type to accept a value that can be passed into castMapping
.
If you want a mapping to be optional, use the OptionalMapping
type instead.
The term “castMapping” combines two key concepts from programming:
+“Cast” originates from type casting in programming, which involves converting a value from one data type to another. This process ensures that data is in the correct format for a specific operation.
+”Mapping” as a noun refers to a correspondence between elements of two sets, or a function that defines such a correspondence. In programming, it often represents a data structure that associates keys with values, or a function that transforms one set of data into another.
+Together, “castMapping” describes a function that takes a value (which could be a function, a property name, or undefined) and converts or “casts” it into a standardized mapping. This resulting mapping can then be used to transform data consistently, regardless of the initial input type. The process enhances flexibility in data manipulation by allowing various input types to be treated uniformly as mappings for data transformation.
Does nothing and returns undefined
This is useful when you need to pass a function somewhere, but you don’t care when it runs or what it receives.
+Since noop
has a function signature of () => undefined
, you will be warned by TypeScript if you pass it where a function is expected to return something different.
?.
operator?noop
is best for cases where you’re not in control of the code that calls it and a function is required.Welcome to the Radashi API Reference.
+Sorts an array of objects alphabetically by a property
+Reduce a list of items down to one item
+Cast a value into an array
+Cast a non-nullish value into an array
+Split a list into many lists of the given size
+Creates an object with counts of occurrences of items
+Create an array of differences between two arrays
+Get the first item from a list
+Flatten an array of arrays into a single dimension
+Split an array into two arrays by a condition
+Sort an array of items into groups
+Determine if two arrays have a common item
+Iterate over a callback n times
+Get the last item from a list
+Create a list with specific items
+Convert an array to a map
+Combine two lists overriding items in the first
+Convert a list to a dictionary object
+Replace an item in an array
+Replace item in array or append if no match
+Filter and map an array
+Find and map the first array element meeting a condition
+Shift array items by n steps
+Remove all falsy items from list
+Sort a list of objects by a numerical property
+Toggles an items existance in an array
+Remove duplicates from an array
+Group array elements by their index position across the input arrays
+Combine multiple arrays in sets
+Combine multiple arrays in sets
+Await many promises
+Run an async function with deferred functions
+Have a function return undefined if it errors out
+Map an array with an async function
+Run many async function in parallel
+Reduce an array with an async function
+Run an async function retrying if it fails
+Asynchronously wait for time to pass
+Convert a function to an error-first function
+Create a chain of function to run in order
+Create a composition of functions
+Create a debounced callback function
+Swap the only two arguments of a function
+Memoize a function
+Create a function that runs at most once
+Create a partial a function
+Create a partob a function
+Create a dynamic proxied a object
+Creates a throttled function that limits invocations to a specified interval
+Create a function that always returns the same value
+Cast a value into a comparator function
+Cast a value into a mapping function
+Does nothing and returns undefined
+Limit the range of a variable number
+Verifies number within range, inclusive start, exclusive end, flexible order, defaulting to 0 if end unspecified
+Smoothly transitions between two values based on a factor
+Get the largest item from an array
+Get the smallest item from an array
+Create a range used for iterating
+Rounds a number to a specified precision.
+Add up all items of an array
+Convert a value to a float if possible
+Convert a value to an int if possible
+Merges two objects together recursively
+Creates a shallow copy of the given object/value.
+Create a deep copy of an object or array
+Builds an object from key paths and values
+Flattens a deep object to a single dimension
+Check if an object key passes a filter
+Get any attribute or child attribute using a deep path
+Invert the keys and values of an object
+Get all keys from an object deeply
+Convert an object to a list
+Convert all object keys to lower case
+Map the keys and values of an object
+Map over the keys of an object
+Map over the keys of an object
+Omit unwanted attributes from an object
+Pick only the desired properties from an object
+Set a value on an object using a path key
+Remove unwanted values from an object
+Deeply enumerate an object and any nested objects
+Convert all object keys to upper case
+Get a random item from a list
+Generate a random number
+Randomly shuffle an array
+Generate a unique identifier
+Create an ordered series object
+Convert a string to camel case
+Convert a string to a capitalized format
+Convert a string to dash case
+Convert a string to pascal case
+Calculate the similarity between two strings using the Levenshtein distance algorithm
+Convert a string to snake case
+Template a string with values from a data object using a search expression
+Convert a string to title case
+Trim values from a string
+Determine if a value is an Array
+Check if a value is a boolean type
+Determine if a value is a Date
+Determine if a value is empty
+Determine if two values are equal
+Determine if a value is a float
+Determine if a value is a Function
+Determine if a value is an int
+Determine if a value is an int in string form
+Returns true for Map instances
+Determine if a value is a number
+Determine if a value is an Object
+Determine if a value is a plain object
+Checks if the given value is primitive
+Determine if a value is a Promise
+Returns true for RegExp instances
+Returns true for Set instances
+Determine if a value is a String
+Determine if a value is a Symbol
+Returns true for WeakMap instances
+Returns true for WeakSet instances
Limit the range of a variable number
The clamp
function restricts a number to be within a specified
+range.
Verifies number within range, inclusive start, exclusive end, flexible order, defaulting to 0 if end unspecified
Pass the number, the start and the end (optional) of the range. The _.inRange
function will return true if the given number is in the range.
>= 0 and < start
.Smoothly transitions between two values based on a factor
The lerp
function is used to linearly interpolate between two numbers based on a specified amount. This function is particularly useful in animations, graphics, and games for smooth transitions.
The name lerp
is short for “linear interpolation”. It’s a term from computer graphics that means “interpolate linearly between two values”.
For more information, check out the Wikipedia article on linear interpolation.
Get the largest item from an array
Given an array of items and a function to get the value of each item, returns the item with the largest value. Uses _.boil
under the hood.
Get the smallest item from an array
Given an array of items and a function to get the value of each item, returns the item with the smallest value. Uses _.boil
under the hood.
Create a range used for iterating
Given a start, end, value, and step size returns a generator that will yield values from start to end by step size. Useful for replacing for (let i = 0)
with for of
. Range will return a generator that for of
will call one at a time, so it’s safe to create large ranges.
The interface is identical to list
.
A hat tip to Python’s range
functionality
The range function can do a lot with different arguments.
+When givin a single argument, it’s treated as the size
. Returns a generator that yields values from 0 to size
.
When given two arguments, they’re treated as the start
and end
. Returns a generator that yields values from start
to end
When given a third argument it’s treated as the value
to be yielded in the generator. If the value
is a function it will be called, with an index argument, to create every value.
When given a fourth argument it’s treated as the step
size to skip when yielding values from start
to end
.
Rounds a number to a specified precision.
The _.round
function rounds a given number to a specified precision.
The precision
argument is limited to be within the range of -323 to +292.
+Without this limit, precision values outside this range can result in NaN.
You may provide a custom rounding method. The default is Math.round
.
Add up all items of an array
Given an array of items, and an optional function to map each item to a number, add up all the items.
+Convert a value to a float if possible
The _.toFloat
function will do its best to convert the given value to a float.
Convert a value to an int if possible
The _.toInt
function will do its best to convert the given value to an int.
Merges two objects together recursively
Merges two objects together recursively into a new object applying values from right to left. Recursion only applies to child object properties.
+Creates a shallow copy of the given object/value.
Creates a shallow copy of the given object/value.
+Create a deep copy of an object or array
Deeply clone the given object or array. The only nested objects that get cloned by default are: plain objects, arrays, Map
instances, and Set
instances.
The default behavior aims to support the most popular use cases. See “Customized cloning” below if you need more control.
+By default, non-enumerable properties and computed properties are copied losslessly. Note that you can opt out of this behavior if you need better performance (see “Faster cloning” below).
+ +You can pass the FastCloningStrategy
for better performance, but bear in mind the following tradeoff.
All plain objects and class instances are cloned with {...obj}
. This means that the original prototype, computed properties, and non-enumerable properties are not preserved.
Also note that built-in, complex objects like RegExp
and Date
are still not cloned with this cloning strategy. You can override the cloneOther
function if you need to clone these object types.
“Cloning strategies” control how certain object types are handled by cloneDeep
. You can pass in a custom strategy, which may even be a partial strategy. Any undefined methods in your strategy will inherit the default logic. Your custom methods can return null
to use the default logic, or they can return the received object to skip cloning.
If you clone the object in your custom method, make sure to pass the clone into the track
function before cloning the nested objects. Here’s an example with cloneOther
that handles a custom class instance.
Builds an object from key paths and values
The opposite of crush, given an object that was crushed into key paths and values will return the original object reconstructed.
+Flattens a deep object to a single dimension
Flattens a deep object to a single dimension. The deep keys will be converted to a dot notation in the new object.
+Check if an object key passes a filter
You have a utility function that is filtering an object’s properties somehow. Using filterKey
will allow your function to filter those properties based on either an array of keys (an allowlist) or a function that returns a boolean for each property.
The KeyFilter
type provided by Radashi is fundamental in taking advantage of the filterKey
function. Be sure to use it to ensure type safety and maintainable code.
Get any attribute or child attribute using a deep path
Given any value and a select function to get the desired attribute, returns the desired value or a default value if the desired value couldn’t be found.
+Invert the keys and values of an object
Given an object returns a new object with the keys and values reversed.
+Get all keys from an object deeply
Given an object, return all of it’s keys and children’s keys deeply as a flat string list.
+ +This is a function you might like to use with get
, which dynamically looks up values in an object given a string path. Using the two together you could do something like flatten a deep object.
As of v10.5.0+ you can get this behavior via the crush function
Convert an object to a list
Given an object and a mapping function, return an array with an item for each entry in the object.
+Convert all object keys to lower case
Convert all keys in an object to lower case. Useful to standardize attribute key casing. For example, headers.
+ +The _.lowerize
function is a shortcut for _.mapKeys(obj, k => k.toLowerCase())
Map the keys and values of an object
Iterates the entries of an object, calling the given toEntry
callback function
+to generate new entries. It’s a _.mapValues
and _.mapKeys
+in one. The toEntry
callback function should return an array with
+two items [key, value]
(a.k.a the new entry).
Map over the keys of an object
Given an object and a toKey
callback function, returns a new object with all the keys
+mapped through the toKey
function. The callback is given both the key and value for each entry.
Map over the keys of an object
Given an object and a toValue
callback function, returns a new object with all the values
+mapped through the toValue
function. The callback is given both the value and key for each entry.
Omit unwanted attributes from an object
Given an object and a list of keys in the object, returns a new object without any of the given keys.
+Pick only the desired properties from an object
Given an object and a list of keys in the object, returns a new object with only the given keys.
+ +The pick
function can also accept a predicate function as the filter argument. This allows for more complex filtering logic beyond simple key inclusion or exclusion.
Set a value on an object using a path key
Opposite of get, dynamically set a nested value into an object using a key path. Does not modify the given initial object.
+Remove unwanted values from an object
A bit like _.sift
but for objects. By default, it will return a new object with all the undefined attributes removed. You can pass a second function argument to remove any attributes by a custom condition.
Deeply enumerate an object and any nested objects
Recursively visit each property of an object (or each element of an array) and its nested objects or arrays. To traverse non-array iterables (e.g. Map
, Set
) and class instances, see the Traversing other objects section.
Traversal is performed in a depth-first manner. That means the deepest object will be visited before the last property of the root object.
+ +Tip: Check out the Advanced section to see what else is possible.
+ +The TraverseVisitor
type represents the function passed to traverse
as its 2nd argument. If you ever need to declare a visitor separate from a traverse
call, you can do so by declaring a function with this type signature.
Every visit includes a context object typed with TraverseContext
, which contains the following properties:
key
: The current key being visited.parent
: The parent object of the current value.parents
: An array of objects (from parent to child) that the current value is contained by.path
: An array describing the key path to the current value from the root.skip
: A function used for skipping traversal of an object. If no object is provided, the current value is skipped. See Skipping objects for more details.skipped
: A set of objects that have been skipped.value
: The current value being visited.You may set these options for traverse
using an object as its 3rd argument.
ownKeys
: A function that returns the own enumerable property names of an object.rootNeedsVisit
: A boolean indicating whether the root object should be visited.See the Options section for more details.
+By default, non-enumerable properties and symbol properties are skipped. You can pass in a custom ownKeys
implementation to control which object properties are visited.
This example shows how Reflect.ownKeys
can be used to include non-enumerable properties and symbol properties. Note that symbol properties are always traversed last when using Reflect.ownKeys
.
By default, your visitor
callback will never receive the object passed into traverse
. To override this behavior, set the rootNeedsVisit
option to true.
When the root object is visited, the key
will be null
.
If traversing plain objects and arrays isn’t enough, try calling traverse
from within another traverse
callback like follows. This takes advantage of the fact that the root object is always traversed.
If you didn’t set any options, the options
argument can be null:
Using the TraverseContext::skip
method, you can prevent an object from being traversed. By calling skip()
with no arguments, the current value won’t be traversed.
You can pass any object to skip()
to skip traversal of that object.
If your visitor
callback returns false, traverse
will exit early and also return false. This is useful if you found what you wanted, so you don’t need to traverse the rest of the objects.
If your visitor
callback returns a function, it will be called once traverse
has visited every visitable property/element within the current object. This is known as a “leave callback”.
Your leave callback can return false to exit traversal early.
+Convert all object keys to upper case
Convert all keys in an object to upper case.
+ +The _.upperize
function is a shortcut for _.mapKeys(obj, k => k.toUpperCase())
Get a random item from a list
Draw, as in ‘to draw a card from a deck’, is used to get a random item from an array.
+Generate a random number
Genearate a number within a range. This function is meant for utility use — not cryptographic.
+Randomly shuffle an array
Create a new array with the items of the given array but in a random order. The randomization is done using the Fisher-Yates algorithm, which is mathematically proven to be unbiased (i.e. all permutations are equally likely).
+Generate a unique identifier
Generates a unique string with optional special characters.
+ +Note, this function is optimized for simplicity and usability — not performance or security. If you need to create universally unique or cryptographically random strings use a package specifically for that purpose.
Create an ordered series object
Sometimes you have an enum or union type, possibly a status, that has inherint order and you need to work with values as though they’re ordered. The series
function takes many values and returns an object that let’s you do ordered logic on those values.
When working with objects you’ll want to provide a second argument to series
, a function that converts non-primitive values into an identity that can be checked for equality.
Convert a string to camel case
Given a string returns it in camel case format.
+Convert a string to a capitalized format
Given a string returns it with the first letter upper cased and all other letters lower cased.
+Convert a string to dash case
Given a string returns it in dash case format.
+Convert a string to pascal case
Formats the given string in pascal case fashion.
+Calculate the similarity between two strings using the Levenshtein distance algorithm
The similarity
function computes the Levenshtein distance between two input strings. This distance represents the minimum number of single-character edits (insertions, deletions, or substitutions) required to change one string into the other.
This function is useful for various applications, including:
+The function is case-sensitive and treats whitespace as significant characters. The order of the input strings doesn’t affect the result, as the Levenshtein distance is symmetric.
+ +The function returns a number
representing the Levenshtein distance between the two input strings. A lower number indicates higher similarity, with 0 meaning the strings are identical.
Convert a string to snake case
Given a string returns it in snake case format.
+ +Warning: In v11.0.0 a change was made to fix this function so that it correctly splits numbers from neighbouring letters (hello5
becomes hello_5
). You can opt out of this behavior and continue with the legacy style (hello5
becomes hello5
) by passing the splitOnNumber
options.
Template a string with values from a data object using a search expression
Given a string, an object of data, and a format expression to search for, returns a string with all elements that matched the search replaced with their matching value from the data object.
+Convert a string to title case
Formats the given string in title case fashion
+Trim values from a string
Trims all prefix and suffix characters from the given string. Like the builtin trim function but accepts alternate (other than space) characters you would like to trim.
+ +Trim also handles more than one character to trim.
+Determine if a value is an Array
Pass in a value and get a boolean telling you if the value is an Array.
+Check if a value is a boolean type
Returns true if the value is a boolean
type. Boxed boolean values (e.g. new Boolean(false)
) are not considered booleans by this function.
Determine if a value is a Date
Determine if a value is a Date. Does not check that the input date is valid, only that it is a Javascript Date type.
+Determine if a value is empty
Pass in a value and get a boolean telling you if the value is empty.
+Determine if two values are equal
Given two values, returns true if they are equal.
+Determine if a value is a float
Pass in a value and get a boolean telling you if the value is a float.
+Determine if a value is a Function
Pass in a value and get a boolean telling you if the value is a function.
+Determine if a value is an int
Pass in a value and get a boolean telling you if the value is an int.
+Determine if a value is an int in string form
Pass in a value and get a boolean telling you if the value is an int in string form.
+Returns true for Map instances
Returns true for Map
instances, even if they are subclass instances or from
+other realms.
Determine if a value is a number
Pass in a value and get a boolean telling you if the value is a number.
+Determine if a value is an Object
Pass in a value and get a boolean telling you if the value is an instance of Object
(or a subclass of Object
).
Beware: This function returns false
for objects created with Object.create(null)
. If you want to check if a value is a plain object, use _.isPlainObject
instead.
Determine if a value is a plain object
Pass in a value and get a boolean telling you if the value is a plain object.
+Checks if the given value is primitive
Checks if the given value is primitive.
+Primitive Types: number , string , boolean , symbol, bigint, undefined, null
+Determine if a value is a Promise
Pass in a value and get a boolean telling you if the value is a Promise. This function is not “bullet proof” because determining if a value is a Promise in javascript is not “bullet proof”. The standard/recommended method is to use Promise.resolve
to essentially cast any value, promise or not, into an awaited value. However, this may do in a pinch.
Returns true for RegExp instances
Returns true for RegExp
instances, even if they are subclass instances or from
+other realms.
Returns true for Set instances
Returns true for Set
instances, even if they are subclass instances or from
+other realms.
Determine if a value is a String
Pass in a value and get a boolean telling you if the value is a string.
+Determine if a value is a Symbol
Pass in a value and get a boolean telling you if the value is a Symbol.
+Returns true for WeakMap instances
Returns true for WeakMap
instances, even if they are subclass instances or from
+other realms.
Returns true for WeakSet instances
Returns true for WeakSet
instances, even if they are subclass instances or from
+other realms.