├── .github └── workflows │ ├── ci.yaml │ └── release-tag.yaml ├── .gitignore ├── .prettierignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README.zh-CN.md ├── docs ├── .vitepress │ ├── config.ts │ ├── items │ │ ├── array.ts │ │ ├── collection.ts │ │ ├── file.ts │ │ ├── function.ts │ │ ├── general.ts │ │ ├── index.ts │ │ ├── math.ts │ │ ├── number.ts │ │ ├── object.ts │ │ ├── string.ts │ │ └── util.ts │ └── theme │ │ ├── custom.css │ │ └── index.ts ├── array │ ├── at.md │ ├── chunk.md │ ├── difference-with.md │ ├── difference.md │ ├── find.md │ ├── group-by.md │ ├── intersection-with.md │ ├── intersection.md │ ├── normalize-to-array.md │ ├── remove-array-blank.md │ ├── remove-array-empty.md │ ├── remove-item.md │ ├── shuffle.md │ ├── toggle-item.md │ ├── uniq-by.md │ ├── uniq.md │ ├── xor-with.md │ └── xor.md ├── collection │ ├── clone-deep-with.md │ ├── clone-deep.md │ ├── merge-with.md │ └── merge.md ├── file │ ├── to-array-buffer.md │ ├── to-data-url.md │ └── to-text.md ├── function │ ├── call.md │ ├── debounce.md │ ├── noop.md │ ├── once.md │ └── throttle.md ├── general │ ├── assert.md │ ├── get-global-this.md │ ├── has-own.md │ ├── in-browser.md │ ├── in-mobile.md │ ├── is-array-buffer.md │ ├── is-array.md │ ├── is-blob.md │ ├── is-boolean.md │ ├── is-data-view.md │ ├── is-date.md │ ├── is-dom-exception.md │ ├── is-empty-plain-object.md │ ├── is-empty.md │ ├── is-equal-with.md │ ├── is-equal.md │ ├── is-error.md │ ├── is-file.md │ ├── is-function.md │ ├── is-map.md │ ├── is-non-empty-array.md │ ├── is-nullish.md │ ├── is-number.md │ ├── is-numeric.md │ ├── is-object.md │ ├── is-plain-object.md │ ├── is-primitive.md │ ├── is-promise.md │ ├── is-reg-exp.md │ ├── is-set.md │ ├── is-string.md │ ├── is-symbol.md │ ├── is-truthy.md │ ├── is-typed-array.md │ ├── is-weak-map.md │ ├── is-weak-set.md │ ├── is-window.md │ ├── support-touch.md │ ├── to-raw-type.md │ └── to-type-string.md ├── getting-started.md ├── index.md ├── math │ ├── ceil.md │ ├── floor.md │ ├── max-by.md │ ├── mean-by.md │ ├── mean.md │ ├── min-by.md │ ├── round.md │ ├── sample.md │ ├── sum-by.md │ ├── sum-hash.md │ └── sum.md ├── number │ ├── clamp-array-range.md │ ├── clamp.md │ ├── delay.md │ ├── gen-number-key.md │ ├── random-number.md │ ├── times.md │ └── to-number.md ├── object │ ├── map-object.md │ ├── omit-by.md │ ├── omit.md │ ├── pick-by.md │ ├── pick.md │ └── promise-with-resolvers.md ├── public │ └── logo.svg ├── string │ ├── camelize.md │ ├── ensure-prefix.md │ ├── ensure-suffix.md │ ├── gen-string-key.md │ ├── kebab-case.md │ ├── lower-first.md │ ├── pascal-case.md │ ├── random-color.md │ ├── random-string.md │ ├── slash.md │ └── upper-first.md ├── util │ ├── cancel-animation-frame.md │ ├── classes.md │ ├── copy-text.md │ ├── create-namespace-fn.md │ ├── double-raf.md │ ├── download.md │ ├── get-all-parent-scroller.md │ ├── get-parent-scroller.md │ ├── get-rect.md │ ├── get-scroll-left.md │ ├── get-scroll-top.md │ ├── get-style.md │ ├── in-viewport.md │ ├── mitt.md │ ├── motion.md │ ├── pretty-JSON-object.md │ ├── prevent-default.md │ ├── raf.md │ ├── request-animation-frame.md │ ├── storage.md │ └── try-parse-JSON.md └── zh │ ├── array │ ├── at.md │ ├── chunk.md │ ├── difference-with.md │ ├── difference.md │ ├── find.md │ ├── group-by.md │ ├── intersection-with.md │ ├── intersection.md │ ├── normalize-to-array.md │ ├── remove-array-blank.md │ ├── remove-array-empty.md │ ├── remove-item.md │ ├── shuffle.md │ ├── sum-by.md │ ├── sum.md │ ├── toggle-item.md │ ├── uniq-by.md │ ├── uniq.md │ ├── xor-with.md │ └── xor.md │ ├── collection │ ├── clone-deep-with.md │ ├── clone-deep.md │ ├── merge-with.md │ └── merge.md │ ├── file │ ├── to-array-buffer.md │ ├── to-data-url.md │ └── to-text.md │ ├── function │ ├── call.md │ ├── debounce.md │ ├── noop.md │ ├── once.md │ └── throttle.md │ ├── general │ ├── assert.md │ ├── get-global-this.md │ ├── has-own.md │ ├── in-browser.md │ ├── in-mobile.md │ ├── is-array-buffer.md │ ├── is-array.md │ ├── is-blob.md │ ├── is-boolean.md │ ├── is-data-view.md │ ├── is-date.md │ ├── is-dom-exception.md │ ├── is-empty-plain-object.md │ ├── is-empty.md │ ├── is-equal-with.md │ ├── is-equal.md │ ├── is-error.md │ ├── is-file.md │ ├── is-function.md │ ├── is-map.md │ ├── is-non-empty-array.md │ ├── is-nullish.md │ ├── is-number.md │ ├── is-numeric.md │ ├── is-object.md │ ├── is-plain-object.md │ ├── is-primitive.md │ ├── is-promise.md │ ├── is-reg-exp.md │ ├── is-set.md │ ├── is-string.md │ ├── is-symbol.md │ ├── is-truthy.md │ ├── is-typed-array.md │ ├── is-weak-map.md │ ├── is-weak-set.md │ ├── is-window.md │ ├── support-touch.md │ ├── to-raw-type.md │ └── to-type-string.md │ ├── getting-started.md │ ├── index.md │ ├── math │ ├── ceil.md │ ├── floor.md │ ├── max-by.md │ ├── mean-by.md │ ├── mean.md │ ├── min-by.md │ ├── round.md │ ├── sample.md │ ├── sum-by.md │ ├── sum-hash.md │ └── sum.md │ ├── number │ ├── clamp-array-range.md │ ├── clamp.md │ ├── delay.md │ ├── gen-number-key.md │ ├── random-number.md │ ├── times.md │ └── to-number.md │ ├── object │ ├── map-object.md │ ├── omit-by.md │ ├── omit.md │ ├── pick-by.md │ ├── pick.md │ └── promise-with-resolvers.md │ ├── string │ ├── camelize.md │ ├── ensure-prefix.md │ ├── ensure-suffix.md │ ├── gen-string-key.md │ ├── kebab-case.md │ ├── lower-first.md │ ├── pascal-case.md │ ├── random-color.md │ ├── random-string.md │ ├── slash.md │ └── upper-first.md │ └── util │ ├── cancel-animation-frame.md │ ├── classes.md │ ├── copy-text.md │ ├── create-namespace-fn.md │ ├── double-raf.md │ ├── download.md │ ├── get-all-parent-scroller.md │ ├── get-parent-scroller.md │ ├── get-rect.md │ ├── get-scroll-left.md │ ├── get-scroll-top.md │ ├── get-style.md │ ├── in-viewport.md │ ├── mitt.md │ ├── motion.md │ ├── pretty-JSON-object.md │ ├── prevent-default.md │ ├── raf.md │ ├── request-animation-frame.md │ ├── storage.md │ └── try-parse-JSON.md ├── eslint.config.js ├── package.json ├── pnpm-lock.yaml ├── prettier.config.js ├── src ├── array │ ├── at.ts │ ├── chunk.ts │ ├── difference.ts │ ├── differenceWith.ts │ ├── find.ts │ ├── groupBy.ts │ ├── index.ts │ ├── intersection.ts │ ├── intersectionWith.ts │ ├── normalizeToArray.ts │ ├── removeArrayBlank.ts │ ├── removeArrayEmpty.ts │ ├── removeItem.ts │ ├── shuffle.ts │ ├── toggleItem.ts │ ├── uniq.ts │ ├── uniqBy.ts │ ├── xor.ts │ └── xorWith.ts ├── collection │ ├── cloneDeep.ts │ ├── cloneDeepWith.ts │ ├── index.ts │ ├── merge.ts │ └── mergeWith.ts ├── file │ ├── index.ts │ ├── toArrayBuffer.ts │ ├── toDataURL.ts │ └── toText.ts ├── function │ ├── NOOP.ts │ ├── call.ts │ ├── debounce.ts │ ├── index.ts │ ├── once.ts │ └── throttle.ts ├── general │ ├── assert.ts │ ├── getGlobalThis.ts │ ├── hasOwn.ts │ ├── inBrowser.ts │ ├── inMobile.ts │ ├── index.ts │ ├── isArray.ts │ ├── isArrayBuffer.ts │ ├── isBlob.ts │ ├── isBoolean.ts │ ├── isDOMException.ts │ ├── isDataView.ts │ ├── isDate.ts │ ├── isEmpty.ts │ ├── isEmptyPlainObject.ts │ ├── isEqual.ts │ ├── isEqualWith.ts │ ├── isError.ts │ ├── isFile.ts │ ├── isFunction.ts │ ├── isMap.ts │ ├── isNonEmptyArray.ts │ ├── isNullish.ts │ ├── isNumber.ts │ ├── isNumeric.ts │ ├── isObject.ts │ ├── isPlainObject.ts │ ├── isPrimitive.ts │ ├── isPromise.ts │ ├── isRegExp.ts │ ├── isSet.ts │ ├── isString.ts │ ├── isSymbol.ts │ ├── isTruthy.ts │ ├── isTypedArray.ts │ ├── isWeakMap.ts │ ├── isWeakSet.ts │ ├── isWindow.ts │ ├── supportTouch.ts │ ├── toRawType.ts │ └── toTypeString.ts ├── index.ts ├── math │ ├── ceil.ts │ ├── floor.ts │ ├── index.ts │ ├── maxBy.ts │ ├── mean.ts │ ├── meanBy.ts │ ├── minBy.ts │ ├── round.ts │ ├── sample.ts │ ├── sum.ts │ ├── sumBy.ts │ └── sumHash.ts ├── number │ ├── clamp.ts │ ├── clampArrayRange.ts │ ├── delay.ts │ ├── genNumberKey.ts │ ├── index.ts │ ├── randomNumber.ts │ ├── times.ts │ └── toNumber.ts ├── object │ ├── index.ts │ ├── mapObject.ts │ ├── omit.ts │ ├── omitBy.ts │ ├── pick.ts │ ├── pickBy.ts │ └── promiseWithResolvers.ts ├── string │ ├── camelize.ts │ ├── ensurePrefix.ts │ ├── ensureSuffix.ts │ ├── genStringKey.ts │ ├── index.ts │ ├── kebabCase.ts │ ├── lowerFirst.ts │ ├── pascalCase.ts │ ├── randomColor.ts │ ├── randomString.ts │ ├── slash.ts │ └── upperFirst.ts └── util │ ├── cancelAnimationFrame.ts │ ├── classes.ts │ ├── copyText.ts │ ├── createNamespaceFn.ts │ ├── doubleRaf.ts │ ├── download.ts │ ├── getAllParentScroller.ts │ ├── getParentScroller.ts │ ├── getRect.ts │ ├── getScrollLeft.ts │ ├── getScrollTop.ts │ ├── getStyle.ts │ ├── inViewport.ts │ ├── index.ts │ ├── motion.ts │ ├── prettyJSONObject.ts │ ├── preventDefault.ts │ ├── raf.ts │ ├── requestAnimationFrame.ts │ ├── storage.ts │ └── tryParseJSON.ts ├── tests ├── array.spec.ts ├── collection.spec.ts ├── file.spec.ts ├── function.spec.ts ├── general.spec.ts ├── math.spec.ts ├── number.spec.ts ├── object.spec.ts ├── string.spec.ts └── util.spec.ts ├── tsconfig.json └── vitest.config.ts /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v4 11 | 12 | - name: Install pnpm 13 | run: corepack enable 14 | 15 | - name: Set node version to 18 16 | uses: actions/setup-node@v3 17 | with: 18 | node-version: '18' 19 | cache: 'pnpm' 20 | 21 | - name: Install dependencies 22 | run: pnpm install --no-frozen-lockfile 23 | 24 | - name: Run linter 25 | run: pnpm lint 26 | 27 | - name: Run test cases 28 | run: pnpm test 29 | 30 | - name: Upload results to Codecov 31 | uses: codecov/codecov-action@v4 32 | with: 33 | token: ${{ secrets.CODECOV_TOKEN }} 34 | -------------------------------------------------------------------------------- /.github/workflows/release-tag.yaml: -------------------------------------------------------------------------------- 1 | name: Create Release Tag 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | release-tag: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@master 14 | 15 | - name: Create Release Tag 16 | id: release_tag 17 | uses: yyx990803/release-tag@master 18 | env: 19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 20 | with: 21 | tag_name: ${{ github.ref }} 22 | body: | 23 | 更新内容请查看[CHANGELOG](https://github.com/varletjs/rattail/blob/main/CHANGELOG.md)。 24 | Please refer to [CHANGELOG](https://github.com/varletjs/rattail/blob/main/CHANGELOG.md) for details. 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | node_modules 3 | lib 4 | coverage 5 | .DS_Store 6 | docs/.vitepress/cache 7 | docs/.vitepress/dist -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | lib/** 2 | .history/** 3 | coverage/** 4 | docs/.vitepress/cache/** 5 | docs/.vitepress/dist/** 6 | 7 | pnpm-lock.yaml 8 | pnpm-workspace.yaml 9 | 10 | CHANGELOG.md -------------------------------------------------------------------------------- /docs/.vitepress/items/collection.ts: -------------------------------------------------------------------------------- 1 | export const collectionItems = [ 2 | { text: 'cloneDeep', link: '/collection/clone-deep' }, 3 | { text: 'cloneDeepWith', link: '/collection/clone-deep-with' }, 4 | { text: 'merge', link: '/collection/merge' }, 5 | { text: 'mergeWith', link: '/collection/merge-with' }, 6 | ] 7 | -------------------------------------------------------------------------------- /docs/.vitepress/items/file.ts: -------------------------------------------------------------------------------- 1 | export const fileItems = [ 2 | { text: 'toText', link: '/file/to-text' }, 3 | { text: 'toDataURL', link: '/file/to-data-url' }, 4 | { text: 'toArrayBuffer', link: '/file/to-array-buffer' }, 5 | ] 6 | -------------------------------------------------------------------------------- /docs/.vitepress/items/function.ts: -------------------------------------------------------------------------------- 1 | export const functionItems = [ 2 | { text: 'NOOP', link: '/function/noop' }, 3 | { text: 'call', link: '/function/call' }, 4 | { text: 'once', link: '/function/once' }, 5 | { text: 'debounce', link: '/function/debounce' }, 6 | { text: 'throttle', link: '/function/throttle' }, 7 | ] 8 | -------------------------------------------------------------------------------- /docs/.vitepress/items/index.ts: -------------------------------------------------------------------------------- 1 | export * from './general' 2 | export * from './string' 3 | export * from './number' 4 | export * from './object' 5 | export * from './array' 6 | export * from './collection' 7 | export * from './function' 8 | export * from './math' 9 | export * from './util' 10 | export * from './file' 11 | -------------------------------------------------------------------------------- /docs/.vitepress/items/math.ts: -------------------------------------------------------------------------------- 1 | export const mathItems = [ 2 | { text: 'sum', link: '/math/sum' }, 3 | { text: 'sumBy', link: '/math/sum-by' }, 4 | { text: 'sumHash', link: '/math/sum-hash' }, 5 | { text: 'minBy', link: '/math/min-by' }, 6 | { text: 'maxBy', link: '/math/max-by' }, 7 | { text: 'mean', link: '/math/mean' }, 8 | { text: 'meanBy', link: '/math/mean-by' }, 9 | { text: 'sample', link: '/math/sample' }, 10 | { text: 'round', link: '/math/round' }, 11 | { text: 'floor', link: '/math/floor' }, 12 | { text: 'ceil', link: '/math/ceil' }, 13 | ] 14 | -------------------------------------------------------------------------------- /docs/.vitepress/items/number.ts: -------------------------------------------------------------------------------- 1 | export const numberItems = [ 2 | { text: 'toNumber', link: '/number/to-number' }, 3 | { text: 'genNumberKey', link: '/number/gen-number-key' }, 4 | { text: 'randomNumber', link: '/number/random-number' }, 5 | { text: 'clamp', link: '/number/clamp' }, 6 | { text: 'clampArrayRange', link: '/number/clamp-array-range' }, 7 | { text: 'times', link: '/number/times' }, 8 | { text: 'delay', link: '/number/delay' }, 9 | ] 10 | -------------------------------------------------------------------------------- /docs/.vitepress/items/object.ts: -------------------------------------------------------------------------------- 1 | export const objectItems = [ 2 | { text: 'pick', link: '/object/pick' }, 3 | { text: 'pickBy', link: '/object/pick-by' }, 4 | { text: 'omit', link: '/object/omit' }, 5 | { text: 'omitBy', link: '/object/omit-by' }, 6 | { text: 'mapObject', link: '/object/map-object' }, 7 | { text: 'promiseWithResolvers', link: '/object/promise-with-resolvers' }, 8 | ] 9 | -------------------------------------------------------------------------------- /docs/.vitepress/items/string.ts: -------------------------------------------------------------------------------- 1 | export const stringItems = [ 2 | { text: 'randomString', link: '/string/random-string' }, 3 | { text: 'randomColor', link: '/string/random-color' }, 4 | { text: 'genStringKey', link: '/string/gen-string-key' }, 5 | { text: 'camelize', link: '/string/camelize' }, 6 | { text: 'kebabCase', link: '/string/kebab-case' }, 7 | { text: 'pascalCase', link: '/string/pascal-case' }, 8 | { text: 'upperFirst', link: '/string/upper-first' }, 9 | { text: 'lowerFirst', link: '/string/lower-first' }, 10 | { text: 'slash', link: '/string/slash' }, 11 | { text: 'ensurePrefix', link: '/string/ensure-prefix' }, 12 | { text: 'ensureSuffix', link: '/string/ensure-suffix' }, 13 | ] 14 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/custom.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --vp-c-brand-1: #cf8040; 3 | --vp-c-brand-2: #a06433; 4 | --vp-button-brand-bg: #cf8040; 5 | --vp-home-hero-image-background-image: linear-gradient(-45deg, #d1841f60 30%, #edcb3260); 6 | --vp-home-hero-image-filter: blur(30px); 7 | } 8 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import DefaultTheme from 'vitepress/theme' 2 | import './custom.css' 3 | 4 | export default DefaultTheme 5 | -------------------------------------------------------------------------------- /docs/array/at.md: -------------------------------------------------------------------------------- 1 | # at 2 | 3 | Retrieves the element at a specified index in an `array`, supporting negative indices. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { at } from 'rattail' 9 | 10 | at([1, 2, 3], 0) // return 1 11 | at([1, 2, 3], -1) // return 3 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | -------- | -------- | 18 | | `arr` | `Array` | | 19 | | `index` | `number` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | ----- | 25 | | `any` | 26 | -------------------------------------------------------------------------------- /docs/array/chunk.md: -------------------------------------------------------------------------------- 1 | # chunk 2 | 3 | Chunking an `array`. The passed `size` indicates the length of the chunk. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { chunk } from 'rattail' 9 | 10 | chunk([1, 2, 3], 2) // return [[1, 2], [3]] 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ------ | -------- | -------- | 17 | | `arr` | `Array` | | 18 | | `size` | `number` | `1` | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | ------- | 24 | | `Array` | 25 | -------------------------------------------------------------------------------- /docs/array/difference-with.md: -------------------------------------------------------------------------------- 1 | # differenceWith 2 | 3 | Creates an `array` of array values ​​that are not contained in other given arrays, and supports custom comparison functions. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { differenceWith } from 'rattail' 9 | 10 | differenceWith([{ num: 1 }, { num: 2 }, { num: 3 }], [{ num: 2 }], (a, b) => a.num === b.num) 11 | // return [{ num: 1 }, { num: 3 }] 12 | differenceWith([{ num: 1 }, { num: 2 }, { num: 3 }], [{ num: 2 }], [{ num: 3 }], (a, b) => a.num === b.num) 13 | // return [{ num: 1 }] 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ----------- | ------------------------- | -------- | 20 | | `arr` | `Array` | | 21 | | `...values` | `Array` | | 22 | | `fn` | `(a: any, b: any) => any` | | 23 | 24 | ### Return 25 | 26 | | Type | 27 | | ------- | 28 | | `Array` | 29 | -------------------------------------------------------------------------------- /docs/array/difference.md: -------------------------------------------------------------------------------- 1 | # difference 2 | 3 | Creates an `array` of array values ​​that are not contained in other given arrays. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { difference } from 'rattail' 9 | 10 | difference([1, 2, 3, 4], [2, 3]) 11 | // return [1, 4] 12 | difference([1, 2, 3, 4], [2, 3], [3, 4]) 13 | // return [1] 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ----------- | -------------- | -------- | 20 | | `arr` | `Array` | | 21 | | `...values` | `Array` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | ------- | 27 | | `Array` | 28 | -------------------------------------------------------------------------------- /docs/array/intersection.md: -------------------------------------------------------------------------------- 1 | # intersection 2 | 3 | Creates an `array` of unique values ​​contained in all given arrays. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { intersection } from 'rattail' 9 | 10 | intersection([1, 2, 3, 3], [2, 3, 4]) 11 | // return [2, 3] 12 | intersection([1, 2, 3, 3], [2, 3, 4], [3, 4, 5]) 13 | // return [3] 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ----------- | -------------- | -------- | 20 | | `...values` | `Array` | | 21 | 22 | ### Return 23 | 24 | | Type | 25 | | ------- | 26 | | `Array` | 27 | -------------------------------------------------------------------------------- /docs/array/normalize-to-array.md: -------------------------------------------------------------------------------- 1 | # normalizeToArray 2 | 3 | Converts a value to an `array` if it is not already an array. If the input is an array, it returns the input as-is. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { normalizeToArray } from 'rattail' 9 | 10 | normalizeToArray(5) // return [5] 11 | normalizeToArray([1, 2, 3]) // return [1, 2, 3] 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | ----- | -------- | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | ------- | 24 | | `Array` | 25 | -------------------------------------------------------------------------------- /docs/array/remove-array-blank.md: -------------------------------------------------------------------------------- 1 | # removeArrayBlank 2 | 3 | Removes `null` or `undefined` values from an `array`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { removeArrayBlank } from 'rattail' 9 | 10 | removeArrayBlank([1, null, 2, undefined, 3]) // return [1, 2, 3] 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ----- | ------- | -------- | 17 | | `arr` | `Array` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | ------- | 23 | | `Array` | 24 | -------------------------------------------------------------------------------- /docs/array/remove-array-empty.md: -------------------------------------------------------------------------------- 1 | # removeArrayEmpty 2 | 3 | Removes `null`, `undefined`, or empty string (`''`) values from an `array`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { removeArrayEmpty } from 'rattail' 9 | 10 | removeArrayEmpty([1, null, undefined, '', 3]) // return [1, 3] 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ----- | ------- | -------- | 17 | | `arr` | `Array` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | ------- | 23 | | `Array` | 24 | -------------------------------------------------------------------------------- /docs/array/remove-item.md: -------------------------------------------------------------------------------- 1 | # removeItem 2 | 3 | Removes the first occurrence of a specific item from an `array` and returns the `removed item`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { removeItem } from 'rattail' 9 | 10 | const arr = [1, 2, 3] 11 | removeItem(arr, 2) // arr becomes [1, 3] 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------ | ------- | -------- | 18 | | `arr` | `Array` | | 19 | | `item` | `any` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | ----- | 25 | | `any` | 26 | -------------------------------------------------------------------------------- /docs/array/shuffle.md: -------------------------------------------------------------------------------- 1 | # shuffle 2 | 3 | Randomly shuffles elements within an `array`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { shuffle } from 'rattail' 9 | 10 | shuffle([1, 2, 3]) // return shuffled array 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ----- | ------- | -------- | 17 | | `arr` | `Array` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | ------- | 23 | | `Array` | 24 | -------------------------------------------------------------------------------- /docs/array/toggle-item.md: -------------------------------------------------------------------------------- 1 | # toggleItem 2 | 3 | Adds or removes an item from an `array`, based on its existence in the array. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { toggleItem } from 'rattail' 9 | 10 | const arr = [1, 2] 11 | toggleItem(arr, 2) // arr becomes [1] 12 | toggleItem(arr, 3) // arr becomes [1, 3] 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ------ | ------- | -------- | 19 | | `arr` | `Array` | | 20 | | `item` | `any` | | 21 | 22 | ### Return 23 | 24 | | Type | 25 | | ------- | 26 | | `Array` | 27 | -------------------------------------------------------------------------------- /docs/array/uniq-by.md: -------------------------------------------------------------------------------- 1 | # uniqBy 2 | 3 | Creates a duplicate-free version of an `array`, using a custom comparison function to determine uniqueness. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { uniqBy } from 'rattail' 9 | 10 | uniqBy([{ id: 1 }, { id: 2 }, { id: 1 }], (a, b) => a.id === b.id) 11 | // return [{ id: 1 }, { id: 2 }] 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----- | ------------------------- | -------- | 18 | | `arr` | `Array` | | 19 | | `fn` | `(a: any, b: any) => any` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | ------- | 25 | | `Array` | 26 | -------------------------------------------------------------------------------- /docs/array/uniq.md: -------------------------------------------------------------------------------- 1 | # uniq 2 | 3 | Creates a duplicate-free version of an `array`, using the values equality. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { uniq } from 'rattail' 9 | 10 | uniq([1, 2, 2, 3]) // return [1, 2, 3] 11 | uniq(['a', 'a', 'b', 'c']) // return ['a', 'b', 'c'] 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----- | ------- | -------- | 18 | | `arr` | `Array` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | ------- | 24 | | `Array` | 25 | -------------------------------------------------------------------------------- /docs/array/xor-with.md: -------------------------------------------------------------------------------- 1 | # xorWith 2 | 3 | XOR(Exclusive OR) the passed array and return a new `array`, and supports custom comparison functions. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { xorWith } from 'rattail' 9 | 10 | xorWith([{ num: 1 }, { num: 2 }, { num: 2 }], [{ num: 1 }, { num: 3 }], (a, b) => a.num === b.num) 11 | // return [{ num: 2 }, { num: 3 }] 12 | xorWith([{ num: 1 }, { num: 2 }], [{ num: 1 }, { num: 2 }], [{ num: 3 }], (a, b) => a.num === b.num) 13 | // return [{ num: 3 }] 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ----------- | ------------------------- | -------- | 20 | | `...values` | `Array` | | 21 | | `fn` | `(a: any, b: any) => any` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | ------- | 27 | | `Array` | 28 | -------------------------------------------------------------------------------- /docs/array/xor.md: -------------------------------------------------------------------------------- 1 | # xor 2 | 3 | XOR(Exclusive OR) the passed array and return a new `array`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { xor } from 'rattail' 9 | 10 | xor([1, 2, 2], [1, 3]) 11 | // return [2, 3] 12 | xor([1, 2], [1, 2], [3]) 13 | // return [3] 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ----------- | -------------- | -------- | 20 | | `...values` | `Array` | | 21 | 22 | ### Return 23 | 24 | | Type | 25 | | ------- | 26 | | `Array` | 27 | -------------------------------------------------------------------------------- /docs/collection/clone-deep-with.md: -------------------------------------------------------------------------------- 1 | # cloneDeepWith 2 | 3 | Create a deep clone of a value, applying a custom function for cloning on each value. The function will process objects with various types. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { cloneDeepWith, isNumber } from 'rattail' 9 | 10 | const original = { a: 1, b: { c: 2 } } 11 | const value = cloneDeepWith(original, (val) => { 12 | if (isNumber(val)) { 13 | return val * 2 14 | } 15 | }) 16 | // value is { a: 2, b: { c: 4 } } 17 | ``` 18 | 19 | ### Arguments 20 | 21 | | Arg | Type | Defaults | 22 | | ------- | :-------------------: | -------: | 23 | | `value` | `any` | | 24 | | `fn` | `(value: any) => any` | | 25 | 26 | ### Return 27 | 28 | | Type | 29 | | :---: | 30 | | `any` | 31 | -------------------------------------------------------------------------------- /docs/collection/clone-deep.md: -------------------------------------------------------------------------------- 1 | # cloneDeep 2 | 3 | Create a deep clone of a value. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { cloneDeep } from 'rattail' 9 | 10 | const original = { a: 1, b: { c: 2 } } 11 | const value = cloneDeep(original) 12 | // value is { a: 1, b: { c: 2 } } 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ------- | :---: | -------: | 19 | | `value` | `any` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :---: | 25 | | `any` | 26 | -------------------------------------------------------------------------------- /docs/collection/merge.md: -------------------------------------------------------------------------------- 1 | # merge 2 | 3 | Merge two objects recursively. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { merge } from 'rattail' 9 | 10 | merge({ a: 1, b: { c: 2 } }, { b: { d: 3 }, e: 4 }) 11 | // return { a: 1, b: { c: 2, d: 3 }, e: 4 } 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------------ | ---------- | -------- | 18 | | `object` | `object` | | 19 | | `...sources` | `object[]` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | -------- | 25 | | `object` | 26 | -------------------------------------------------------------------------------- /docs/file/to-array-buffer.md: -------------------------------------------------------------------------------- 1 | # toArrayBuffer 2 | 3 | Converts a `File` object to an `ArrayBuffer`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { toArrayBuffer } from 'rattail' 9 | 10 | await toArrayBuffer(new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' })) 11 | // return ArrayBuffer 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------ | ------ | -------- | 18 | | `file` | `File` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | ---------------------- | 24 | | `Promise` | 25 | -------------------------------------------------------------------------------- /docs/file/to-data-url.md: -------------------------------------------------------------------------------- 1 | # toDataURL 2 | 3 | Converts a `File` object to a Data URL string. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { toDataURL } from 'rattail' 9 | 10 | await toDataURL(new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' })) 11 | // return 'data:text/plain;base64,SGVsbG8sIHdvcmxkIQ==' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------ | ------ | -------- | 18 | | `file` | `File` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | ----------------- | 24 | | `Promise` | 25 | -------------------------------------------------------------------------------- /docs/file/to-text.md: -------------------------------------------------------------------------------- 1 | # toText 2 | 3 | Converts a `File` object to a text string. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { toText } from 'rattail' 9 | 10 | await toText(new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' })) 11 | // return 'Hello, world!' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------ | ------ | -------- | 18 | | `file` | `File` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | ----------------- | 24 | | `Promise` | 25 | -------------------------------------------------------------------------------- /docs/function/call.md: -------------------------------------------------------------------------------- 1 | # call 2 | 3 | Call a single function or multiple functions (passed as an array) and pass arguments to them. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { call } from 'rattail' 9 | 10 | call((a, b) => a + b, 1, 2) 11 | // return 3 12 | call([(a, b) => a + b, (a, b) => a + b], 1, 2) 13 | // return [3, 3] 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | --------- | :----------------------: | -------: | 20 | | `fn` | `Function \| Function[]` | | 21 | | `...args` | `any[]` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | :--------: | 27 | | `Function` | 28 | -------------------------------------------------------------------------------- /docs/function/debounce.md: -------------------------------------------------------------------------------- 1 | # debounce 2 | 3 | Create a `debounce` function that delays the execution of the fn method by `delay` milliseconds after the last call. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { debounce } from 'rattail' 9 | 10 | const debouncedFn = debounce(() => { 11 | // do something 12 | }, 1000) 13 | 14 | window.addEventListener('resize', debouncedFn) 15 | ``` 16 | 17 | ### Arguments 18 | 19 | | Arg | Type | Defaults | 20 | | ------- | :--------: | -------: | 21 | | `fn` | `Function` | | 22 | | `delay` | `number` | `0` | 23 | 24 | ### Return 25 | 26 | | Type | 27 | | :--------: | 28 | | `Function` | 29 | -------------------------------------------------------------------------------- /docs/function/noop.md: -------------------------------------------------------------------------------- 1 | # NOOP 2 | 3 | This method returns `undefined`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { NOOP } from 'rattail' 9 | 10 | NOOP() // return undefined 11 | ``` 12 | 13 | ### Return 14 | 15 | | Type | 16 | | :---------: | 17 | | `undefined` | 18 | -------------------------------------------------------------------------------- /docs/function/once.md: -------------------------------------------------------------------------------- 1 | # once 2 | 3 | Creates a function that will only execute once. Subsequent calls return the result of the first invocation. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { once } from 'rattail' 9 | 10 | const fn = once(() => 'initialized') 11 | fn() // return 'initialized' 12 | fn() // return 'initialized' 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ---- | :--------: | -------: | 19 | | `fn` | `Function` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :--------: | 25 | | `Function` | 26 | -------------------------------------------------------------------------------- /docs/function/throttle.md: -------------------------------------------------------------------------------- 1 | # throttle 2 | 3 | Create a throttle function that calls `fn` at most once every `delay` milliseconds. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { throttle } from 'rattail' 9 | 10 | const throttledFn = throttle(() => { 11 | // do something, it will be called at most 1 time per second 12 | }, 1000) 13 | 14 | window.addEventListener('resize', throttledFn) 15 | ``` 16 | 17 | ### Arguments 18 | 19 | | Arg | Type | Defaults | 20 | | ------- | :--------: | -------: | 21 | | `fn` | `Function` | | 22 | | `delay` | `number` | `200` | 23 | 24 | ### Return 25 | 26 | | Type | 27 | | :--------: | 28 | | `Function` | 29 | -------------------------------------------------------------------------------- /docs/general/assert.md: -------------------------------------------------------------------------------- 1 | # assert 2 | 3 | Throws an error when the input value is not `true`, the second argument is the error message. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { assert } from 'rattail' 9 | 10 | const count = 99 11 | assert(count < 100, 'error message') 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----------- | :-------: | -------: | 18 | | `condition` | `boolean` | | 19 | | `message` | `string` | | 20 | -------------------------------------------------------------------------------- /docs/general/get-global-this.md: -------------------------------------------------------------------------------- 1 | # getGlobalThis 2 | 3 | Retrieve the global object based on the current environment. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { getGlobalThis } from 'rattail' 9 | 10 | getGlobalThis() 11 | // returns `window` in browser, `global` in Node.js, 12 | // or `self` in web worker 13 | ``` 14 | 15 | ### Return 16 | 17 | | Type | 18 | | :-----------------: | 19 | | `typeof globalThis` | 20 | -------------------------------------------------------------------------------- /docs/general/has-own.md: -------------------------------------------------------------------------------- 1 | # hasOwn 2 | 3 | Determine whether an `object` has a specific property as its own (not inherited). 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { hasOwn } from 'rattail' 9 | 10 | const obj = { foo: 123 } 11 | hasOwn(obj, 'foo') // return true 12 | hasOwn(obj, 'bar') // return false 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ------- | :------: | -------: | 19 | | `value` | `object` | | 20 | | `key` | `string` | | 21 | 22 | ### Return 23 | 24 | | Type | 25 | | :-------: | 26 | | `boolean` | 27 | -------------------------------------------------------------------------------- /docs/general/in-browser.md: -------------------------------------------------------------------------------- 1 | # inBrowser 2 | 3 | Determine whether the code is running in a `browser` environment. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { inBrowser } from 'rattail' 9 | 10 | inBrowser() // return true in browser 11 | ``` 12 | 13 | ### Return 14 | 15 | | Type | 16 | | :-------: | 17 | | `boolean` | 18 | -------------------------------------------------------------------------------- /docs/general/in-mobile.md: -------------------------------------------------------------------------------- 1 | # inMobile 2 | 3 | Determine whether the code is running in a `mobile` browser environment. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { inMobile } from 'rattail' 9 | 10 | inMobile() // return true if in mobile browser, false otherwise 11 | ``` 12 | 13 | ### Return 14 | 15 | | Type | 16 | | :-------: | 17 | | `boolean` | 18 | -------------------------------------------------------------------------------- /docs/general/is-array-buffer.md: -------------------------------------------------------------------------------- 1 | # isArrayBuffer 2 | 3 | Determine whether the input value is a `ArrayBuffer`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isArrayBuffer } from 'rattail' 9 | 10 | isArrayBuffer(new ArrayBuffer(8)) // return true 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ------- | :---: | -------: | 17 | | `value` | `any` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/general/is-array.md: -------------------------------------------------------------------------------- 1 | # isArray 2 | 3 | Determine whether the input value is an `array`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isArray } from 'rattail' 9 | 10 | isArray([]) // return true 11 | isArray({}) // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-blob.md: -------------------------------------------------------------------------------- 1 | # isBlob 2 | 3 | Determine whether the input value is a `Blob`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isBlob } from 'rattail' 9 | 10 | isBlob(new Blob(['Hello, World!'], { type: 'text/plain' })) // return true 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ------- | :---: | -------: | 17 | | `value` | `any` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/general/is-boolean.md: -------------------------------------------------------------------------------- 1 | # isBoolean 2 | 3 | Determine whether the input value is a `boolean`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isBoolean } from 'rattail' 9 | 10 | isBoolean(true) // return true 11 | isBoolean('rattail') // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-data-view.md: -------------------------------------------------------------------------------- 1 | # isDataView 2 | 3 | Determine whether the input value is a `DataView`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isDataView } from 'rattail' 9 | 10 | isDataView(new DataView(new ArrayBuffer(1))) // return true 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ------- | :---: | -------: | 17 | | `value` | `any` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/general/is-date.md: -------------------------------------------------------------------------------- 1 | # isDate 2 | 3 | Determine whether the input value is a `Date`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isDate } from 'rattail' 9 | 10 | isDate(new Date()) // return true 11 | isDate('2024-01-01') // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-dom-exception.md: -------------------------------------------------------------------------------- 1 | # isDOMException 2 | 3 | Determine whether the input value is a `DOMException` object. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isDOMException } from 'rattail' 9 | 10 | isDOMException(new DOMException('An error occurred')) // return true 11 | isDOMException(new Error('An error occurred')) // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----- | :---: | -------: | 18 | | `val` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-empty-plain-object.md: -------------------------------------------------------------------------------- 1 | # isEmptyPlainObject 2 | 3 | Determine whether the input value is a empty(No own enumerable keys and no symbols) plain object. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isEmptyPlainObject } from 'rattail' 9 | 10 | isEmptyPlainObject({}) // return true 11 | isEmptyPlainObject(Object.create(null)) // return true 12 | isEmptyPlainObject([]) // return false 13 | isEmptyPlainObject({ a: 1 }) // return false 14 | isEmptyPlainObject({ [Symbol()]: 1 }) // return false 15 | ``` 16 | 17 | ### Arguments 18 | 19 | | Arg | Type | Defaults | 20 | | ------- | :---: | -------: | 21 | | `value` | `any` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | :-------: | 27 | | `boolean` | 28 | -------------------------------------------------------------------------------- /docs/general/is-empty.md: -------------------------------------------------------------------------------- 1 | # isEmpty 2 | 3 | Determine whether the input value is empty (`undefined`, `null`, an `empty string`, or an `empty array`). 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isEmpty } from 'rattail' 9 | 10 | isEmpty(null) // return true 11 | isEmpty('') // return true 12 | isEmpty([]) // return true 13 | isEmpty([1, 2, 3]) // return false 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ------- | :---: | -------: | 20 | | `value` | `any` | | 21 | 22 | ### Return 23 | 24 | | Type | 25 | | :-------: | 26 | | `boolean` | 27 | -------------------------------------------------------------------------------- /docs/general/is-equal-with.md: -------------------------------------------------------------------------------- 1 | # isEqualWith 2 | 3 | Deeply compare two values. Supports passing a comparison method, and returns `true` if the two values ​​are equal. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isEqualWith, isObject } from 'rattail' 9 | 10 | isEqualWith([1, 2], ['1', '2'], (v1, v2) => { 11 | if (!isObject(v1) && !isObject(v2)) { 12 | return String(v1) === String(v2) 13 | } 14 | }) 15 | // return true 16 | ``` 17 | 18 | ### Arguments 19 | 20 | | Arg | Type | Defaults | 21 | | ------- | :---------------------: | -------: | 22 | | `value` | `any` | | 23 | | `other` | `any` | | 24 | | `fn` | `(value, other) => any` | | 25 | 26 | ### Return 27 | 28 | | Type | 29 | | :-------: | 30 | | `boolean` | 31 | -------------------------------------------------------------------------------- /docs/general/is-equal.md: -------------------------------------------------------------------------------- 1 | # isEqual 2 | 3 | Deeply compare two values. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isEqual } from 'rattail' 9 | 10 | isEqual({ n: 1 }, { n: 1 }) 11 | // return true 12 | isEqual([1, 2, 3], [1, 2, 3]) 13 | // return true 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ------- | :---: | -------: | 20 | | `value` | `any` | | 21 | | `other` | `any` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | :-------: | 27 | | `boolean` | 28 | -------------------------------------------------------------------------------- /docs/general/is-error.md: -------------------------------------------------------------------------------- 1 | # isError 2 | 3 | Determine whether the input value is an `Error` object. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isError } from 'rattail' 9 | 10 | isError(new Error('message')) // return true 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ----- | :---: | -------: | 17 | | `val` | `any` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/general/is-file.md: -------------------------------------------------------------------------------- 1 | # isFile 2 | 3 | Determine whether the input value is a `File`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isFile } from 'rattail' 9 | 10 | isFile(new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' })) 11 | // return true 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-function.md: -------------------------------------------------------------------------------- 1 | # isFunction 2 | 3 | Determine whether the input value is a `function`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isFunction } from 'rattail' 9 | 10 | isFunction(() => {}) // return true 11 | isFunction(123) // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-map.md: -------------------------------------------------------------------------------- 1 | # isMap 2 | 3 | Determine whether the input value is a `Map`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isMap } from 'rattail' 9 | 10 | isMap(new Map()) // return true 11 | isMap({}) // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-non-empty-array.md: -------------------------------------------------------------------------------- 1 | # isNonEmptyArray 2 | 3 | Determine whether the input value is a `non-empty array`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isNonEmptyArray } from 'rattail' 9 | 10 | isNonEmptyArray([1, 2, 3]) // return true 11 | isNonEmptyArray([]) // return false 12 | isNonEmptyArray(1) // return false 13 | isNonEmptyArray(null) // return false 14 | isNonEmptyArray(undefined) // return false 15 | ``` 16 | 17 | ### Arguments 18 | 19 | | Arg | Type | Defaults | 20 | | ------- | :---: | -------: | 21 | | `value` | `any` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | :-------: | 27 | | `boolean` | 28 | -------------------------------------------------------------------------------- /docs/general/is-nullish.md: -------------------------------------------------------------------------------- 1 | # isNullish 2 | 3 | Determine whether the input value is `null` or `undefined`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isNullish } from 'rattail' 9 | 10 | isNullish(null) // return true 11 | isNullish(undefined) // return true 12 | isNullish(123) // return false 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ------- | :---: | -------: | 19 | | `value` | `any` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :-------: | 25 | | `boolean` | 26 | -------------------------------------------------------------------------------- /docs/general/is-number.md: -------------------------------------------------------------------------------- 1 | # isNumber 2 | 3 | Determine whether the input value is a `number`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isNumber } from 'rattail' 9 | 10 | isNumber(123) // return true 11 | isNumber('rattail') // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-numeric.md: -------------------------------------------------------------------------------- 1 | # isNumeric 2 | 3 | Determine whether the input value is a `number` or a `numeric string`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isNumeric } from 'rattail' 9 | 10 | isNumeric(123) // return true 11 | isNumeric('456') // return true 12 | isNumeric('rattail') // return false 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ------- | :---: | -------: | 19 | | `value` | `any` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :-------: | 25 | | `boolean` | 26 | -------------------------------------------------------------------------------- /docs/general/is-object.md: -------------------------------------------------------------------------------- 1 | # isObject 2 | 3 | Determine whether the input value is an `object` (excluding `null`). 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isObject } from 'rattail' 9 | 10 | isObject({}) // return true 11 | isObject([]) // return true 12 | isObject(null) // return false 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ------- | :---: | -------: | 19 | | `value` | `any` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :-------: | 25 | | `boolean` | 26 | -------------------------------------------------------------------------------- /docs/general/is-plain-object.md: -------------------------------------------------------------------------------- 1 | # isPlainObject 2 | 3 | Determine whether the input value is a `plain object`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isPlainObject } from 'rattail' 9 | 10 | isPlainObject({}) // return true 11 | isPlainObject([]) // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-primitive.md: -------------------------------------------------------------------------------- 1 | # isPrimitive 2 | 3 | Determine whether the input value is a `primitive`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isPrimitive } from 'rattail' 9 | 10 | isPrimitive(1) // return true 11 | isPrimitive('1') // return true 12 | isPrimitive(null) // return true 13 | isPrimitive(undefined) // return true 14 | isPrimitive(true) // return true 15 | isPrimitive(Symbol('1')) // return true 16 | isPrimitive(1n) // return true 17 | isPrimitive({}) // return false 18 | isPrimitive([]) // return false 19 | isPrimitive(new Date()) // return false 20 | ``` 21 | 22 | ### Arguments 23 | 24 | | Arg | Type | Defaults | 25 | | ------- | :---: | -------: | 26 | | `value` | `any` | | 27 | 28 | ### Return 29 | 30 | | Type | 31 | | :-------: | 32 | | `boolean` | 33 | -------------------------------------------------------------------------------- /docs/general/is-promise.md: -------------------------------------------------------------------------------- 1 | # isPromise 2 | 3 | Determine whether the input value is a `Promise`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isPromise } from 'rattail' 9 | 10 | isPromise(Promise.resolve()) // return true 11 | isPromise({}) // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-reg-exp.md: -------------------------------------------------------------------------------- 1 | # isRegExp 2 | 3 | Determine whether the input value is a `RegExp`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isRegExp } from 'rattail' 9 | 10 | isRegExp(/abc/) // return true 11 | isRegExp('abc') // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-set.md: -------------------------------------------------------------------------------- 1 | # isSet 2 | 3 | Determine whether the input value is a `Set`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isSet } from 'rattail' 9 | 10 | isSet(new Set()) // return true 11 | isSet({}) // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-string.md: -------------------------------------------------------------------------------- 1 | # isString 2 | 3 | Determine whether the input value is a `string`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isString } from 'rattail' 9 | 10 | isString('rattail') // return true 11 | isString(123) // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-symbol.md: -------------------------------------------------------------------------------- 1 | # isSymbol 2 | 3 | Determine whether the input value is a `symbol`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isSymbol } from 'rattail' 9 | 10 | isSymbol(Symbol('test')) // return true 11 | isSymbol('rattail') // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/is-truthy.md: -------------------------------------------------------------------------------- 1 | # isTruthy 2 | 3 | Determine whether the input value is `truthy`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isTruthy } from 'rattail' 9 | 10 | isTruthy(1) // return true 11 | isTruthy([]) // return true 12 | isTruthy({}) // return true 13 | isTruthy(0) // return false 14 | isTruthy('') // return false 15 | isTruthy(null) // return false 16 | isTruthy(undefined) // return false 17 | ``` 18 | 19 | ### Arguments 20 | 21 | | Arg | Type | Defaults | 22 | | ------- | :---: | -------: | 23 | | `value` | `any` | | 24 | 25 | ### Return 26 | 27 | | Type | 28 | | :-------: | 29 | | `boolean` | 30 | -------------------------------------------------------------------------------- /docs/general/is-typed-array.md: -------------------------------------------------------------------------------- 1 | # isTypedArray 2 | 3 | Determine whether the input value is a `TypedArray`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isTypedArray } from 'rattail' 9 | 10 | isTypedArray(new Int8Array(8)) // return true 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ------- | :---: | -------: | 17 | | `value` | `any` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/general/is-weak-map.md: -------------------------------------------------------------------------------- 1 | # isWeakMap 2 | 3 | Determine whether the input value is a `WeakMap`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isWeakMap } from 'rattail' 9 | 10 | isWeakMap(new WeakMap()) // return true 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ------- | :---: | -------: | 17 | | `value` | `any` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/general/is-weak-set.md: -------------------------------------------------------------------------------- 1 | # isWeakSet 2 | 3 | Determine whether the input value is a `WeakSet`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { WeakSet } from 'rattail' 9 | 10 | isWeakMap(new WeakSet()) // return true 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ------- | :---: | -------: | 17 | | `value` | `any` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/general/is-window.md: -------------------------------------------------------------------------------- 1 | # isWindow 2 | 3 | Determine whether the input value is the global `window` object. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { isWindow } from 'rattail' 9 | 10 | isWindow(window) // return true 11 | isWindow({}) // return false 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/general/support-touch.md: -------------------------------------------------------------------------------- 1 | # supportTouch 2 | 3 | Determine whether the current environment supports `touch events`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { supportTouch } from 'rattail' 9 | 10 | supportTouch() // return true if touch events are supported, false otherwise 11 | ``` 12 | 13 | ### Return 14 | 15 | | Type | 16 | | :-------: | 17 | | `boolean` | 18 | -------------------------------------------------------------------------------- /docs/general/to-raw-type.md: -------------------------------------------------------------------------------- 1 | # toRawType 2 | 3 | Return the `raw type` of the input value. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { toRawType } from 'rattail' 9 | 10 | toRawType({}) // return 'Object' 11 | toRawType([]) // return 'Array' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/general/to-type-string.md: -------------------------------------------------------------------------------- 1 | # toTypeString 2 | 3 | Return the `type string` of the input value. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { toTypeString } from 'rattail' 9 | 10 | toTypeString({}) // return '[object Object]' 11 | toTypeString([]) // return '[object Array]' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :---: | -------: | 18 | | `value` | `any` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/getting-started.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ## Overview 4 | 5 | `Rattail` is a utilities library for front-end developers, `lightweight` and `ts-friendly`. 6 | 7 | ### Installation 8 | 9 | ::: code-group 10 | 11 | ```shell [npm] 12 | npm i rattail -S 13 | ``` 14 | 15 | ```shell [yarn] 16 | yarn add rattail 17 | ``` 18 | 19 | ```shell [pnpm] 20 | pnpm add rattail 21 | ``` 22 | 23 | ::: 24 | 25 | ### Usage 26 | 27 | ```ts 28 | import { isString } from 'rattail' 29 | 30 | console.log(isString('rattail')) 31 | ``` 32 | 33 | ### Why not Lodash? 34 | 35 | `Rattail` is not a replacement for [Lodash](https://lodash.com/) nor a functional programming solution. Rattail aims to provide practical tools for more application scenarios. 36 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | hero: 5 | name: 'Rattail' 6 | text: 'A Utilities Library' 7 | tagline: A utilities library for front-end developers, lightweight and ts-friendly 8 | logo: /logo.svg 9 | image: 10 | src: /logo.svg 11 | actions: 12 | - theme: brand 13 | text: Get Started 14 | link: /getting-started 15 | - theme: alt 16 | text: View On Github 17 | link: https://github.com/varletjs/rattail 18 | 19 | features: 20 | - title: General 21 | details: Provide utilities frequently used in daily development 22 | - title: Tests Coverage 23 | details: Make sure more than 99% unit test coverage, providing stability assurance 24 | - title: Lightweight 25 | details: Utilities implementation is very lightweight 26 | - title: Ts-friendly 27 | details: Written based on ts, providing complete ts types 28 | --- 29 | -------------------------------------------------------------------------------- /docs/math/ceil.md: -------------------------------------------------------------------------------- 1 | # ceil 2 | 3 | Return number rounded up to precision. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { ceil } from 'rattail' 9 | 10 | ceil(1.004) // return 2 11 | ceil(1.004, 2) // return 1.01 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----------- | :------: | -------: | 18 | | `val` | `number` | | 19 | | `precision` | `number` | `0` | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :------: | 25 | | `number` | 26 | -------------------------------------------------------------------------------- /docs/math/floor.md: -------------------------------------------------------------------------------- 1 | # floor 2 | 3 | Return number rounded down to precision. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { floor } from 'rattail' 9 | 10 | floor(1.005) // return 1 11 | floor(1.0015, 3) // return 1.001 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----------- | :------: | -------: | 18 | | `val` | `number` | | 19 | | `precision` | `number` | `0` | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :------: | 25 | | `number` | 26 | -------------------------------------------------------------------------------- /docs/math/max-by.md: -------------------------------------------------------------------------------- 1 | # maxBy 2 | 3 | Find the maximum value in an array based on the result of applying a function to each element. If the array is empty, `undefined` is returned. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { maxBy } from 'rattail' 9 | 10 | maxBy([{ n: 5 }, { n: 10 }, { n: 8 }], ({ n }) => n) 11 | // return { n: 10 } 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----- | :------------------: | -------: | 18 | | `arr` | `T[]` | | 19 | | `fn` | `(val: T) => number` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :---------------: | 25 | | `T \| undefined` | 26 | -------------------------------------------------------------------------------- /docs/math/mean-by.md: -------------------------------------------------------------------------------- 1 | # meanBy 2 | 3 | Calculate the mean (average) of an `array` by applying a function to each element to derive a numeric value. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { meanBy } from 'rattail' 9 | 10 | meanBy([{ n: 4 }, { n: 6 }, { n: 8 }], ({ n }) => n) 11 | // return 6 12 | meanBy([10, 20, 30], (n) => n / 2) 13 | // return 10 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ----- | :------------------: | -------: | 20 | | `arr` | `T[]` | | 21 | | `fn` | `(val: T) => number` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | :------: | 27 | | `number` | 28 | -------------------------------------------------------------------------------- /docs/math/mean.md: -------------------------------------------------------------------------------- 1 | # mean 2 | 3 | Calculate the `mean` (average) of an `array` of `numbers`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { mean } from 'rattail' 9 | 10 | mean([1, 2, 3, 4, 5]) // return 3 11 | mean([10, 20, 30]) // return 20 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----- | :--------: | -------: | 18 | | `arr` | `number[]` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :------: | 24 | | `number` | 25 | -------------------------------------------------------------------------------- /docs/math/min-by.md: -------------------------------------------------------------------------------- 1 | # minBy 2 | 3 | Find the `minimum` value in an `array` based on the result of applying a function to each element. If the array is empty, `undefined` is returned. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { minBy } from 'rattail' 9 | 10 | minBy([{ n: 5 }, { n: 2 }, { n: 8 }], ({ n }) => n) 11 | // return { n: 2 } 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----- | :------------------: | -------: | 18 | | `arr` | `T[]` | | 19 | | `fn` | `(val: T) => number` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :---------------: | 25 | | `T \| undefined` | 26 | -------------------------------------------------------------------------------- /docs/math/round.md: -------------------------------------------------------------------------------- 1 | # round 2 | 3 | Return number rounded to precision. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { round } from 'rattail' 9 | 10 | round(1.005) // return 1 11 | round(1.005, 2) // return 1.01 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----------- | :------: | -------: | 18 | | `val` | `number` | | 19 | | `precision` | `number` | `0` | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :------: | 25 | | `number` | 26 | -------------------------------------------------------------------------------- /docs/math/sample.md: -------------------------------------------------------------------------------- 1 | # sample 2 | 3 | Return a random element from an `array`. If the array is empty, `undefined` is returned. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { sample } from 'rattail' 9 | 10 | sample([1, 2, 3, 4, 5]) // returns a random element, e.g., 3 11 | sample([]) // returns undefined 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----- | :---: | -------: | 18 | | `arr` | `T[]` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :---------------: | 24 | | `T \| undefined` | 25 | -------------------------------------------------------------------------------- /docs/math/sum-by.md: -------------------------------------------------------------------------------- 1 | # sumBy 2 | 3 | Calculates the sum of values in an `array` based on a provided function. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { sumBy } from 'rattail' 9 | 10 | sumBy([{ n: 1 }, { n: 2 }, { n: 3 }], ({ n }) => n) // return 6 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ----- | ---------------------- | -------- | 17 | | `arr` | `Array` | | 18 | | `fn` | `(val: any) => number` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | -------- | 24 | | `number` | 25 | -------------------------------------------------------------------------------- /docs/math/sum-hash.md: -------------------------------------------------------------------------------- 1 | # sumHash 2 | 3 | Calculate a hash sum for a given value. The hash is generated based on the value's properties and content, and it returns a hexadecimal string representation of the hash. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { sumHash } from 'rattail' 9 | 10 | sumHash('123') 11 | // return '1a3a267c' 12 | sumHash({ a: '123' }) 13 | // return 'b1c920ac' 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ------- | :---: | -------: | 20 | | `value` | `any` | | 21 | 22 | ### Return 23 | 24 | | Type | 25 | | :------: | 26 | | `string` | 27 | -------------------------------------------------------------------------------- /docs/math/sum.md: -------------------------------------------------------------------------------- 1 | # sum 2 | 3 | Calculates the sum of values in an `array` of numbers. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { sum } from 'rattail' 9 | 10 | sum([1, 2, 3]) // return 6 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ----- | ---------- | -------- | 17 | | `arr` | `number[]` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | -------- | 23 | | `number` | 24 | -------------------------------------------------------------------------------- /docs/number/clamp-array-range.md: -------------------------------------------------------------------------------- 1 | # clampArrayRange 2 | 3 | Clamp an index within the bounds of an array's length. Ensures the index is at least `0` and at most `arr.length - 1`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { clampArrayRange } from 'rattail' 9 | 10 | const arr = ['a', 'b', 'c'] 11 | clampArrayRange(1, arr) // return 1 12 | clampArrayRange(-1, arr) // return 0 13 | clampArrayRange(5, arr) // return 2 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ------- | :------: | -------: | 20 | | `index` | `number` | | 21 | | `arr` | `Array` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | :------: | 27 | | `number` | 28 | -------------------------------------------------------------------------------- /docs/number/clamp.md: -------------------------------------------------------------------------------- 1 | # clamp 2 | 3 | Clamp a number within the inclusive `min` and `max` bounds. If the number is less than `min`, it returns `min`; if it's greater than `max`, it returns `max`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { clamp } from 'rattail' 9 | 10 | clamp(5, 1, 10) // return 5 11 | clamp(0, 1, 10) // return 1 12 | clamp(15, 1, 10) // return 10 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ----- | :------: | -------: | 19 | | `num` | `number` | | 20 | | `min` | `number` | | 21 | | `max` | `number` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | :------: | 27 | | `number` | 28 | -------------------------------------------------------------------------------- /docs/number/delay.md: -------------------------------------------------------------------------------- 1 | # delay 2 | 3 | Create a promise that resolves after a specified time in milliseconds. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { delay } from 'rattail' 9 | 10 | console.log('Start') 11 | await delay(1000) 12 | console.log('End after 1 second') 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ----------- | :------: | -------: | 19 | | `time (ms)` | `number` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :-------------: | 25 | | `Promise` | 26 | -------------------------------------------------------------------------------- /docs/number/gen-number-key.md: -------------------------------------------------------------------------------- 1 | # genNumberKey 2 | 3 | Generate a unique numeric key, `incrementing` with each call. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { genNumberKey } from 'rattail' 9 | 10 | genNumberKey() // return 0 11 | genNumberKey() // return 1 12 | genNumberKey() // return 2 13 | ``` 14 | 15 | ### Return 16 | 17 | | Type | 18 | | :------: | 19 | | `number` | 20 | -------------------------------------------------------------------------------- /docs/number/random-number.md: -------------------------------------------------------------------------------- 1 | # randomNumber 2 | 3 | Generate a random integer between `min` and `max`, inclusive. If no values are provided, it defaults to a range of `0` to `100`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { randomNumber } from 'rattail' 9 | 10 | randomNumber(1, 10) // return a random integer between 1 and 10 11 | randomNumber() // return 0 or 100 (default range) 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ----- | :------: | -------: | 18 | | `min` | `number` | `0` | 19 | | `max` | `number` | `100` | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :------: | 25 | | `number` | 26 | -------------------------------------------------------------------------------- /docs/number/times.md: -------------------------------------------------------------------------------- 1 | # times 2 | 3 | Execute a function a specified number of times and return an array of results. Each call to the function is provided with the current index. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { times } from 'rattail' 9 | 10 | times(3, (index) => index * 2) 11 | // returns [0, 2, 4] 12 | times(5, (index) => `Item ${index}`) 13 | // returns ['Item 0', 'Item 1', 'Item 2', 'Item 3', 'Item 4'] 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ----- | :----------------------: | -------: | 20 | | `num` | `number` | | 21 | | `fn` | `(index: number) => any` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | :-----: | 27 | | `Array` | 28 | -------------------------------------------------------------------------------- /docs/number/to-number.md: -------------------------------------------------------------------------------- 1 | # toNumber 2 | 3 | Convert the input value to a `number`. If the value is `null` or `undefined`, it returns `0`. If the value is a boolean, it converts `true` to `1` and `false` to `0`. If the value is a string that cannot be parsed as a number, it returns `0`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { toNumber } from 'rattail' 9 | 10 | toNumber('123') // return 123 11 | toNumber(true) // return 1 12 | toNumber(false) // return 0 13 | toNumber('abc') // return 0 14 | toNumber(null) // return 0 15 | ``` 16 | 17 | ### Arguments 18 | 19 | | Arg | Type | Defaults | 20 | | ------- | :---: | -------: | 21 | | `value` | `any` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | :------: | 27 | | `number` | 28 | -------------------------------------------------------------------------------- /docs/object/omit-by.md: -------------------------------------------------------------------------------- 1 | # omitBy 2 | 3 | Excludes an object property by providing a function that constructs a new object. Returns a `truthy` value to indicate that the property should be excluded. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { omitBy } from 'rattail' 9 | 10 | omitBy({ a: 1, b: 2, c: 3 }, (value) => value > 1) 11 | // return { a: 1 } 12 | omitBy({ a: 1, b: 2, c: 3 }, (value, key) => key !== 'a') 13 | // return { a: 1 } 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | -------- | ---------------------------------- | -------- | 20 | | `object` | `object` | | 21 | | `fn` | `(value: any, key: string) => any` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | -------- | 27 | | `object` | 28 | -------------------------------------------------------------------------------- /docs/object/omit.md: -------------------------------------------------------------------------------- 1 | # omit 2 | 3 | Excludes object properties and constructs a new object. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { omit } from 'rattail' 9 | 10 | omit({ a: 1, b: 2, c: 3 }, ['a', 'c']) 11 | // return { b: 2 } 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | -------- | ---------- | -------- | 18 | | `object` | `object` | | 19 | | `keys` | `string[]` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | -------- | 25 | | `object` | 26 | -------------------------------------------------------------------------------- /docs/object/pick-by.md: -------------------------------------------------------------------------------- 1 | # pickBy 2 | 3 | By providing a function to extract object properties and construct a new object, returning a `truthy` value indicates that the property needs to be extracted. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { pickBy } from 'rattail' 9 | 10 | pickBy({ a: 1, b: 2, c: 3 }, (value) => value > 1) 11 | // return { b: 2, c: 3 } 12 | pickBy({ a: 1, b: 2, c: 3 }, (value, key) => key !== 'a') 13 | // return { b: 2, c: 3 } 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | -------- | ---------------------------------- | -------- | 20 | | `object` | `object` | | 21 | | `fn` | `(value: any, key: string) => any` | | 22 | 23 | ### Return 24 | 25 | | Type | 26 | | -------- | 27 | | `object` | 28 | -------------------------------------------------------------------------------- /docs/object/pick.md: -------------------------------------------------------------------------------- 1 | # pick 2 | 3 | Pick object properties and construct a new object. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { pick } from 'rattail' 9 | 10 | pick({ a: 1, b: 2, c: 3 }, ['a', 'c']) 11 | // return { a: 1, c: 3 } 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | -------- | ---------- | -------- | 18 | | `object` | `object` | | 19 | | `keys` | `string[]` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | -------- | 25 | | `object` | 26 | -------------------------------------------------------------------------------- /docs/object/promise-with-resolvers.md: -------------------------------------------------------------------------------- 1 | # promiseWithResolvers 2 | 3 | returns an object containing a new Promise object and two functions to `resolve` or `reject` it, corresponding to the two parameters passed to the executor of the `Promise()` constructor. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { promiseWithResolvers } from 'rattail' 9 | 10 | const { promise, resolve } = promiseWithResolvers() 11 | 12 | setTimeout(() => { 13 | resolve('hello') 14 | }, 300) 15 | 16 | await promise 17 | // after 300ms return 'hello' 18 | ``` 19 | 20 | ### Return 21 | 22 | | Type | 23 | | ------------------------------------------------------------------------------------------ | 24 | | `{ promise: Promise; resolve: (value: any) => void; reject: (reason?: any) => void }` | 25 | -------------------------------------------------------------------------------- /docs/string/camelize.md: -------------------------------------------------------------------------------- 1 | # camelize 2 | 3 | Convert a string to `camelCase`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { camelize } from 'rattail' 9 | 10 | camelize('hello-world') // return 'helloWorld' 11 | camelize('FooBar') // return 'fooBar' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :------: | -------: | 18 | | `value` | `string` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/string/ensure-prefix.md: -------------------------------------------------------------------------------- 1 | # ensurePrefix 2 | 3 | Ensure that a prefix exists in the `string`, and add it if it does not exist 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { ensurePrefix } from 'rattail' 9 | 10 | ensurePrefix('prefix-hello-world', 'prefix-') // return 'prefix-hello-world' 11 | ensurePrefix('hello-world', 'prefix-') // return 'prefix-hello-world' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | -------- | :------: | -------: | 18 | | `value` | `string` | | 19 | | `prefix` | `string` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :------: | 25 | | `string` | 26 | -------------------------------------------------------------------------------- /docs/string/ensure-suffix.md: -------------------------------------------------------------------------------- 1 | # ensureSuffix 2 | 3 | Ensure that a suffix exists in the `string`, and add it if it does not exist 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { ensureSuffix } from 'rattail' 9 | 10 | ensureSuffix('hello-world-suffix', '-suffix') // return 'hello-world-suffix' 11 | ensureSuffix('hello-world', '-suffix') // return 'hello-world-suffix' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | -------- | :------: | -------: | 18 | | `value` | `string` | | 19 | | `suffix` | `string` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | :------: | 25 | | `string` | 26 | -------------------------------------------------------------------------------- /docs/string/gen-string-key.md: -------------------------------------------------------------------------------- 1 | # genStringKey 2 | 3 | Generate a unique `string` key by incrementing a numeric value and converting it to a string. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { genStringKey } from 'rattail' 9 | 10 | genStringKey() // return 'generated-key-0' 11 | genStringKey() // return 'generated-key-1' 12 | genStringKey() // return 'generated-key-2' 13 | ``` 14 | 15 | ### Return 16 | 17 | | Type | 18 | | :------: | 19 | | `string` | 20 | -------------------------------------------------------------------------------- /docs/string/kebab-case.md: -------------------------------------------------------------------------------- 1 | # kebabCase 2 | 3 | Convert a string to `kebab-case`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { kebabCase } from 'rattail' 9 | 10 | kebabCase('HelloWorld') // return 'hello-world' 11 | kebabCase('fooBar') // return 'foo-bar' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :------: | -------: | 18 | | `value` | `string` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/string/lower-first.md: -------------------------------------------------------------------------------- 1 | # lowerFirst 2 | 3 | Lowercase the `first letter` of the `string` and keep the rest unchanged. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { upperFirst } from 'rattail' 9 | 10 | upperFirst('Hello') // return 'hello' 11 | upperFirst('Rattail') // return 'rattail' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :------: | -------: | 18 | | `value` | `string` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/string/pascal-case.md: -------------------------------------------------------------------------------- 1 | pascalCase 2 | 3 | Convert a string to `PascalCase`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { pascalCase } from 'rattail' 9 | 10 | pascalCase('hello-world') // return 'HelloWorld' 11 | pascalCase('fooBar') // return 'FooBar' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :------: | -------: | 18 | | `value` | `string` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/string/random-color.md: -------------------------------------------------------------------------------- 1 | # randomColor 2 | 3 | Generate a random hexadecimal color string. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { randomColor } from 'rattail' 9 | 10 | randomColor() // Generates a random hex color, e.g., '#a1b2c3' 11 | ``` 12 | 13 | ### Return 14 | 15 | | Type | 16 | | :------: | 17 | | `string` | 18 | -------------------------------------------------------------------------------- /docs/string/random-string.md: -------------------------------------------------------------------------------- 1 | # randomString 2 | 3 | Generate a random alphanumeric string of a specified length. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { randomString } from 'rattail' 9 | 10 | randomString() // Generates a random string of length 10 11 | randomString(30) // Generates a random string of length 30 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | -------- | :------: | -------: | 18 | | `length` | `number` | `10` | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/string/slash.md: -------------------------------------------------------------------------------- 1 | # slash 2 | 3 | Convert all backslashes (`\`) in a path to forward slashes (`/`). If the path starts with `\\?\`, indicating an extended-length path, it is returned as-is without modification. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { slash } from 'rattail' 9 | 10 | slash('C:\\path\\to\\file') 11 | // return 'C:/path/to/file' 12 | slash('\\\\?\\C:\\path\\to\\file') 13 | // return '\\\\?\\C:\\path\\to\\file' (unmodified) 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | ------ | :------: | -------: | 20 | | `path` | `string` | | 21 | 22 | ### Return 23 | 24 | | Type | 25 | | :------: | 26 | | `string` | 27 | -------------------------------------------------------------------------------- /docs/string/upper-first.md: -------------------------------------------------------------------------------- 1 | # upperFirst 2 | 3 | Capitalize the `first letter` of a `string`, leaving the rest of the string unchanged. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { upperFirst } from 'rattail' 9 | 10 | upperFirst('hello world') // return 'Hello world' 11 | upperFirst('rattail') // return 'Rattail' 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | ------- | :------: | -------: | 18 | | `value` | `string` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/util/cancel-animation-frame.md: -------------------------------------------------------------------------------- 1 | # cancelAnimationFrame 2 | 3 | Cancels a `requestAnimationFrame` request using the provided handle, with a fallback to `clearTimeout`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { cancelAnimationFrame } from 'rattail' 9 | 10 | const handle = requestAnimationFrame(() => {}) 11 | cancelAnimationFrame(handle) 12 | ``` 13 | 14 | ### Arguments 15 | 16 | | Arg | Type | Defaults | 17 | | -------- | -------- | -------- | 18 | | `handle` | `number` | | 19 | 20 | ### Return 21 | 22 | | Type | 23 | | ------ | 24 | | `void` | 25 | -------------------------------------------------------------------------------- /docs/util/classes.md: -------------------------------------------------------------------------------- 1 | # classes 2 | 3 | Generates a list of class names based on a given condition or directly returns class names. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { classes } from 'rattail' 9 | 10 | classes('a', [true, 'b', 'c']) 11 | // return ['a', 'b'] 12 | classes('a', [false, 'b', 'c']) 13 | // return ['a', 'c'] 14 | ``` 15 | 16 | ### Arguments 17 | 18 | | Arg | Type | Defaults | 19 | | --------- | ----------------- | -------- | 20 | | `...args` | `string \| Array` | | 21 | 22 | ### Return 23 | 24 | | Type | 25 | | ------- | 26 | | `any[]` | 27 | -------------------------------------------------------------------------------- /docs/util/copy-text.md: -------------------------------------------------------------------------------- 1 | # copyText 2 | 3 | Copies text to the clipboard. 4 | 5 | ### Usage 6 | 7 | ```js 8 | import { copyText } from 'rattail' 9 | 10 | copyText('Hello, clipboard!') // The string will be written to the clipboard 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ------ | -------- | -------- | 17 | | `text` | `string` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | ---- | 23 | | `-` | 24 | -------------------------------------------------------------------------------- /docs/util/create-namespace-fn.md: -------------------------------------------------------------------------------- 1 | # createNamespaceFn 2 | 3 | Creates a namespace function that allows BEM-style naming of components and classes. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { createNamespaceFn } from 'rattail' 9 | 10 | const createNamespace = createNamespaceFn('var') 11 | const { name, n, classes } = createNamespace('button') 12 | // name: 'VarButton', classes 与 rattail 提供的 classes 一致 13 | 14 | n() // return 'var-button' 15 | n('$-box') // return 'var-box' 16 | n('element') // return 'var-button__element' 17 | n('--modifier') // return 'var-button--modifier' 18 | ``` 19 | 20 | ### Arguments 21 | 22 | | Arg | Type | Defaults | 23 | | ----------- | -------- | -------- | 24 | | `namespace` | `string` | | 25 | 26 | ### Return 27 | 28 | | Type | 29 | | -------------------------------------------------- | 30 | | `{ name: string; n: Function; classes: Function }` | 31 | -------------------------------------------------------------------------------- /docs/util/double-raf.md: -------------------------------------------------------------------------------- 1 | # doubleRaf 2 | 3 | Creates a Promise-based double `requestAnimationFrame` that resolves after two frames. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { doubleRaf } from 'rattail' 9 | 10 | await doubleRaf() 11 | console.log('Two frames later') 12 | ``` 13 | 14 | ### Return 15 | 16 | | Type | 17 | | --------------- | 18 | | `Promise` | 19 | -------------------------------------------------------------------------------- /docs/util/download.md: -------------------------------------------------------------------------------- 1 | # download 2 | 3 | Trigger browser download, supporting downloading via file `url`, `Blob`, `File`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { download } from 'rattail' 9 | 10 | download('/hello.txt', 'hello.txt') 11 | download(new Blob(['hello']), 'hello.txt') 12 | download(new File(['helle'], 'hello.txt', { type: 'text/plain' }), 'hello.txt') 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ---------- | ------------------------ | -------- | 19 | | `value` | `string \| Blob \| File` | | 20 | | `filename` | `string` | `file` | 21 | -------------------------------------------------------------------------------- /docs/util/get-all-parent-scroller.md: -------------------------------------------------------------------------------- 1 | # getAllParentScroller 2 | 3 | Retrieves all scrollable ancestor elements of an element in an array, including the `window` as the last item. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { getAllParentScroller } from 'rattail' 9 | 10 | const scrollers = getAllParentScroller(document.querySelector('div')) 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ---- | ------------- | -------- | 17 | | `el` | `HTMLElement` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | ------------------------------ | 23 | | `Array` | 24 | -------------------------------------------------------------------------------- /docs/util/get-parent-scroller.md: -------------------------------------------------------------------------------- 1 | # getParentScroller 2 | 3 | Finds the closest scrollable ancestor of an element. If no scrollable ancestor is found, returns the `window`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { getParentScroller } from 'rattail' 9 | 10 | const scroller = getParentScroller(document.querySelector('div')) 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ---- | ------------- | -------- | 17 | | `el` | `HTMLElement` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | ----------------------- | 23 | | `HTMLElement \| Window` | 24 | -------------------------------------------------------------------------------- /docs/util/get-rect.md: -------------------------------------------------------------------------------- 1 | # getRect 2 | 3 | Gets the dimensions and position of an element or window as a `DOMRect` object. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { getRect } from 'rattail' 9 | 10 | const rect = getRect(document.querySelector('div')) 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | --------- | --------- | -------- | 17 | | `element` | `Element` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | --------- | 23 | | `DOMRect` | 24 | -------------------------------------------------------------------------------- /docs/util/get-scroll-left.md: -------------------------------------------------------------------------------- 1 | # getScrollLeft 2 | 3 | Gets the horizontal scroll position of an element or window. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { getScrollLeft } from 'rattail' 9 | 10 | const scrollLeft = getScrollLeft(window) 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | --------- | ------------------- | -------- | 17 | | `element` | `Element \| Window` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | -------- | 23 | | `number` | 24 | -------------------------------------------------------------------------------- /docs/util/get-scroll-top.md: -------------------------------------------------------------------------------- 1 | # getScrollTop 2 | 3 | Gets the vertical scroll position of an element or window. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { getScrollTop } from 'rattail' 9 | 10 | const scrollTop = getScrollTop(window) 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | --------- | ------------------- | -------- | 17 | | `element` | `Element \| Window` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | -------- | 23 | | `number` | 24 | -------------------------------------------------------------------------------- /docs/util/get-style.md: -------------------------------------------------------------------------------- 1 | # getStyle 2 | 3 | Retrieves computed CSS styles for a given DOM element. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { getStyle } from 'rattail' 9 | 10 | const elementStyle = getStyle(document.querySelector('div')) 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | --------- | --------- | -------- | 17 | | `element` | `Element` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | --------------------- | 23 | | `CSSStyleDeclaration` | 24 | -------------------------------------------------------------------------------- /docs/util/in-viewport.md: -------------------------------------------------------------------------------- 1 | # inViewport 2 | 3 | Determines if an element is visible within the viewport. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { inViewport } from 'rattail' 9 | 10 | const isVisible = inViewport(document.querySelector('div')) 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | --------- | ------------- | -------- | 17 | | `element` | `HTMLElement` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | --------- | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/util/mitt.md: -------------------------------------------------------------------------------- 1 | # mitt 2 | 3 | Event emitter / pubsub. Integrated with [mitt](https://github.com/developit/mitt). 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { mitt } from 'rattail' 9 | 10 | const emitter = mitt() 11 | 12 | // listen to an event 13 | emitter.on('foo', (e) => { 14 | console.log('foo', e) 15 | }) 16 | 17 | // listen to all events 18 | emitter.on('*', (type, e) => { 19 | console.log(type, e) 20 | }) 21 | 22 | // fire an event 23 | emitter.emit('foo', { a: 'b' }) 24 | 25 | // clearing all events 26 | emitter.all.clear() 27 | 28 | // working with handler references: 29 | emitter.on('foo', onFoo) 30 | emitter.off('foo', onFoo) 31 | 32 | function onFoo() {} 33 | ``` 34 | 35 | ### API 36 | 37 | [Reference](https://github.com/developit/mitt) 38 | -------------------------------------------------------------------------------- /docs/util/pretty-JSON-object.md: -------------------------------------------------------------------------------- 1 | # prettyJSONObject 2 | 3 | Formats a `JSON` object with indentation for easy readability. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { prettyJSONObject } from 'rattail' 9 | 10 | const jsonObject = { key: 'value', nested: { key: 'nestedValue' } } 11 | const pretty = prettyJSONObject(jsonObject) 12 | console.log(pretty) 13 | /* 14 | { 15 | "key": "value", 16 | "nested": { 17 | "key": "nestedValue" 18 | } 19 | } 20 | */ 21 | ``` 22 | 23 | ### Arguments 24 | 25 | | Arg | Type | Defaults | 26 | | ------------ | -------- | -------- | 27 | | `jsonObject` | `object` | | 28 | 29 | ### Return 30 | 31 | | Type | 32 | | -------- | 33 | | `string` | 34 | -------------------------------------------------------------------------------- /docs/util/prevent-default.md: -------------------------------------------------------------------------------- 1 | # preventDefault 2 | 3 | Prevents the default action of an event if it is cancelable. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { preventDefault } from 'rattail' 9 | 10 | document.addEventListener('click', preventDefault) 11 | ``` 12 | 13 | ### Arguments 14 | 15 | | Arg | Type | Defaults | 16 | | ------- | ------- | -------- | 17 | | `event` | `Event` | | 18 | 19 | ### Return 20 | 21 | | Type | 22 | | ------ | 23 | | `void` | 24 | -------------------------------------------------------------------------------- /docs/util/raf.md: -------------------------------------------------------------------------------- 1 | # raf 2 | 3 | Creates a Promise-based `requestAnimationFrame` that resolves on the next frame. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { raf } from 'rattail' 9 | 10 | await raf() 11 | console.log('Next animation frame') 12 | ``` 13 | 14 | ### Return 15 | 16 | | Type | 17 | | --------------- | 18 | | `Promise` | 19 | -------------------------------------------------------------------------------- /docs/util/request-animation-frame.md: -------------------------------------------------------------------------------- 1 | # requestAnimationFrame 2 | 3 | Provides a cross-browser compatible `requestAnimationFrame` function, with a fallback to `setTimeout`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { requestAnimationFrame } from 'rattail' 9 | 10 | requestAnimationFrame(() => { 11 | console.log('Frame requested') 12 | }) 13 | ``` 14 | 15 | ### Arguments 16 | 17 | | Arg | Type | Defaults | 18 | | ---- | ---------------------- | -------- | 19 | | `fn` | `FrameRequestCallback` | | 20 | 21 | ### Return 22 | 23 | | Type | 24 | | -------- | 25 | | `number` | 26 | -------------------------------------------------------------------------------- /docs/util/storage.md: -------------------------------------------------------------------------------- 1 | # storage 2 | 3 | Enhance `localStorage` and `sessionStorage`, support automatic json `stringify` and `parse` of data, and retain all native APIs. 4 | 5 | ### Usage 6 | 7 | #### localStorage 8 | 9 | ```js 10 | import { localStorage } from 'rattail' 11 | 12 | localStorage.set('key', { a: 1 }) // automatic json stringify 13 | localStorage.get('key') // return { a: 1 }, automatic json parse 14 | localStorage.remove('key') // same with localStorage.removeItem('key') 15 | ``` 16 | 17 | #### sessionStorage 18 | 19 | ```js 20 | import { sessionStorage } from 'rattail' 21 | 22 | sessionStorage.set('key', { a: 1 }) // automatic json stringify 23 | sessionStorage.get('key') // return { a: 1 }, automatic json parse 24 | sessionStorage.remove('key') // same with sessionStorage.removeItem('key') 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/util/try-parse-JSON.md: -------------------------------------------------------------------------------- 1 | # tryParseJSON 2 | 3 | Attempts to parse a `JSON` string. If parsing fails, returns `undefined`. 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { tryParseJSON } from 'rattail' 9 | 10 | const jsonString = '{"key": "value"}' 11 | const parsed = tryParseJSON(jsonString) 12 | console.log(parsed) // { key: "value" } 13 | 14 | const invalidJsonString = '{"key": value}' 15 | const invalidParsed = tryParseJSON(invalidJsonString) 16 | console.log(invalidParsed) // undefined 17 | ``` 18 | 19 | ### Arguments 20 | 21 | | Arg | Type | Defaults | 22 | | ------ | -------- | -------- | 23 | | `json` | `string` | | 24 | 25 | ### Return 26 | 27 | | Type | 28 | | --------------------- | 29 | | `object \| undefined` | 30 | -------------------------------------------------------------------------------- /docs/zh/array/at.md: -------------------------------------------------------------------------------- 1 | # at 2 | 3 | 获取 `数组` 中指定索引的元素,支持负索引。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { at } from 'rattail' 9 | 10 | at([1, 2, 3], 0) // return 1 11 | at([1, 2, 3], -1) // return 3 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | -------- | ------ | 18 | | `arr` | `Array` | | 19 | | `index` | `number` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | ----- | 25 | | `any` | 26 | -------------------------------------------------------------------------------- /docs/zh/array/chunk.md: -------------------------------------------------------------------------------- 1 | # chunk 2 | 3 | 对 `数组` 进行分块。传递的 `size` 表示块的长度。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { chunk } from 'rattail' 9 | 10 | chunk([1, 2, 3], 2) // return [[1, 2], [3]] 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ------ | -------- | ------ | 17 | | `arr` | `Array` | | 18 | | `size` | `number` | `1` | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | ------- | 24 | | `Array` | 25 | -------------------------------------------------------------------------------- /docs/zh/array/difference-with.md: -------------------------------------------------------------------------------- 1 | # differenceWith 2 | 3 | 创建一个不包含在其他给定数组中的数组值的 `数组`,并支持自定义比较函数。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { differenceWith } from 'rattail' 9 | 10 | differenceWith([{ num: 1 }, { num: 2 }, { num: 3 }], [{ num: 2 }], (a, b) => a.num === b.num) 11 | // return [{ num: 1 }, { num: 3 }] 12 | differenceWith([{ num: 1 }, { num: 2 }, { num: 3 }], [{ num: 2 }], [{ num: 3 }], (a, b) => a.num === b.num) 13 | // return [{ num: 1 }] 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ----------- | ------------------------- | ------ | 20 | | `arr` | `Array` | | 21 | | `...values` | `Array` | | 22 | | `fn` | `(a: any, b: any) => any` | | 23 | 24 | ### 返回值 25 | 26 | | 类型 | 27 | | ------- | 28 | | `Array` | 29 | -------------------------------------------------------------------------------- /docs/zh/array/difference.md: -------------------------------------------------------------------------------- 1 | # difference 2 | 3 | 创建一个不包含在其他给定数组中的数组值的 `数组`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { difference } from 'rattail' 9 | 10 | difference([1, 2, 3, 4], [2, 3]) 11 | // return [1, 4] 12 | difference([1, 2, 3, 4], [2, 3], [3, 4]) 13 | // return [1] 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ----------- | -------------- | ------ | 20 | | `arr` | `Array` | | 21 | | `...values` | `Array` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | ------- | 27 | | `Array` | 28 | -------------------------------------------------------------------------------- /docs/zh/array/find.md: -------------------------------------------------------------------------------- 1 | # find 2 | 3 | 在 `数组` 中查找 `第一个` 或 `最后一个` 满足指定条件的元素,返回该元素及其索引。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { find } from 'rattail' 9 | 10 | find(['a', 'b', 'c'], (item) => item === 'a') 11 | // return ['a', 0] 12 | find(['a', 'b', 'a'], (item) => item === 'a', 'end') 13 | // return ['a', 2] 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ------ | ----------------------------------------------------- | --------- | 20 | | `arr` | `Array` | | 21 | | `fn` | `(item: any, index: number, array: Array) => boolean` | | 22 | | `from` | `'start' \| 'end'` | `'start'` | 23 | 24 | ### 返回值 25 | 26 | | 类型 | 27 | | ----------------------------- | 28 | | `[any, number] \| [null, -1]` | 29 | -------------------------------------------------------------------------------- /docs/zh/array/group-by.md: -------------------------------------------------------------------------------- 1 | # groupBy 2 | 3 | 对给定的 `数组` 中的元素进行分组,传递的函数的返回值将用作分组的键。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { groupBy } from 'rattail' 9 | 10 | groupBy([1, 2, 3, 4, 5], (num) => (num % 2 === 0 ? 'even' : 'odd')) 11 | // return { odd: [1, 3, 5], even: [2, 4] } 12 | groupBy( 13 | [ 14 | { name: 'a', gender: 'female' }, 15 | { name: 'b', gender: 'female' }, 16 | { name: 'c', gender: 'male' }, 17 | ], 18 | (val) => val.gender, 19 | ) 20 | // return { 21 | // female: [ 22 | // { name: 'a', gender: 'female' }, 23 | // { name: 'b', gender: 'female' }, 24 | // ], 25 | // male: [{ name: 'c', gender: 'male' }], 26 | // } 27 | ``` 28 | 29 | ### 参数 30 | 31 | | 参数 | 类型 | 默认值 | 32 | | ----- | ------------------- | ------ | 33 | | `arr` | `Array` | | 34 | | `fn` | `(val: any) => any` | | 35 | 36 | ### 返回值 37 | 38 | | 类型 | 39 | | -------- | 40 | | `object` | 41 | -------------------------------------------------------------------------------- /docs/zh/array/intersection-with.md: -------------------------------------------------------------------------------- 1 | # intersectionWith 2 | 3 | 创建一个去重数组,数组中的每个值都被包含在所有的给定数组中(数组取交集),支持传入比较函数。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { intersectionWith } from 'rattail' 9 | 10 | intersectionWith( 11 | [{ num: 1 }, { num: 2 }, { num: 3 }, { num: 3 }], 12 | [{ num: 2 }, { num: 3 }, { num: 4 }], 13 | (a, b) => a.num === b.num, 14 | ) 15 | // return [{ num: 2 }, { num: 3 }] 16 | intersectionWith( 17 | [{ num: 1 }, { num: 2 }, { num: 3 }, { num: 3 }], 18 | [{ num: 2 }, { num: 3 }, { num: 4 }], 19 | [{ num: 3 }, { num: 4 }, { num: 5 }], 20 | (a, b) => a.num === b.num, 21 | ) 22 | // return [{ num: 3 }] 23 | ``` 24 | 25 | ### 参数 26 | 27 | | 参数 | 类型 | 默认值 | 28 | | ----------- | ------------------------- | ------ | 29 | | `...values` | `Array` | | 30 | | `fn` | `(a: any, b: any) => any` | | 31 | 32 | ### 返回值 33 | 34 | | 类型 | 35 | | ------- | 36 | | `Array` | 37 | -------------------------------------------------------------------------------- /docs/zh/array/intersection.md: -------------------------------------------------------------------------------- 1 | # intersection 2 | 3 | 创建一个去重数组,数组中的每个值都被包含在所有的给定数组中(数组取交集)。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { intersection } from 'rattail' 9 | 10 | intersection([1, 2, 3, 3], [2, 3, 4]) 11 | // return [2, 3] 12 | intersection([1, 2, 3, 3], [2, 3, 4], [3, 4, 5]) 13 | // return [3] 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ----------- | -------------- | ------ | 20 | | `...values` | `Array` | | 21 | 22 | ### 返回值 23 | 24 | | 类型 | 25 | | ------- | 26 | | `Array` | 27 | -------------------------------------------------------------------------------- /docs/zh/array/normalize-to-array.md: -------------------------------------------------------------------------------- 1 | # normalizeToArray 2 | 3 | 将值转换为 `数组`,如果输入已经是数组,则直接返回输入值。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { normalizeToArray } from 'rattail' 9 | 10 | normalizeToArray(5) // return [5] 11 | normalizeToArray([1, 2, 3]) // return [1, 2, 3] 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | ----- | ------ | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | ------- | 24 | | `Array` | 25 | -------------------------------------------------------------------------------- /docs/zh/array/remove-array-blank.md: -------------------------------------------------------------------------------- 1 | # removeArrayBlank 2 | 3 | 移除数组中值为 `null` 或 `undefined` 的元素。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { removeArrayBlank } from 'rattail' 9 | 10 | removeArrayBlank([1, null, 2, undefined, 3]) // return [1, 2, 3] 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ----- | ------- | ------ | 17 | | `arr` | `Array` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | ------- | 23 | | `Array` | 24 | -------------------------------------------------------------------------------- /docs/zh/array/remove-array-empty.md: -------------------------------------------------------------------------------- 1 | # removeArrayEmpty 2 | 3 | 移除数组中值为 `null`、`undefined` 或空字符串(`''`)的元素。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { removeArrayEmpty } from 'rattail' 9 | 10 | removeArrayEmpty([1, null, undefined, '', 3]) // return [1, 3] 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ----- | ------- | ------ | 17 | | `arr` | `Array` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | ------- | 23 | | `Array` | 24 | -------------------------------------------------------------------------------- /docs/zh/array/remove-item.md: -------------------------------------------------------------------------------- 1 | # removeItem 2 | 3 | 从 `数组` 中移除 `第一次` 出现的指定元素,返回移除的元素。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { removeItem } from 'rattail' 9 | 10 | const arr = [1, 2, 3] 11 | removeItem(arr, 2) // arr 变为 [1, 3] 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------ | ------- | ------ | 18 | | `arr` | `Array` | | 19 | | `item` | `any` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | ----- | 25 | | `any` | 26 | -------------------------------------------------------------------------------- /docs/zh/array/shuffle.md: -------------------------------------------------------------------------------- 1 | # shuffle 2 | 3 | 随机打乱 `数组` 中的元素。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { shuffle } from 'rattail' 9 | 10 | shuffle([1, 2, 3]) // return 打乱后的数组 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ----- | ------- | ------ | 17 | | `arr` | `Array` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | ------- | 23 | | `Array` | 24 | -------------------------------------------------------------------------------- /docs/zh/array/sum-by.md: -------------------------------------------------------------------------------- 1 | # sumBy 2 | 3 | 根据提供的函数计算 `数组` 中各项值的和。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { sumBy } from 'rattail' 9 | 10 | sumBy([{ n: 1 }, { n: 2 }, { n: 3 }], (item) => item.n) // return 6 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ----- | ---------------------- | ------ | 17 | | `arr` | `Array` | | 18 | | `fn` | `(val: any) => number` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | -------- | 24 | | `number` | 25 | -------------------------------------------------------------------------------- /docs/zh/array/sum.md: -------------------------------------------------------------------------------- 1 | # sum 2 | 3 | 计算数字 `数组` 中各项值的和。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { sum } from 'rattail' 9 | 10 | sum([1, 2, 3]) // return 6 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ----- | ---------- | ------ | 17 | | `arr` | `number[]` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | -------- | 23 | | `number` | 24 | -------------------------------------------------------------------------------- /docs/zh/array/toggle-item.md: -------------------------------------------------------------------------------- 1 | # toggleItem 2 | 3 | 根据元素是否在 `数组` 中,将其添加到数组 `末尾` 或从数组中移除。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { toggleItem } from 'rattail' 9 | 10 | const arr = [1, 2] 11 | toggleItem(arr, 2) // arr 变为 [1] 12 | toggleItem(arr, 3) // arr 变为 [1, 3] 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ------ | ------- | ------ | 19 | | `arr` | `Array` | | 20 | | `item` | `any` | | 21 | 22 | ### 返回值 23 | 24 | | 类型 | 25 | | ------- | 26 | | `Array` | 27 | -------------------------------------------------------------------------------- /docs/zh/array/uniq-by.md: -------------------------------------------------------------------------------- 1 | # uniqBy 2 | 3 | 使用自定义比较函数返回去重后的 `数组`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { uniqBy } from 'rattail' 9 | 10 | uniqBy([{ id: 1 }, { id: 2 }, { id: 1 }], (a, b) => a.id === b.id) 11 | // return [{ id: 1 }, { id: 2 }] 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----- | ------------------------- | ------ | 18 | | `arr` | `Array` | | 19 | | `fn` | `(a: any, b: any) => any` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | ------- | 25 | | `Array` | 26 | -------------------------------------------------------------------------------- /docs/zh/array/uniq.md: -------------------------------------------------------------------------------- 1 | # uniq 2 | 3 | 返回去重后的 `数组`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { uniq } from 'rattail' 9 | 10 | uniq([1, 2, 2, 3]) // return [1, 2, 3] 11 | uniq(['a', 'a', 'b', 'c']) // return ['a', 'b', 'c'] 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----- | ------- | ------ | 18 | | `arr` | `Array` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | ------- | 24 | | `Array` | 25 | -------------------------------------------------------------------------------- /docs/zh/array/xor-with.md: -------------------------------------------------------------------------------- 1 | # xorWith 2 | 3 | 对传入的数组进行异或(Exclusive OR)计算,返回一个新的 `数组`,并支持自定义比较函数。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { xorWith } from 'rattail' 9 | 10 | xorWith([{ num: 1 }, { num: 2 }, { num: 2 }], [{ num: 1 }, { num: 3 }], (a, b) => a.num === b.num) 11 | // return [{ num: 2 }, { num: 3 }] 12 | xorWith([{ num: 1 }, { num: 2 }], [{ num: 1 }, { num: 2 }], [{ num: 3 }], (a, b) => a.num === b.num) 13 | // return [{ num: 3 }] 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ----------- | ------------------------- | ------ | 20 | | `...values` | `Array` | | 21 | | `fn` | `(a: any, b: any) => any` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | ------- | 27 | | `Array` | 28 | -------------------------------------------------------------------------------- /docs/zh/array/xor.md: -------------------------------------------------------------------------------- 1 | # xor 2 | 3 | 对传入的数组进行异或(Exclusive OR)计算,返回一个新的 `数组`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { xor } from 'rattail' 9 | 10 | xor([1, 2, 2], [1, 3]) 11 | // return [2, 3] 12 | xor([1, 2], [1, 2], [3]) 13 | // return [3] 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ----------- | -------------- | ------ | 20 | | `...values` | `Array` | | 21 | 22 | ### 返回值 23 | 24 | | 类型 | 25 | | ------- | 26 | | `Array` | 27 | -------------------------------------------------------------------------------- /docs/zh/collection/clone-deep-with.md: -------------------------------------------------------------------------------- 1 | # cloneDeepWith 2 | 3 | 创建一个值的深拷贝,并为每个值应用一个自定义函数来处理克隆。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { cloneDeepWith, isNumber } from 'rattail' 9 | 10 | const original = { a: 1, b: { c: 2 } } 11 | const value = cloneDeepWith(original, (val) => { 12 | if (isNumber(val)) { 13 | return val * 2 14 | } 15 | }) 16 | // value: { a: 2, b: { c: 4 } } 17 | ``` 18 | 19 | ### 参数 20 | 21 | | 参数 | 类型 | 默认值 | 22 | | ------- | :-------------------: | -----: | 23 | | `value` | `any` | | 24 | | `fn` | `(value: any) => any` | | 25 | 26 | ### 返回值 27 | 28 | | 类型 | 29 | | :---: | 30 | | `any` | 31 | -------------------------------------------------------------------------------- /docs/zh/collection/clone-deep.md: -------------------------------------------------------------------------------- 1 | # cloneDeep 2 | 3 | 创建一个值的深拷贝。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { cloneDeep } from 'rattail' 9 | 10 | const original = { a: 1, b: { c: 2 } } 11 | const value = cloneDeep(original) 12 | // value: { a: 1, b: { c: 2 } } 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ------- | :---: | -----: | 19 | | `value` | `any` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :---: | 25 | | `any` | 26 | -------------------------------------------------------------------------------- /docs/zh/collection/merge-with.md: -------------------------------------------------------------------------------- 1 | # mergeWith 2 | 3 | 递归合并两个对象,可通过回调函数自定义合并逻辑。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { mergeWith } from 'rattail' 9 | 10 | mergeWith({ a: [1, 2] }, { a: [3, 4] }, (objValue, srcValue) => [...objValue, ...srcValue]) 11 | // return { a: [ 1, 2, 3, 4 ] } 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------------ | --------------------------------------------------------------------------------- | ------ | 18 | | `object` | `object` | | 19 | | `...sources` | `object[]` | | 20 | | `fn` | `(objValue: any, srcValue: any, key: any, object: object, source: object) => any` | | 21 | 22 | ### 返回值 23 | 24 | | 类型 | 25 | | -------- | 26 | | `object` | 27 | -------------------------------------------------------------------------------- /docs/zh/collection/merge.md: -------------------------------------------------------------------------------- 1 | # merge 2 | 3 | 递归合并两个对象。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { merge } from 'rattail' 9 | 10 | merge({ a: 1, b: { c: 2 } }, { b: { d: 3 }, e: 4 }) 11 | // return { a: 1, b: { c: 2, d: 3 }, e: 4 } 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------------ | ---------- | ------ | 18 | | `object` | `object` | | 19 | | `...sources` | `object[]` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | -------- | 25 | | `object` | 26 | -------------------------------------------------------------------------------- /docs/zh/file/to-array-buffer.md: -------------------------------------------------------------------------------- 1 | # toArrayBuffer 2 | 3 | 将 `File` 对象转换为 `ArrayBuffer`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { toArrayBuffer } from 'rattail' 9 | 10 | await toArrayBuffer(new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' })) 11 | // return ArrayBuffer 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------ | ------ | ------ | 18 | | `file` | `File` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | ---------------------- | 24 | | `Promise` | 25 | -------------------------------------------------------------------------------- /docs/zh/file/to-data-url.md: -------------------------------------------------------------------------------- 1 | # toDataURL 2 | 3 | 将 `File` 对象转换为 Data URL 字符串。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { toDataURL } from 'rattail' 9 | 10 | await toDataURL(new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' })) 11 | // return 'data:text/plain;base64,SGVsbG8sIHdvcmxkIQ==' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------ | ------ | ------ | 18 | | `file` | `File` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | ----------------- | 24 | | `Promise` | 25 | -------------------------------------------------------------------------------- /docs/zh/file/to-text.md: -------------------------------------------------------------------------------- 1 | # toText 2 | 3 | 将 `File` 对象转换为文本字符串。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { toText } from 'rattail' 9 | 10 | await toText(new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' })) 11 | // return 'Hello, world!' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------ | ------ | ------ | 18 | | `file` | `File` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | ----------------- | 24 | | `Promise` | 25 | -------------------------------------------------------------------------------- /docs/zh/function/call.md: -------------------------------------------------------------------------------- 1 | # call 2 | 3 | 调用单个函数或多个函数(通过数组传入),并传递参数给它们。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { call } from 'rattail' 9 | 10 | call((a, b) => a + b, 1, 2) 11 | // return 3 12 | call([(a, b) => a + b, (a, b) => a + b], 1, 2) 13 | // return [3, 3] 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | --------- | :----------------------: | -----: | 20 | | `fn` | `Function \| Function[]` | | 21 | | `...args` | `any[]` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | :--------: | 27 | | `Function` | 28 | -------------------------------------------------------------------------------- /docs/zh/function/debounce.md: -------------------------------------------------------------------------------- 1 | # debounce 2 | 3 | 创建一个防抖函数,该函数会从上一次被调用后,延迟 `delay` 毫秒后调用 `fn` 方法。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { debounce } from 'rattail' 9 | 10 | const debouncedFn = debounce(() => { 11 | // do something 12 | }, 1000) 13 | 14 | window.addEventListener('resize', debouncedFn) 15 | ``` 16 | 17 | ### 参数 18 | 19 | | 参数 | 类型 | 默认值 | 20 | | ------- | :--------: | -----: | 21 | | `fn` | `Function` | | 22 | | `delay` | `number` | `0` | 23 | 24 | ### 返回值 25 | 26 | | 类型 | 27 | | :--------: | 28 | | `Function` | 29 | -------------------------------------------------------------------------------- /docs/zh/function/noop.md: -------------------------------------------------------------------------------- 1 | # NOOP 2 | 3 | 此方法返回 `undefined`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { NOOP } from 'rattail' 9 | 10 | NOOP() // return undefined 11 | ``` 12 | 13 | ### 返回值 14 | 15 | | 类型 | 16 | | :---------: | 17 | | `undefined` | 18 | -------------------------------------------------------------------------------- /docs/zh/function/once.md: -------------------------------------------------------------------------------- 1 | # once 2 | 3 | 创建一个只会执行一次的函数。后续调用将返回第一次调用的结果。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { once } from 'rattail' 9 | 10 | const fn = once(() => 'initialized') 11 | fn() // return 'initialized' 12 | fn() // return 'initialized' 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ---- | :--------: | -----: | 19 | | `fn` | `Function` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :--------: | 25 | | `Function` | 26 | -------------------------------------------------------------------------------- /docs/zh/function/throttle.md: -------------------------------------------------------------------------------- 1 | # throttle 2 | 3 | 创建一个节流函数,该函数每 `delay` 毫秒最多只调用一次 `fn`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { throttle } from 'rattail' 9 | 10 | const throttledFn = throttle(() => { 11 | // do something, it will be called at most 1 time per second 12 | }, 1000) 13 | 14 | window.addEventListener('resize', throttledFn) 15 | ``` 16 | 17 | ### 参数 18 | 19 | | 参数 | 类型 | 默认值 | 20 | | ------- | :--------: | -----: | 21 | | `fn` | `Function` | | 22 | | `delay` | `number` | `200` | 23 | 24 | ### 返回值 25 | 26 | | 类型 | 27 | | :--------: | 28 | | `Function` | 29 | -------------------------------------------------------------------------------- /docs/zh/general/assert.md: -------------------------------------------------------------------------------- 1 | # assert 2 | 3 | 当输入值不是 `true` 时抛出错误,第二个参数是错误信息。 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { assert } from 'rattail' 9 | 10 | const count = 99 11 | assert(count < 100, 'error message') 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----------- | :-------: | -----: | 18 | | `condition` | `boolean` | | 19 | | `message` | `string` | | 20 | -------------------------------------------------------------------------------- /docs/zh/general/get-global-this.md: -------------------------------------------------------------------------------- 1 | # getGlobalThis 2 | 3 | 根据当前环境获取全局对象。 4 | 5 | ### Usage 6 | 7 | ```ts 8 | import { getGlobalThis } from 'rattail' 9 | 10 | getGlobalThis() 11 | // 在浏览器中 return `window`,在 Node.js 中 return `global`, 12 | // 在 web worker return `self` 13 | ``` 14 | 15 | ### Return 16 | 17 | | Type | 18 | | :-----------------: | 19 | | `typeof globalThis` | 20 | -------------------------------------------------------------------------------- /docs/zh/general/has-own.md: -------------------------------------------------------------------------------- 1 | # hasOwn 2 | 3 | 判断对象是否具有某个 `自有(非继承)` 属性。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { hasOwn } from 'rattail' 9 | 10 | const obj = { foo: 123 } 11 | hasOwn(obj, 'foo') // return true 12 | hasOwn(obj, 'bar') // return false 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ------- | :------: | -----: | 19 | | `value` | `object` | | 20 | | `key` | `string` | | 21 | 22 | ### 返回值 23 | 24 | | 类型 | 25 | | :-------: | 26 | | `boolean` | 27 | -------------------------------------------------------------------------------- /docs/zh/general/in-browser.md: -------------------------------------------------------------------------------- 1 | # inBrowser 2 | 3 | 判断代码是否在 `浏览器环境` 中运行。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { inBrowser } from 'rattail' 9 | 10 | inBrowser() // 在浏览器中返回 true 11 | ``` 12 | 13 | ### 返回值 14 | 15 | | 类型 | 16 | | :-------: | 17 | | `boolean` | 18 | -------------------------------------------------------------------------------- /docs/zh/general/in-mobile.md: -------------------------------------------------------------------------------- 1 | # inMobile 2 | 3 | 判断代码是否在 `移动浏览器环境` 中运行。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { inMobile } from 'rattail' 9 | 10 | inMobile() // 如果在移动浏览器中返回 true,否则返回 false 11 | ``` 12 | 13 | ### 返回值 14 | 15 | | 类型 | 16 | | :-------: | 17 | | `boolean` | 18 | -------------------------------------------------------------------------------- /docs/zh/general/is-array-buffer.md: -------------------------------------------------------------------------------- 1 | # isArrayBuffer 2 | 3 | 判断输入值是否是 `ArrayBuffer`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isArrayBuffer } from 'rattail' 9 | 10 | isArrayBuffer(new ArrayBuffer(8)) // return true 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ------- | :---: | -----: | 17 | | `value` | `any` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/zh/general/is-array.md: -------------------------------------------------------------------------------- 1 | # isArray 2 | 3 | 判断输入值是否是数组。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isArray } from 'rattail' 9 | 10 | isArray([]) // return true 11 | isArray({}) // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-blob.md: -------------------------------------------------------------------------------- 1 | # isBlob 2 | 3 | 判断输入值是否是 `Blob`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isBlob } from 'rattail' 9 | 10 | isBlob(new Blob(['Hello, World!'], { type: 'text/plain' })) // return true 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ------- | :---: | -----: | 17 | | `value` | `any` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/zh/general/is-boolean.md: -------------------------------------------------------------------------------- 1 | # isBoolean 2 | 3 | 判断输入值是否是 `布尔值`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isBoolean } from 'rattail' 9 | 10 | isBoolean(true) // return true 11 | isBoolean('rattail') // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-data-view.md: -------------------------------------------------------------------------------- 1 | # isDataView 2 | 3 | 判断输入值是否是 `DataView`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isDataView } from 'rattail' 9 | 10 | isDataView(new DataView(new ArrayBuffer(1))) // return true 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ------- | :---: | -----: | 17 | | `value` | `any` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/zh/general/is-date.md: -------------------------------------------------------------------------------- 1 | # isDate 2 | 3 | 判断输入值是否是 `Date`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isDate } from 'rattail' 9 | 10 | isDate(new Date()) // return true 11 | isDate('2024-01-01') // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-dom-exception.md: -------------------------------------------------------------------------------- 1 | # isDOMException 2 | 3 | 判断输入值是否为 `DOMException` 对象。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isDOMException } from 'rattail' 9 | 10 | isDOMException(new DOMException('An error occurred')) // return true 11 | isDOMException(new Error('An error occurred')) // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----- | :---: | -----: | 18 | | `val` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-empty-plain-object.md: -------------------------------------------------------------------------------- 1 | # isEmptyPlainObject 2 | 3 | 判断输入值是否为空(没有自身的可枚举 key 并且没有 symbol)的普通对象。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isEmptyPlainObject } from 'rattail' 9 | 10 | isEmptyPlainObject({}) // return true 11 | isEmptyPlainObject(Object.create(null)) // return true 12 | isEmptyPlainObject([]) // return false 13 | isEmptyPlainObject({ a: 1 }) // return false 14 | isEmptyPlainObject({ [Symbol()]: 1 }) // return false 15 | ``` 16 | 17 | ### 参数 18 | 19 | | 参数 | 类型 | 默认值 | 20 | | ------- | :---: | -----: | 21 | | `value` | `any` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | :-------: | 27 | | `boolean` | 28 | -------------------------------------------------------------------------------- /docs/zh/general/is-empty.md: -------------------------------------------------------------------------------- 1 | # isEmpty 2 | 3 | 判断输入值是否为空(`undefined`、`null`、`空字符串`或`空数组`)。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isEmpty } from 'rattail' 9 | 10 | isEmpty(null) // return true 11 | isEmpty('') // return true 12 | isEmpty([]) // return true 13 | isEmpty([1, 2, 3]) // return false 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ------- | :---: | -----: | 20 | | `value` | `any` | | 21 | 22 | ### 返回值 23 | 24 | | 类型 | 25 | | :-------: | 26 | | `boolean` | 27 | -------------------------------------------------------------------------------- /docs/zh/general/is-equal-with.md: -------------------------------------------------------------------------------- 1 | # isEqualWith 2 | 3 | 深度比较两个值。支持传入一个比较方法,返回 `true` 时表示两个值相等。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isEqualWith, isObject } from 'rattail' 9 | 10 | isEqualWith([1, 2], ['1', '2'], (v1, v2) => { 11 | if (!isObject(v1) && !isObject(v2)) { 12 | return String(v1) === String(v2) 13 | } 14 | }) 15 | // return true 16 | ``` 17 | 18 | ### 参数 19 | 20 | | 参数 | 类型 | 默认值 | 21 | | ------- | :---------------------: | -----: | 22 | | `value` | `any` | | 23 | | `other` | `any` | | 24 | | `fn` | `(value, other) => any` | | 25 | 26 | ### 返回值 27 | 28 | | 类型 | 29 | | :-------: | 30 | | `boolean` | 31 | -------------------------------------------------------------------------------- /docs/zh/general/is-equal.md: -------------------------------------------------------------------------------- 1 | # isEqual 2 | 3 | 深度比较两个值。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isEqual } from 'rattail' 9 | 10 | isEqual({ n: 1 }, { n: 1 }) 11 | // return true 12 | isEqual([1, 2, 3], [1, 2, 3]) 13 | // return true 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ------- | :---: | -----: | 20 | | `value` | `any` | | 21 | | `other` | `any` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | :-------: | 27 | | `boolean` | 28 | -------------------------------------------------------------------------------- /docs/zh/general/is-error.md: -------------------------------------------------------------------------------- 1 | # isError 2 | 3 | 判断输入值是否为 `Error` 对象。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isError } from 'rattail' 9 | 10 | isError(new Error('message')) // return true 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ----- | :---: | -----: | 17 | | `val` | `any` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/zh/general/is-file.md: -------------------------------------------------------------------------------- 1 | # isFile 2 | 3 | 判断输入值是否是 `File`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isFile } from 'rattail' 9 | 10 | isFile(new File(['Hello, world!'], 'hello.txt', { type: 'text/plain' })) 11 | // return true 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-function.md: -------------------------------------------------------------------------------- 1 | # isFunction 2 | 3 | 判断输入值是否是 `函数`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isFunction } from 'rattail' 9 | 10 | isFunction(() => {}) // return true 11 | isFunction(123) // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-map.md: -------------------------------------------------------------------------------- 1 | # isMap 2 | 3 | 判断输入值是否是 `Map`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isMap } from 'rattail' 9 | 10 | isMap(new Map()) // return true 11 | isMap({}) // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-non-empty-array.md: -------------------------------------------------------------------------------- 1 | # isNonEmptyArray 2 | 3 | 判断输入值是否为 `非空数组`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isNonEmptyArray } from 'rattail' 9 | 10 | isNonEmptyArray([1, 2, 3]) // return true 11 | isNonEmptyArray([]) // return false 12 | isNonEmptyArray(1) // return false 13 | isNonEmptyArray(null) // return false 14 | isNonEmptyArray(undefined) // return false 15 | ``` 16 | 17 | ### 参数 18 | 19 | | 参数 | 类型 | 默认值 | 20 | | ------- | :---: | -----: | 21 | | `value` | `any` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | :-------: | 27 | | `boolean` | 28 | -------------------------------------------------------------------------------- /docs/zh/general/is-nullish.md: -------------------------------------------------------------------------------- 1 | # isNullish 2 | 3 | 判断输入值是否为 `null` 或 `undefined`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isNullish } from 'rattail' 9 | 10 | isNullish(null) // return true 11 | isNullish(undefined) // return true 12 | isNullish(123) // return false 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ------- | :---: | -----: | 19 | | `value` | `any` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :-------: | 25 | | `boolean` | 26 | -------------------------------------------------------------------------------- /docs/zh/general/is-number.md: -------------------------------------------------------------------------------- 1 | # isNumber 2 | 3 | 判断输入值是否是 `数字`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isNumber } from 'rattail' 9 | 10 | isNumber(123) // return true 11 | isNumber('rattail') // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-numeric.md: -------------------------------------------------------------------------------- 1 | # isNumeric 2 | 3 | 判断输入值是否是 `数字` 或 `数字字符串`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isNumeric } from 'rattail' 9 | 10 | isNumeric(123) // return true 11 | isNumeric('456') // return true 12 | isNumeric('rattail') // return false 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ------- | :---: | -----: | 19 | | `value` | `any` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :-------: | 25 | | `boolean` | 26 | -------------------------------------------------------------------------------- /docs/zh/general/is-object.md: -------------------------------------------------------------------------------- 1 | # isObject 2 | 3 | 判断输入值是否是 `对象`(不包括 `null`)。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isObject } from 'rattail' 9 | 10 | isObject({}) // return true 11 | isObject([]) // return true 12 | isObject(null) // return false 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ------- | :---: | -----: | 19 | | `value` | `any` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :-------: | 25 | | `boolean` | 26 | -------------------------------------------------------------------------------- /docs/zh/general/is-plain-object.md: -------------------------------------------------------------------------------- 1 | # isPlainObject 2 | 3 | 判断输入值是否是 `普通对象`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isPlainObject } from 'rattail' 9 | 10 | isPlainObject({}) // return true 11 | isPlainObject([]) // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-primitive.md: -------------------------------------------------------------------------------- 1 | # isPrimitive 2 | 3 | 判断输入值是否是 `基本数据类型`. 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isPrimitive } from 'rattail' 9 | 10 | isPrimitive(1) // return true 11 | isPrimitive('1') // return true 12 | isPrimitive(null) // return true 13 | isPrimitive(undefined) // return true 14 | isPrimitive(true) // return true 15 | isPrimitive(Symbol('1')) // return true 16 | isPrimitive(1n) // return true 17 | isPrimitive({}) // return false 18 | isPrimitive([]) // return false 19 | isPrimitive(new Date()) // return false 20 | ``` 21 | 22 | ### 参数 23 | 24 | | 参数 | 类型 | 默认值 | 25 | | ------- | :---: | -----: | 26 | | `value` | `any` | | 27 | 28 | ### 返回值 29 | 30 | | 类型 | 31 | | :-------: | 32 | | `boolean` | 33 | -------------------------------------------------------------------------------- /docs/zh/general/is-promise.md: -------------------------------------------------------------------------------- 1 | # isPromise 2 | 3 | 判断输入值是否是 `Promise`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isPromise } from 'rattail' 9 | 10 | isPromise(Promise.resolve()) // return true 11 | isPromise({}) // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-reg-exp.md: -------------------------------------------------------------------------------- 1 | # isRegExp 2 | 3 | 判断输入值是否是 `RegExp`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isRegExp } from 'rattail' 9 | 10 | isRegExp(/abc/) // return true 11 | isRegExp('abc') // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-set.md: -------------------------------------------------------------------------------- 1 | # isSet 2 | 3 | 判断输入值是否是 `Set`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isSet } from 'rattail' 9 | 10 | isSet(new Set()) // return true 11 | isSet({}) // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-string.md: -------------------------------------------------------------------------------- 1 | # isString 2 | 3 | 判断输入值是否是 `字符串`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isString } from 'rattail' 9 | 10 | isString('rattail') // return true 11 | isString(123) // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-symbol.md: -------------------------------------------------------------------------------- 1 | # isSymbol 2 | 3 | 判断输入值是否是 `符号`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isSymbol } from 'rattail' 9 | 10 | isSymbol(Symbol('test')) // return true 11 | isSymbol('rattail') // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/is-truthy.md: -------------------------------------------------------------------------------- 1 | # isTruthy 2 | 3 | 判断输入值是否为 `真值`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isTruthy } from 'rattail' 9 | 10 | isTruthy(1) // return true 11 | isTruthy([]) // return true 12 | isTruthy({}) // return true 13 | isTruthy(0) // return false 14 | isTruthy('') // return false 15 | isTruthy(null) // return false 16 | isTruthy(undefined) // return false 17 | ``` 18 | 19 | ### 参数 20 | 21 | | 参数 | 类型 | 默认值 | 22 | | ------- | :---: | -----: | 23 | | `value` | `any` | | 24 | 25 | ### 返回值 26 | 27 | | 类型 | 28 | | :-------: | 29 | | `boolean` | 30 | -------------------------------------------------------------------------------- /docs/zh/general/is-typed-array.md: -------------------------------------------------------------------------------- 1 | # isTypedArray 2 | 3 | 判断输入值是否是 `TypedArray`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isTypedArray } from 'rattail' 9 | 10 | isTypedArray(new Int8Array(8)) // return true 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ------- | :---: | -----: | 17 | | `value` | `any` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/zh/general/is-weak-map.md: -------------------------------------------------------------------------------- 1 | # isWeakMap 2 | 3 | 判断输入值是否是 `WeakMap`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isWeakMap } from 'rattail' 9 | 10 | isWeakMap(new WeakMap()) // return true 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ------- | :---: | -----: | 17 | | `value` | `any` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/zh/general/is-weak-set.md: -------------------------------------------------------------------------------- 1 | # isWeakSet 2 | 3 | 判断输入值是否是 `WeakSet`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isWeakSet } from 'rattail' 9 | 10 | isWeakSet(new WeakSet()) // return true 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ------- | :---: | -----: | 17 | | `value` | `any` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | :-------: | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/zh/general/is-window.md: -------------------------------------------------------------------------------- 1 | # isWindow 2 | 3 | 判断输入值是否是全局 `window` 对象 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { isWindow } from 'rattail' 9 | 10 | isWindow(window) // return true 11 | isWindow({}) // return false 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :-------: | 24 | | `boolean` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/support-touch.md: -------------------------------------------------------------------------------- 1 | # supportTouch 2 | 3 | 判断当前环境是否支持 `触摸事件`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { supportTouch } from 'rattail' 9 | 10 | supportTouch() // 如果支持触摸事件返回 true,否则返回 false 11 | ``` 12 | 13 | ### 返回值 14 | 15 | | 类型 | 16 | | :-------: | 17 | | `boolean` | 18 | -------------------------------------------------------------------------------- /docs/zh/general/to-raw-type.md: -------------------------------------------------------------------------------- 1 | # toRawType 2 | 3 | 返回输入值的 `原始类型`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { toRawType } from 'rattail' 9 | 10 | toRawType({}) // return 'Object' 11 | toRawType([]) // return 'Array' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/zh/general/to-type-string.md: -------------------------------------------------------------------------------- 1 | # toTypeString 2 | 3 | 返回输入值的 `类型字符串`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { toTypeString } from 'rattail' 9 | 10 | toTypeString({}) // return '[object Object]' 11 | toTypeString([]) // return '[object Array]' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :---: | -----: | 18 | | `value` | `any` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/zh/getting-started.md: -------------------------------------------------------------------------------- 1 | # 快速开始 2 | 3 | ## 总览 4 | 5 | `Rattail` 是一个面向前端开发人员的实用工具库,轻量级且 `ts` 友好 6 | 7 | ### 安装 8 | 9 | ::: code-group 10 | 11 | ```shell [npm] 12 | npm i rattail -S 13 | ``` 14 | 15 | ```shell [yarn] 16 | yarn add rattail 17 | ``` 18 | 19 | ```shell [pnpm] 20 | pnpm add rattail 21 | ``` 22 | 23 | ::: 24 | 25 | ### 使用 26 | 27 | ```ts 28 | import { isString } from 'rattail' 29 | 30 | console.log(isString('rattail')) 31 | ``` 32 | 33 | ### 为什么不是 Lodash? 34 | 35 | `Rattail` 不是 [Lodash](https://lodash.com/) 的替代品,也不是函数式编程解决方案。`Rattail` 旨在为更多应用场景提供更加实用的工具。 36 | -------------------------------------------------------------------------------- /docs/zh/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | hero: 5 | name: 'Rattail' 6 | text: '实用工具库' 7 | tagline: 面向前端开发人员的实用工具库,轻量级且 ts 友好 8 | actions: 9 | - theme: brand 10 | text: 快速开始 11 | link: /zh/getting-started 12 | - theme: alt 13 | text: 查看源码 14 | link: https://github.com/varletjs/rattail 15 | 16 | features: 17 | - title: 通用 18 | details: 提供日常开发中经常使用的实用工具 19 | - title: 测试覆盖 20 | details: 确保 99% 以上单元测试覆盖率,提供稳定性保证 21 | - title: 轻量 22 | details: 工具实现非常轻量 23 | - title: Ts 友好 24 | details: 使用 ts 编写,提供完善的类型支持 25 | --- 26 | -------------------------------------------------------------------------------- /docs/zh/math/ceil.md: -------------------------------------------------------------------------------- 1 | # ceil 2 | 3 | 返回向上取整到指定精度的数字。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { ceil } from 'rattail' 9 | 10 | ceil(1.004) // return 2 11 | ceil(1.004, 2) // return 1.01 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----------- | :------: | -----: | 18 | | `val` | `number` | | 19 | | `precision` | `number` | `0` | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :------: | 25 | | `number` | 26 | -------------------------------------------------------------------------------- /docs/zh/math/floor.md: -------------------------------------------------------------------------------- 1 | # floor 2 | 3 | 返回向下取整到指定精度的数字。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { floor } from 'rattail' 9 | 10 | floor(1.005) // return 1 11 | floor(1.0015, 3) // return 1.001 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----------- | :------: | -----: | 18 | | `val` | `number` | | 19 | | `precision` | `number` | `0` | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :------: | 25 | | `number` | 26 | -------------------------------------------------------------------------------- /docs/zh/math/max-by.md: -------------------------------------------------------------------------------- 1 | # maxBy 2 | 3 | 在 `数组` 中查找通过函数应用到每个元素后的 `最大值`。如果数组为空,则返回 `undefined`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { maxBy } from 'rattail' 9 | 10 | maxBy([{ n: 5 }, { n: 10 }, { n: 8 }], ({ n }) => n) 11 | // return { n: 10 } 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----- | :------------------: | -----: | 18 | | `arr` | `T[]` | | 19 | | `fn` | `(val: T) => number` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :---------------: | 25 | | `T \| undefined` | 26 | -------------------------------------------------------------------------------- /docs/zh/math/mean-by.md: -------------------------------------------------------------------------------- 1 | # meanBy 2 | 3 | 通过对 `数组` 的每个元素应用一个函数以得出数值,计算数组的平均值。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { meanBy } from 'rattail' 9 | 10 | meanBy([{ n: 4 }, { n: 6 }, { n: 8 }], ({ n }) => n) 11 | // return 6 12 | meanBy([10, 20, 30], (n) => n / 2) 13 | // return 10 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ----- | :------------------: | -----: | 20 | | `arr` | `T[]` | | 21 | | `fn` | `(val: T) => number` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | :------: | 27 | | `number` | 28 | -------------------------------------------------------------------------------- /docs/zh/math/mean.md: -------------------------------------------------------------------------------- 1 | # mean 2 | 3 | 计算数字数组的平均值。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { mean } from 'rattail' 9 | 10 | mean([1, 2, 3, 4, 5]) // return 3 11 | mean([10, 20, 30]) // return 20 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----- | :--------: | -----: | 18 | | `arr` | `number[]` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :------: | 24 | | `number` | 25 | -------------------------------------------------------------------------------- /docs/zh/math/min-by.md: -------------------------------------------------------------------------------- 1 | # minBy 2 | 3 | 在 `数组` 中查找通过函数应用到每个元素后的 `最小值`。如果数组为空,则返回 `undefined`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { minBy } from 'rattail' 9 | 10 | minBy([{ n: 5 }, { n: 2 }, { n: 8 }], ({ n }) => n) 11 | // return { n: 2 } 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----- | :------------------: | -----: | 18 | | `arr` | `T[]` | | 19 | | `fn` | `(val: T) => number` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :---------------: | 25 | | `T \| undefined` | 26 | -------------------------------------------------------------------------------- /docs/zh/math/round.md: -------------------------------------------------------------------------------- 1 | # round 2 | 3 | 返回四舍五入到指定精度的数字。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { round } from 'rattail' 9 | 10 | round(1.005) // return 1 11 | round(1.005, 2) // return 1.01 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----------- | :------: | -----: | 18 | | `val` | `number` | | 19 | | `precision` | `number` | `0` | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :------: | 25 | | `number` | 26 | -------------------------------------------------------------------------------- /docs/zh/math/sample.md: -------------------------------------------------------------------------------- 1 | # sample 2 | 3 | 从 `数组` 中返回一个随机元素。如果数组为空,则返回 `undefined`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { sample } from 'rattail' 9 | 10 | sample([1, 2, 3, 4, 5]) // return 一个随机元素,例如 3 11 | sample([]) // return undefined 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----- | :---: | -----: | 18 | | `arr` | `T[]` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :---------------: | 24 | | `T \| undefined` | 25 | -------------------------------------------------------------------------------- /docs/zh/math/sum-by.md: -------------------------------------------------------------------------------- 1 | # sumBy 2 | 3 | 根据提供的函数计算 `数组` 中各项值的和。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { sumBy } from 'rattail' 9 | 10 | sumBy([{ n: 1 }, { n: 2 }, { n: 3 }], ({ n }) => n) // return 6 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ----- | ---------------------- | ------ | 17 | | `arr` | `Array` | | 18 | | `fn` | `(val: any) => number` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | -------- | 24 | | `number` | 25 | -------------------------------------------------------------------------------- /docs/zh/math/sum-hash.md: -------------------------------------------------------------------------------- 1 | # sumHash 2 | 3 | 为给定的值计算一个哈希值。哈希值是基于值的属性和内容生成的,并返回哈希的十六进制字符串表示。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { sumHash } from 'rattail' 9 | 10 | sumHash('123') 11 | // return '1a3a267c' 12 | sumHash({ a: '123' }) 13 | // return 'b1c920ac' 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ------- | :---: | -----: | 20 | | `value` | `any` | | 21 | 22 | ### 返回值 23 | 24 | | 类型 | 25 | | :------: | 26 | | `string` | 27 | -------------------------------------------------------------------------------- /docs/zh/math/sum.md: -------------------------------------------------------------------------------- 1 | # sum 2 | 3 | 计算数字 `数组` 中各项值的和。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { sum } from 'rattail' 9 | 10 | sum([1, 2, 3]) // return 6 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ----- | ---------- | ------ | 17 | | `arr` | `number[]` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | -------- | 23 | | `number` | 24 | -------------------------------------------------------------------------------- /docs/zh/number/clamp-array-range.md: -------------------------------------------------------------------------------- 1 | # clampArrayRange 2 | 3 | 将索引限制在数组长度的范围内。确保索引至少为 `0`,最大为 `arr.length - 1` 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { clampArrayRange } from 'rattail' 9 | 10 | const arr = ['a', 'b', 'c'] 11 | clampArrayRange(1, arr) // return 1 12 | clampArrayRange(-1, arr) // return 0 13 | clampArrayRange(5, arr) // return 2 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ------- | :------: | -----: | 20 | | `index` | `number` | | 21 | | `arr` | `Array` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | :------: | 27 | | `number` | 28 | -------------------------------------------------------------------------------- /docs/zh/number/clamp.md: -------------------------------------------------------------------------------- 1 | # clamp 2 | 3 | 将数字限制在 `min` 和 `max` 的范围内。如果数字小于 `min`,则返回 `min`;如果大于 `max`,则返回 `max` 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { clamp } from 'rattail' 9 | 10 | clamp(5, 1, 10) // return 5 11 | clamp(0, 1, 10) // return 1 12 | clamp(15, 1, 10) // return 10 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ----- | :------: | -----: | 19 | | `num` | `number` | | 20 | | `min` | `number` | | 21 | | `max` | `number` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | :------: | 27 | | `number` | 28 | -------------------------------------------------------------------------------- /docs/zh/number/delay.md: -------------------------------------------------------------------------------- 1 | # delay 2 | 3 | 创建一个在指定的毫秒数后完成的 `promise`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { delay } from 'rattail' 9 | 10 | console.log('Start') 11 | await delay(1000) 12 | console.log('End after 1 second') 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ----------- | :------: | -----: | 19 | | `time (ms)` | `number` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :-------------: | 25 | | `Promise` | 26 | -------------------------------------------------------------------------------- /docs/zh/number/gen-number-key.md: -------------------------------------------------------------------------------- 1 | # genNumberKey 2 | 3 | 生成一个唯一的数值键,每次调用后递增 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { genNumberKey } from 'rattail' 9 | 10 | genNumberKey() // return 0 11 | genNumberKey() // return 1 12 | genNumberKey() // return 2 13 | ``` 14 | 15 | ### 返回值 16 | 17 | | 类型 | 18 | | :------: | 19 | | `number` | 20 | -------------------------------------------------------------------------------- /docs/zh/number/random-number.md: -------------------------------------------------------------------------------- 1 | # randomNumber 2 | 3 | 生成一个在 `min` 和 `max` 范围内的随机整数(包含 `min` 和 `max`)。如果没有提供值,默认为 `0` 到 `100` 的范围。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { randomNumber } from 'rattail' 9 | 10 | randomNumber(1, 10) // return 1 到 10 之间的随机整数 11 | randomNumber() // return 0 或 100(默认范围) 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ----- | :------: | -----: | 18 | | `min` | `number` | `0` | 19 | | `max` | `number` | `100` | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :------: | 25 | | `number` | 26 | -------------------------------------------------------------------------------- /docs/zh/number/times.md: -------------------------------------------------------------------------------- 1 | # times 2 | 3 | 执行指定次数的函数调用,并返回结果数组。每次调用会传入当前索引。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { times } from 'rattail' 9 | 10 | times(3, (index) => index * 2) 11 | // return [0, 2, 4] 12 | times(5, (index) => `Item ${index}`) 13 | // return ['Item 0', 'Item 1', 'Item 2', 'Item 3', 'Item 4'] 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ----- | :----------------------: | -----: | 20 | | `num` | `number` | | 21 | | `fn` | `(index: number) => any` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | :-----: | 27 | | `Array` | 28 | -------------------------------------------------------------------------------- /docs/zh/number/to-number.md: -------------------------------------------------------------------------------- 1 | # toNumber 2 | 3 | 将输入值转换为数字。如果值为 `null` 或 `undefined`,返回 `0`。如果值为布尔值,`true` 转换为 `1`,`false` 转换为 `0`。如果值是字符串且不能解析为数字,返回 `0` 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { toNumber } from 'rattail' 9 | 10 | toNumber('123') // return 123 11 | toNumber(true) // return 1 12 | toNumber(false) // return 0 13 | toNumber('abc') // return 0 14 | toNumber(null) // return 0 15 | ``` 16 | 17 | ### 参数 18 | 19 | | 参数 | 类型 | 默认值 | 20 | | ------- | :---: | -----: | 21 | | `value` | `any` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | :------: | 27 | | `number` | 28 | -------------------------------------------------------------------------------- /docs/zh/object/map-object.md: -------------------------------------------------------------------------------- 1 | # mapObject 2 | 3 | 将传入的对象映射成一个新的对象。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { mapObject } from 'rattail' 9 | 10 | mapObject({ a: 1, b: 2 }, (key, value) => [key, value * 2]) 11 | // return { a: 2, b: 4 } 12 | mapObject({ a: 1, b: 2 }, (key, value) => [`${key}${value}`, value]) 13 | // return { a1: 1, b2: 2 } 14 | mapObject({ a: 1, b: 2 }, (key, value) => (value === 1 ? [key, value] : undefined)) 15 | // return { a: 1 } 16 | ``` 17 | 18 | ### 参数 19 | 20 | | 参数 | 类型 | 默认值 | 21 | | -------- | --------------------------------------------------------------------- | ------ | 22 | | `object` | `object` | | 23 | | `fn` | `(key: string, value: any) => [key: string, value: any] \| undefined` | | 24 | 25 | ### 返回值 26 | 27 | | 类型 | 28 | | -------- | 29 | | `object` | 30 | -------------------------------------------------------------------------------- /docs/zh/object/omit-by.md: -------------------------------------------------------------------------------- 1 | # omitBy 2 | 3 | 通过提供一个函数来排除对象属性并构造成一个新的对象, 返回 `真值` 表示需要排除该属性。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { omitBy } from 'rattail' 9 | 10 | omitBy({ a: 1, b: 2, c: 3 }, (value) => value > 1) 11 | // return { a: 1 } 12 | omitBy({ a: 1, b: 2, c: 3 }, (value, key) => key !== 'a') 13 | // return { a: 1 } 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | -------- | ---------------------------------- | ------ | 20 | | `object` | `object` | | 21 | | `fn` | `(value: any, key: string) => any` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | -------- | 27 | | `object` | 28 | -------------------------------------------------------------------------------- /docs/zh/object/omit.md: -------------------------------------------------------------------------------- 1 | # omit 2 | 3 | 排除对象属性并构造成一个新的对象。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { omit } from 'rattail' 9 | 10 | omit({ a: 1, b: 2, c: 3 }, ['a', 'c']) 11 | // return { b: 2 } 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | -------- | ---------- | ------ | 18 | | `object` | `object` | | 19 | | `keys` | `string[]` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | -------- | 25 | | `object` | 26 | -------------------------------------------------------------------------------- /docs/zh/object/pick-by.md: -------------------------------------------------------------------------------- 1 | # pickBy 2 | 3 | 通过提供一个函数来提取对象属性并构造成一个新的对象, 返回 `真值` 表示需要提取该属性。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { pickBy } from 'rattail' 9 | 10 | pickBy({ a: 1, b: 2, c: 3 }, (value) => value > 1) 11 | // return { b: 2, c: 3 } 12 | pickBy({ a: 1, b: 2, c: 3 }, (value, key) => key !== 'a') 13 | // return { b: 2, c: 3 } 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | -------- | ---------------------------------- | ------ | 20 | | `object` | `object` | | 21 | | `fn` | `(value: any, key: string) => any` | | 22 | 23 | ### 返回值 24 | 25 | | 类型 | 26 | | -------- | 27 | | `object` | 28 | -------------------------------------------------------------------------------- /docs/zh/object/pick.md: -------------------------------------------------------------------------------- 1 | # pick 2 | 3 | 提取对象属性并构造成一个新的对象。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { pick } from 'rattail' 9 | 10 | pick({ a: 1, b: 2, c: 3 }, ['a', 'c']) 11 | // return { a: 1, c: 3 } 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | -------- | ---------- | ------ | 18 | | `object` | `object` | | 19 | | `keys` | `string[]` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | -------- | 25 | | `object` | 26 | -------------------------------------------------------------------------------- /docs/zh/object/promise-with-resolvers.md: -------------------------------------------------------------------------------- 1 | # promiseWithResolvers 2 | 3 | 返回一个对象,其中包含一个新的 `Promise 对象` 以及 `resolve`,`reject` 两个函数用于解决或拒绝它。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { promiseWithResolvers } from 'rattail' 9 | 10 | const { promise, resolve } = promiseWithResolvers() 11 | 12 | setTimeout(() => { 13 | resolve('hello') 14 | }, 300) 15 | 16 | await promise 17 | // 300ms 后 return 'hello' 18 | ``` 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | ------------------------------------------------------------------------------------------ | 24 | | `{ promise: Promise; resolve: (value: any) => void; reject: (reason?: any) => void }` | 25 | -------------------------------------------------------------------------------- /docs/zh/string/camelize.md: -------------------------------------------------------------------------------- 1 | # camelize 2 | 3 | 将字符串转换为 `camelCase` 格式。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { camelize } from 'rattail' 9 | 10 | camelize('hello-world') // return 'helloWorld' 11 | camelize('FooBar') // return 'fooBar' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :------: | -----: | 18 | | `value` | `string` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/zh/string/ensure-prefix.md: -------------------------------------------------------------------------------- 1 | # ensurePrefix 2 | 3 | 确保 `字符串` 存在某个前缀,如果不存在则添加该前缀。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { ensurePrefix } from 'rattail' 9 | 10 | ensurePrefix('prefix-hello-world', 'prefix-') // return 'prefix-hello-world' 11 | ensurePrefix('hello-world', 'prefix-') // return 'prefix-hello-world' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | -------- | :------: | -----: | 18 | | `value` | `string` | | 19 | | `prefix` | `string` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :------: | 25 | | `string` | 26 | -------------------------------------------------------------------------------- /docs/zh/string/ensure-suffix.md: -------------------------------------------------------------------------------- 1 | # ensureSuffix 2 | 3 | 确保 `字符串` 存在某个后缀,如果不存在则添加该后缀。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { ensureSuffix } from 'rattail' 9 | 10 | ensureSuffix('hello-world-suffix', '-suffix') // return 'hello-world-suffix' 11 | ensureSuffix('hello-world', '-suffix') // return 'hello-world-suffix' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | -------- | :------: | -----: | 18 | | `value` | `string` | | 19 | | `suffix` | `string` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | :------: | 25 | | `string` | 26 | -------------------------------------------------------------------------------- /docs/zh/string/gen-string-key.md: -------------------------------------------------------------------------------- 1 | # genStringKey 2 | 3 | 生成一个唯一的 `字符串键`,通过递增数字值并将其转换为字符串。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { genStringKey } from 'rattail' 9 | 10 | genStringKey() // return 'generated-key-0' 11 | genStringKey() // return 'generated-key-1' 12 | genStringKey() // return 'generated-key-2' 13 | ``` 14 | 15 | ### 返回值 16 | 17 | | 类型 | 18 | | :------: | 19 | | `string` | 20 | -------------------------------------------------------------------------------- /docs/zh/string/kebab-case.md: -------------------------------------------------------------------------------- 1 | # kebabCase 2 | 3 | 将字符串转换为 `kebab-case` 格式。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { kebabCase } from 'rattail' 9 | 10 | kebabCase('HelloWorld') // return 'hello-world' 11 | kebabCase('fooBar') // return 'foo-bar' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :------: | -----: | 18 | | `value` | `string` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/zh/string/lower-first.md: -------------------------------------------------------------------------------- 1 | # lowerFirst 2 | 3 | 将 `字符串` 的 `首字母` 小写,其余部分保持不变。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { lowerFirst } from 'rattail' 9 | 10 | upperFirst('Hello') // return 'hello' 11 | upperFirst('Rattail') // return 'rattail' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :------: | -----: | 18 | | `value` | `string` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/zh/string/pascal-case.md: -------------------------------------------------------------------------------- 1 | # pascalCase 2 | 3 | 将字符串转换为 `PascalCase`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { pascalCase } from 'rattail' 9 | 10 | pascalCase('hello-world') // return 'HelloWorld' 11 | pascalCase('fooBar') // return 'FooBar' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :------: | -----: | 18 | | `value` | `string` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/zh/string/random-color.md: -------------------------------------------------------------------------------- 1 | # randomColor 2 | 3 | 生成一个随机的十六进制颜色字符串。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { randomColor } from 'rattail' 9 | 10 | randomColor() // 生成一个随机的十六进制颜色,例如: '#a1b2c3' 11 | ``` 12 | 13 | ### 参数 14 | 15 | 无 16 | 17 | ### 返回值 18 | 19 | | 类型 | 20 | | :------: | 21 | | `string` | 22 | -------------------------------------------------------------------------------- /docs/zh/string/random-string.md: -------------------------------------------------------------------------------- 1 | # randomString 2 | 3 | 生成指定长度的随机字符串。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { randomString } from 'rattail' 9 | 10 | randomString() // 生成一个长度为 10 的随机字符串 11 | randomString(30) // 生成一个长度为 30 的随机字符串 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | -------- | :------: | -----: | 18 | | `length` | `number` | `10` | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/zh/string/slash.md: -------------------------------------------------------------------------------- 1 | # slash 2 | 3 | 将路径中的所有反斜杠 (`\`) 转换为正斜杠 (`/`)。如果路径以 `\\?\` 开头(表示扩展长度路径),则保持不变。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { slash } from 'rattail' 9 | 10 | slash('C:\\path\\to\\file') 11 | // return 'C:/path/to/file' 12 | slash('\\\\?\\C:\\path\\to\\file') 13 | // return '\\\\?\\C:\\path\\to\\file' (保持不变) 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | ------ | :------: | -----: | 20 | | `path` | `string` | | 21 | 22 | ### 返回值 23 | 24 | | 类型 | 25 | | :------: | 26 | | `string` | 27 | -------------------------------------------------------------------------------- /docs/zh/string/upper-first.md: -------------------------------------------------------------------------------- 1 | # upperFirst 2 | 3 | 将 `字符串` 的 `首字母` 大写,其余部分保持不变。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { capitalizeFirstLetter } from 'rattail' 9 | 10 | capitalizeFirstLetter('hello world') // return 'Hello world' 11 | capitalizeFirstLetter('rattail') // return 'Rattail' 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | ------- | :------: | -----: | 18 | | `value` | `string` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | :------: | 24 | | `string` | 25 | -------------------------------------------------------------------------------- /docs/zh/util/cancel-animation-frame.md: -------------------------------------------------------------------------------- 1 | # cancelAnimationFrame 2 | 3 | 使用给定的句柄取消 `requestAnimationFrame` 请求,并使用 `clearTimeout` 作为回退选项。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { cancelAnimationFrame } from 'rattail' 9 | 10 | const handle = requestAnimationFrame(() => {}) 11 | cancelAnimationFrame(handle) 12 | ``` 13 | 14 | ### 参数 15 | 16 | | 参数 | 类型 | 默认值 | 17 | | -------- | -------- | ------ | 18 | | `handle` | `number` | | 19 | 20 | ### 返回值 21 | 22 | | 类型 | 23 | | ------ | 24 | | `void` | 25 | -------------------------------------------------------------------------------- /docs/zh/util/classes.md: -------------------------------------------------------------------------------- 1 | # classes 2 | 3 | 根据给定条件生成类名列表,或直接返回类名。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { classes } from 'rattail' 9 | 10 | classes('a', [true, 'b', 'c']) 11 | // return ['a', 'b'] 12 | classes('a', [false, 'b', 'c']) 13 | // return ['a', 'c'] 14 | ``` 15 | 16 | ### 参数 17 | 18 | | 参数 | 类型 | 默认值 | 19 | | --------- | ----------------- | ------ | 20 | | `...args` | `string \| Array` | | 21 | 22 | ### 返回值 23 | 24 | | 类型 | 25 | | ------- | 26 | | `any[]` | 27 | -------------------------------------------------------------------------------- /docs/zh/util/copy-text.md: -------------------------------------------------------------------------------- 1 | # copyText 2 | 3 | 复制文本到剪贴板。 4 | 5 | ### 用法 6 | 7 | ```js 8 | import { copyText } from 'rattail' 9 | 10 | copyText('Hello, clipboard!') // 字符串会被写入剪切板 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ------ | -------- | ------ | 17 | | `text` | `string` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | ---- | 23 | | `-` | 24 | -------------------------------------------------------------------------------- /docs/zh/util/create-namespace-fn.md: -------------------------------------------------------------------------------- 1 | # createNamespaceFn 2 | 3 | 创建一个命名空间函数,用于生成 BEM 样式的组件和类名。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { createNamespaceFn } from 'rattail' 9 | 10 | const ns = createNamespaceFn('my-app') 11 | const bem = ns('button') 12 | console.log(bem.n('--active')) 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ----------- | -------- | ------ | 19 | | `namespace` | `string` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | -------------------------------------------------- | 25 | | `{ name: string; n: Function; classes: Function }` | 26 | -------------------------------------------------------------------------------- /docs/zh/util/double-raf.md: -------------------------------------------------------------------------------- 1 | # doubleRaf 2 | 3 | 创建一个基于 `Promise` 的双重 `requestAnimationFrame`,在两帧之后 `resolved`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { doubleRaf } from 'rattail' 9 | 10 | await doubleRaf() 11 | console.log('两帧后') 12 | ``` 13 | 14 | ### 返回值 15 | 16 | | 类型 | 17 | | --------------- | 18 | | `Promise` | 19 | -------------------------------------------------------------------------------- /docs/zh/util/download.md: -------------------------------------------------------------------------------- 1 | # download 2 | 3 | 触发浏览器下载,支持通过 `文件地址`、`Blob`、`File`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { download } from 'rattail' 9 | 10 | download('/hello.txt', 'hello.txt') 11 | download(new Blob(['hello']), 'hello.txt') 12 | download(new File(['helle'], 'hello.txt', { type: 'text/plain' }), 'hello.txt') 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ---------- | ------------------------ | ------ | 19 | | `value` | `string \| Blob \| File` | | 20 | | `filename` | `string` | `file` | 21 | -------------------------------------------------------------------------------- /docs/zh/util/get-all-parent-scroller.md: -------------------------------------------------------------------------------- 1 | # getAllParentScroller 2 | 3 | 获取元素的所有可滚动父级元素,包含 `window` 作为最后一项。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { getAllParentScroller } from 'rattail' 9 | 10 | const scrollers = getAllParentScroller(document.querySelector('div')) 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ---- | ------------- | ------ | 17 | | `el` | `HTMLElement` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | ------------------------------ | 23 | | `Array` | 24 | -------------------------------------------------------------------------------- /docs/zh/util/get-parent-scroller.md: -------------------------------------------------------------------------------- 1 | # getParentScroller 2 | 3 | 查找元素的最近可滚动父级元素。如果没有找到滚动父级,则返回 `window`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { getParentScroller } from 'rattail' 9 | 10 | const scroller = getParentScroller(document.querySelector('div')) 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ---- | ------------- | ------ | 17 | | `el` | `HTMLElement` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | ----------------------- | 23 | | `HTMLElement \| Window` | 24 | -------------------------------------------------------------------------------- /docs/zh/util/get-rect.md: -------------------------------------------------------------------------------- 1 | # getRect 2 | 3 | 获取元素或窗口的尺寸和位置,返回一个 `DOMRect` 对象。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { getRect } from 'rattail' 9 | 10 | const rect = getRect(document.querySelector('div')) 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | --------- | --------- | ------ | 17 | | `element` | `Element` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | --------- | 23 | | `DOMRect` | 24 | -------------------------------------------------------------------------------- /docs/zh/util/get-scroll-left.md: -------------------------------------------------------------------------------- 1 | # getScrollLeft 2 | 3 | 获取元素或窗口的水平滚动位置。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { getScrollLeft } from 'rattail' 9 | 10 | const scrollLeft = getScrollLeft(window) 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | --------- | ------------------- | ------ | 17 | | `element` | `Element \| Window` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | -------- | 23 | | `number` | 24 | -------------------------------------------------------------------------------- /docs/zh/util/get-scroll-top.md: -------------------------------------------------------------------------------- 1 | # getScrollTop 2 | 3 | 获取元素或窗口的垂直滚动位置。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { getScrollTop } from 'rattail' 9 | 10 | const scrollTop = getScrollTop(window) 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | --------- | ------------------- | ------ | 17 | | `element` | `Element \| Window` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | -------- | 23 | | `number` | 24 | -------------------------------------------------------------------------------- /docs/zh/util/get-style.md: -------------------------------------------------------------------------------- 1 | # getStyle 2 | 3 | 获取给定 DOM 元素的计算 CSS 样式。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { getStyle } from 'rattail' 9 | 10 | const elementStyle = getStyle(document.querySelector('div')) 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | --------- | --------- | ------ | 17 | | `element` | `Element` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | --------------------- | 23 | | `CSSStyleDeclaration` | 24 | -------------------------------------------------------------------------------- /docs/zh/util/in-viewport.md: -------------------------------------------------------------------------------- 1 | # inViewport 2 | 3 | 判断元素是否在视口内可见。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { inViewport } from 'rattail' 9 | 10 | const isVisible = inViewport(document.querySelector('div')) 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | --------- | ------------- | ------ | 17 | | `element` | `HTMLElement` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | --------- | 23 | | `boolean` | 24 | -------------------------------------------------------------------------------- /docs/zh/util/mitt.md: -------------------------------------------------------------------------------- 1 | # mitt 2 | 3 | 事件调度器,集成了 [mitt](https://github.com/developit/mitt)。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { mitt } from 'rattail' 9 | 10 | const emitter = mitt() 11 | 12 | // 监听特定事件 13 | emitter.on('foo', (e) => { 14 | console.log('foo', e) 15 | }) 16 | 17 | // 监听所有的事件 18 | emitter.on('*', (type, e) => { 19 | console.log(type, e) 20 | }) 21 | 22 | // 触发事件 23 | emitter.emit('foo', { a: 'b' }) 24 | 25 | // 清理所有的事件处理器 26 | emitter.all.clear() 27 | 28 | // 监听事件 / 卸载事件 29 | emitter.on('foo', onFoo) 30 | emitter.off('foo', onFoo) 31 | 32 | function onFoo() {} 33 | ``` 34 | 35 | ### API 36 | 37 | [Reference](https://github.com/developit/mitt) 38 | -------------------------------------------------------------------------------- /docs/zh/util/pretty-JSON-object.md: -------------------------------------------------------------------------------- 1 | # prettyJSONObject 2 | 3 | 格式化 `JSON` 对象,增加缩进以便于阅读。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { prettyJSONObject } from 'rattail' 9 | 10 | const jsonObject = { key: 'value', nested: { key: 'nestedValue' } } 11 | const pretty = prettyJSONObject(jsonObject) 12 | console.log(pretty) 13 | /* 14 | { 15 | "key": "value", 16 | "nested": { 17 | "key": "nestedValue" 18 | } 19 | } 20 | */ 21 | ``` 22 | 23 | ### 参数 24 | 25 | | 参数 | 类型 | 默认值 | 26 | | ------------ | -------- | ------ | 27 | | `jsonObject` | `object` | | 28 | 29 | ### 返回值 30 | 31 | | 类型 | 32 | | -------- | 33 | | `string` | 34 | -------------------------------------------------------------------------------- /docs/zh/util/prevent-default.md: -------------------------------------------------------------------------------- 1 | # preventDefault 2 | 3 | 阻止事件的默认行为(如果该事件可取消)。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { preventDefault } from 'rattail' 9 | 10 | document.addEventListener('click', preventDefault) 11 | ``` 12 | 13 | ### 参数 14 | 15 | | 参数 | 类型 | 默认值 | 16 | | ------- | ------- | ------ | 17 | | `event` | `Event` | | 18 | 19 | ### 返回值 20 | 21 | | 类型 | 22 | | ------ | 23 | | `void` | 24 | -------------------------------------------------------------------------------- /docs/zh/util/raf.md: -------------------------------------------------------------------------------- 1 | # raf 2 | 3 | 创建一个基于 `Promise` 的 `requestAnimationFrame`,在下一帧时 `resolved`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { raf } from 'rattail' 9 | 10 | await raf() 11 | console.log('下一帧') 12 | ``` 13 | 14 | ### 返回值 15 | 16 | | 类型 | 17 | | --------------- | 18 | | `Promise` | 19 | -------------------------------------------------------------------------------- /docs/zh/util/request-animation-frame.md: -------------------------------------------------------------------------------- 1 | # requestAnimationFrame 2 | 3 | 提供跨浏览器兼容的 `requestAnimationFrame` 函数,并使用 `setTimeout` 作为回退选项。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { requestAnimationFrame } from 'rattail' 9 | 10 | requestAnimationFrame(() => { 11 | console.log('请求了一帧') 12 | }) 13 | ``` 14 | 15 | ### 参数 16 | 17 | | 参数 | 类型 | 默认值 | 18 | | ---- | ------------- | ------ | 19 | | `el` | `HTMLElement` | | 20 | 21 | ### 返回值 22 | 23 | | 类型 | 24 | | ------------------------------ | 25 | | `Array` | 26 | -------------------------------------------------------------------------------- /docs/zh/util/storage.md: -------------------------------------------------------------------------------- 1 | # storage 2 | 3 | 增强 `localStorage` 和 `sessionStorage`,支持数据的自动 json `stringify` 和 `parse`,并保留所有原生 API。 4 | 5 | ### 使用 6 | 7 | #### localStorage 8 | 9 | ```js 10 | import { localStorage } from 'rattail' 11 | 12 | localStorage.set('key', { a: 1 }) // 自动 json stringify 13 | localStorage.get('key') // return { a: 1 },自动 json parse 14 | localStorage.remove('key') // 等价于 localStorage.removeItem('key') 15 | ``` 16 | 17 | #### sessionStorage 18 | 19 | ```js 20 | import { sessionStorage } from 'rattail' 21 | 22 | sessionStorage.set('key', { a: 1 }) // 自动 json stringify 23 | sessionStorage.get('key') // return { a: 1 },自动 json parse 24 | sessionStorage.remove('key') // 等价于 sessionStorage.removeItem('key') 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/zh/util/try-parse-JSON.md: -------------------------------------------------------------------------------- 1 | # tryParseJSON 2 | 3 | 尝试解析 `JSON` 字符串。如果解析失败,返回 `undefined`。 4 | 5 | ### 使用 6 | 7 | ```ts 8 | import { tryParseJSON } from 'rattail' 9 | 10 | const jsonString = '{"key": "value"}' 11 | const parsed = tryParseJSON(jsonString) 12 | console.log(parsed) // { key: "value" } 13 | 14 | const invalidJsonString = '{"key": value}' 15 | const invalidParsed = tryParseJSON(invalidJsonString) 16 | console.log(invalidParsed) // undefined 17 | ``` 18 | 19 | ### 参数 20 | 21 | | 参数 | 类型 | 默认值 | 22 | | ------ | -------- | ------ | 23 | | `json` | `string` | | 24 | 25 | ### 返回值 26 | 27 | | 类型 | 28 | | --------------------- | 29 | | `object \| undefined` | 30 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@configurajs/eslint' 2 | 3 | export default defineConfig({ 4 | ignores: ['lib'], 5 | }) 6 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from '@configurajs/prettier' 2 | 3 | export default defineConfig() 4 | -------------------------------------------------------------------------------- /src/array/at.ts: -------------------------------------------------------------------------------- 1 | export function at(arr: T[], index: number): T | undefined { 2 | if (!arr.length) { 3 | return 4 | } 5 | 6 | if (index < 0) { 7 | index += arr.length 8 | } 9 | 10 | return arr[index] 11 | } 12 | -------------------------------------------------------------------------------- /src/array/chunk.ts: -------------------------------------------------------------------------------- 1 | import { clamp } from '../number' 2 | 3 | export function chunk(arr: T[], size = 1): T[][] { 4 | size = clamp(size, 1, arr.length) 5 | 6 | const result: T[][] = [] 7 | let index = 0 8 | 9 | while (index < arr.length) { 10 | result.push(arr.slice(index, index + size)) 11 | index += size 12 | } 13 | 14 | return result 15 | } 16 | -------------------------------------------------------------------------------- /src/array/difference.ts: -------------------------------------------------------------------------------- 1 | import { differenceWith } from './differenceWith' 2 | 3 | export function difference(arr: T[], ...values: T[][]): T[] { 4 | return differenceWith(arr, ...values, (a, b) => a === b) 5 | } 6 | -------------------------------------------------------------------------------- /src/array/differenceWith.ts: -------------------------------------------------------------------------------- 1 | import { at } from './at' 2 | 3 | type Fn = (a: T, b: T) => any 4 | 5 | export function differenceWith(arr: T[], ...values: [...T[][], fn: Fn]): T[] { 6 | const fn = at(values, -1) as Fn 7 | const targets = (values.slice(0, -1) as T[][]).reduce((targets, value) => [...targets, ...value], []) 8 | 9 | return arr.filter((item) => !targets.some((value) => fn(item, value))) 10 | } 11 | -------------------------------------------------------------------------------- /src/array/find.ts: -------------------------------------------------------------------------------- 1 | export function find( 2 | arr: T[], 3 | fn: (item: T, index: number, array: T[]) => any, 4 | from: 'start' | 'end' = 'start', 5 | ): [T, number] | [null, -1] { 6 | let i = from === 'start' ? 0 : arr.length - 1 7 | 8 | while (arr.length > 0 && i >= 0 && i <= arr.length - 1) { 9 | const flag = fn(arr[i], i, arr) 10 | 11 | if (flag) { 12 | return [arr[i], i] 13 | } 14 | 15 | from === 'start' ? i++ : i-- 16 | } 17 | 18 | return [null, -1] 19 | } 20 | -------------------------------------------------------------------------------- /src/array/groupBy.ts: -------------------------------------------------------------------------------- 1 | type Fn = (val: T) => K 2 | 3 | export function groupBy(arr: T[], fn: Fn): Record { 4 | return arr.reduce( 5 | (result, item) => { 6 | const key = fn(item) 7 | ;(result[key] ??= []).push(item) 8 | return result 9 | }, 10 | {} as Record, 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/array/index.ts: -------------------------------------------------------------------------------- 1 | export * from './at' 2 | export * from './chunk' 3 | export * from './removeItem' 4 | export * from './toggleItem' 5 | export * from './uniq' 6 | export * from './uniqBy' 7 | export * from './find' 8 | export * from './shuffle' 9 | export * from './removeArrayBlank' 10 | export * from './removeArrayEmpty' 11 | export * from './normalizeToArray' 12 | export * from './difference' 13 | export * from './differenceWith' 14 | export * from './intersection' 15 | export * from './intersectionWith' 16 | export * from './groupBy' 17 | export * from './xor' 18 | export * from './xorWith' 19 | -------------------------------------------------------------------------------- /src/array/intersection.ts: -------------------------------------------------------------------------------- 1 | import { intersectionWith } from './intersectionWith' 2 | 3 | export function intersection(...values: T[][]): T[] { 4 | return intersectionWith(...values, (a, b) => a === b) 5 | } 6 | -------------------------------------------------------------------------------- /src/array/intersectionWith.ts: -------------------------------------------------------------------------------- 1 | import { at } from './at' 2 | import { uniqBy } from './uniqBy' 3 | 4 | type Fn = (a: T, b: T) => any 5 | 6 | export function intersectionWith(...values: [...T[][], fn: Fn]): T[] { 7 | const fn = at(values, -1) as Fn 8 | const targets = values.slice(0, -1) as T[][] 9 | 10 | if (targets.length === 0) { 11 | return [] 12 | } 13 | 14 | if (targets.length === 1) { 15 | return uniqBy(targets[0], fn) 16 | } 17 | 18 | function baseIntersectionWith(arr1: T[], arr2: T[]): T[] { 19 | return arr1.filter((item) => arr2.some((value) => fn(item, value))) 20 | } 21 | 22 | return uniqBy( 23 | targets.reduce((result, target) => baseIntersectionWith(result, target)), 24 | fn, 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /src/array/normalizeToArray.ts: -------------------------------------------------------------------------------- 1 | import { isArray } from '../general' 2 | 3 | export function normalizeToArray(value: T | T[]) { 4 | return isArray(value) ? value : [value] 5 | } 6 | -------------------------------------------------------------------------------- /src/array/removeArrayBlank.ts: -------------------------------------------------------------------------------- 1 | export function removeArrayBlank(arr: (T | null | undefined)[]) { 2 | return arr.filter((item) => item != null) as T[] 3 | } 4 | -------------------------------------------------------------------------------- /src/array/removeArrayEmpty.ts: -------------------------------------------------------------------------------- 1 | export function removeArrayEmpty(arr: (T | null | undefined | '')[]) { 2 | return arr.filter((item) => item != null && item !== '') as T[] 3 | } 4 | -------------------------------------------------------------------------------- /src/array/removeItem.ts: -------------------------------------------------------------------------------- 1 | export function removeItem(arr: T[], item: T) { 2 | if (arr.length) { 3 | const index: number = arr.indexOf(item) 4 | if (index > -1) { 5 | return arr.splice(index, 1) 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/array/shuffle.ts: -------------------------------------------------------------------------------- 1 | export function shuffle(arr: T[]): T[] { 2 | for (let i = arr.length - 1; i > 0; i--) { 3 | const j = Math.floor(Math.random() * (i + 1)) 4 | ;[arr[i], arr[j]] = [arr[j], arr[i]] 5 | } 6 | return arr 7 | } 8 | -------------------------------------------------------------------------------- /src/array/toggleItem.ts: -------------------------------------------------------------------------------- 1 | import { removeItem } from './removeItem' 2 | 3 | export function toggleItem(arr: T[], item: T) { 4 | arr.includes(item) ? removeItem(arr, item) : arr.push(item) 5 | return arr 6 | } 7 | -------------------------------------------------------------------------------- /src/array/uniq.ts: -------------------------------------------------------------------------------- 1 | export function uniq(arr: T[]) { 2 | return [...new Set(arr)] 3 | } 4 | -------------------------------------------------------------------------------- /src/array/uniqBy.ts: -------------------------------------------------------------------------------- 1 | export function uniqBy(arr: T[], fn: (a: T, b: T) => any): T[] { 2 | return arr.reduce((ret: T[], i: T) => { 3 | const index = ret.findIndex((j: T) => fn(i, j)) 4 | 5 | if (index === -1) { 6 | ret.push(i) 7 | } 8 | 9 | return ret 10 | }, []) 11 | } 12 | -------------------------------------------------------------------------------- /src/array/xor.ts: -------------------------------------------------------------------------------- 1 | import { xorWith } from './xorWith' 2 | 3 | export function xor(...values: T[][]): T[] { 4 | return xorWith(...values, (a, b) => a === b) 5 | } 6 | -------------------------------------------------------------------------------- /src/array/xorWith.ts: -------------------------------------------------------------------------------- 1 | import { at } from './at' 2 | import { differenceWith } from './differenceWith' 3 | import { uniqBy } from './uniqBy' 4 | 5 | type Fn = (a: T, b: T) => any 6 | 7 | export function xorWith(...values: [...T[][], fn: Fn]): T[] { 8 | const fn = at(values, -1) as Fn 9 | const targets = values.slice(0, -1) as T[][] 10 | 11 | return uniqBy( 12 | targets.reduce((result, target) => { 13 | return [...differenceWith(result, target, fn), ...differenceWith(target, result, fn)] 14 | }), 15 | fn, 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /src/collection/cloneDeep.ts: -------------------------------------------------------------------------------- 1 | import { cloneDeepWith } from './cloneDeepWith' 2 | 3 | export function cloneDeep(value: T): T { 4 | return cloneDeepWith(value, () => undefined) 5 | } 6 | -------------------------------------------------------------------------------- /src/collection/index.ts: -------------------------------------------------------------------------------- 1 | export * from './cloneDeep' 2 | export * from './cloneDeepWith' 3 | export * from './merge' 4 | export * from './mergeWith' 5 | -------------------------------------------------------------------------------- /src/collection/merge.ts: -------------------------------------------------------------------------------- 1 | import { mergeWith } from './mergeWith' 2 | 3 | export function merge, K extends Record>(object: T, ...sources: K[]) { 4 | return mergeWith(object, ...sources, () => undefined) 5 | } 6 | -------------------------------------------------------------------------------- /src/file/index.ts: -------------------------------------------------------------------------------- 1 | export * from './toArrayBuffer' 2 | export * from './toDataURL' 3 | export * from './toText' 4 | -------------------------------------------------------------------------------- /src/file/toArrayBuffer.ts: -------------------------------------------------------------------------------- 1 | export function toArrayBuffer(file: File): Promise { 2 | return new Promise((resolve) => { 3 | const fileReader = new FileReader() 4 | 5 | fileReader.onload = () => { 6 | resolve(fileReader.result as ArrayBuffer) 7 | } 8 | 9 | fileReader.readAsArrayBuffer(file) 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /src/file/toDataURL.ts: -------------------------------------------------------------------------------- 1 | export function toDataURL(file: File): Promise { 2 | return new Promise((resolve) => { 3 | const fileReader = new FileReader() 4 | 5 | fileReader.onload = () => { 6 | resolve(fileReader.result as string) 7 | } 8 | 9 | fileReader.readAsDataURL(file) 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /src/file/toText.ts: -------------------------------------------------------------------------------- 1 | export function toText(file: File): Promise { 2 | return new Promise((resolve) => { 3 | const fileReader = new FileReader() 4 | 5 | fileReader.onload = () => { 6 | resolve(fileReader.result as string) 7 | } 8 | 9 | fileReader.readAsText(file) 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /src/function/NOOP.ts: -------------------------------------------------------------------------------- 1 | export function NOOP() {} 2 | -------------------------------------------------------------------------------- /src/function/call.ts: -------------------------------------------------------------------------------- 1 | import { isArray } from '../general' 2 | 3 | export function call

( 4 | fn?: ((...arg: P) => R) | ((...arg: P) => R)[] | null, 5 | ...args: P 6 | ): R | R[] | undefined { 7 | if (isArray(fn)) { 8 | return fn.map((f) => f(...args)) 9 | } 10 | 11 | if (fn) { 12 | return fn(...args) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/function/debounce.ts: -------------------------------------------------------------------------------- 1 | export function debounce any>(fn: F, delay = 0) { 2 | let timer: any 3 | 4 | return function (this: unknown, ...args: Parameters) { 5 | if (timer) { 6 | clearTimeout(timer) 7 | } 8 | 9 | timer = setTimeout(() => { 10 | fn.apply(this, args) 11 | }, delay) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/function/index.ts: -------------------------------------------------------------------------------- 1 | export * from './call' 2 | export * from './once' 3 | export * from './debounce' 4 | export * from './throttle' 5 | export * from './NOOP' 6 | -------------------------------------------------------------------------------- /src/function/once.ts: -------------------------------------------------------------------------------- 1 | export function once any>(fn: F) { 2 | let called = false 3 | let result: ReturnType 4 | 5 | return function (this: unknown, ...args: Parameters): ReturnType { 6 | if (called) { 7 | return result 8 | } 9 | 10 | called = true 11 | result = fn.apply(this, args) 12 | return result 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/function/throttle.ts: -------------------------------------------------------------------------------- 1 | export function throttle any>(fn: F, delay = 200) { 2 | let timer: any 3 | let start = 0 4 | 5 | return function loop(this: unknown, ...args: Parameters) { 6 | const now = performance.now() 7 | const elapsed = now - start 8 | 9 | if (!start) { 10 | start = now 11 | } 12 | 13 | if (timer) { 14 | clearTimeout(timer) 15 | } 16 | 17 | if (elapsed >= delay) { 18 | fn.apply(this, args) 19 | start = now 20 | } else { 21 | timer = setTimeout(() => { 22 | loop.apply(this, args) 23 | }, delay - elapsed) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/general/assert.ts: -------------------------------------------------------------------------------- 1 | export function assert(condition: boolean, message: string): asserts condition { 2 | if (!condition) { 3 | throw new Error(message) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/general/getGlobalThis.ts: -------------------------------------------------------------------------------- 1 | import { inBrowser } from './inBrowser' 2 | 3 | export function getGlobalThis() { 4 | if (typeof globalThis !== 'undefined') { 5 | return globalThis 6 | } 7 | 8 | if (inBrowser()) { 9 | return window 10 | } 11 | 12 | return typeof global !== 'undefined' ? global : self 13 | } 14 | -------------------------------------------------------------------------------- /src/general/hasOwn.ts: -------------------------------------------------------------------------------- 1 | const { hasOwnProperty } = Object.prototype 2 | 3 | export function hasOwn(val: T, key: PropertyKey): key is keyof T { 4 | return hasOwnProperty.call(val, key) 5 | } 6 | -------------------------------------------------------------------------------- /src/general/inBrowser.ts: -------------------------------------------------------------------------------- 1 | export function inBrowser() { 2 | return typeof window !== 'undefined' 3 | } 4 | -------------------------------------------------------------------------------- /src/general/inMobile.ts: -------------------------------------------------------------------------------- 1 | import { inBrowser } from './inBrowser' 2 | 3 | export function inMobile() { 4 | return inBrowser() && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isArray.ts: -------------------------------------------------------------------------------- 1 | export function isArray(val: unknown): val is any[] { 2 | return Array.isArray(val) 3 | } 4 | -------------------------------------------------------------------------------- /src/general/isArrayBuffer.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isArrayBuffer(val: unknown): val is ArrayBuffer { 4 | return toRawType(val) === 'ArrayBuffer' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isBlob.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isBlob(val: unknown): val is Blob { 4 | return toRawType(val) === 'Blob' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isBoolean.ts: -------------------------------------------------------------------------------- 1 | export function isBoolean(val: unknown): val is boolean { 2 | return typeof val === 'boolean' 3 | } 4 | -------------------------------------------------------------------------------- /src/general/isDOMException.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isDOMException(val: unknown): val is DOMException { 4 | return toRawType(val) === 'DOMException' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isDataView.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isDataView(val: unknown): val is DataView { 4 | return toRawType(val) === 'DataView' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isDate.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isDate(val: unknown): val is Date { 4 | return toRawType(val) === 'Date' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isEmpty.ts: -------------------------------------------------------------------------------- 1 | import { isArray } from './isArray' 2 | 3 | export function isEmpty(val: unknown) { 4 | return val === undefined || val === null || val === '' || (isArray(val) && !val.length) 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isEmptyPlainObject.ts: -------------------------------------------------------------------------------- 1 | import { isPlainObject } from './isPlainObject' 2 | 3 | export function isEmptyPlainObject(val: unknown): val is Record { 4 | return isPlainObject(val) && Object.keys(val).length === 0 && Object.getOwnPropertySymbols(val).length === 0 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isEqual.ts: -------------------------------------------------------------------------------- 1 | import { isEqualWith } from './isEqualWith' 2 | 3 | export function isEqual(value: any, other: any): boolean { 4 | return isEqualWith(value, other, () => undefined) 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isError.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isError(val: unknown): val is Error { 4 | return toRawType(val) === 'Error' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isFile.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isFile(val: unknown): val is File { 4 | return toRawType(val) === 'File' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isFunction.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type 2 | export function isFunction(val: unknown): val is Function { 3 | return typeof val === 'function' 4 | } 5 | -------------------------------------------------------------------------------- /src/general/isMap.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isMap(val: unknown): val is Map { 4 | return toRawType(val) === 'Map' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isNonEmptyArray.ts: -------------------------------------------------------------------------------- 1 | import { isArray } from './isArray' 2 | 3 | export function isNonEmptyArray(val: unknown): val is any[] { 4 | return isArray(val) && !!val.length 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isNullish.ts: -------------------------------------------------------------------------------- 1 | export function isNullish(val: T | null | undefined): val is NonNullable { 2 | return val == null 3 | } 4 | -------------------------------------------------------------------------------- /src/general/isNumber.ts: -------------------------------------------------------------------------------- 1 | export function isNumber(val: unknown): val is number { 2 | return typeof val === 'number' 3 | } 4 | -------------------------------------------------------------------------------- /src/general/isNumeric.ts: -------------------------------------------------------------------------------- 1 | import { isNumber } from './isNumber' 2 | import { isString } from './isString' 3 | 4 | export function isNumeric(val: unknown): val is number | string { 5 | return isNumber(val) || (isString(val) && /^[-+]?\d+$/.test(val)) 6 | } 7 | -------------------------------------------------------------------------------- /src/general/isObject.ts: -------------------------------------------------------------------------------- 1 | export function isObject(val: unknown): val is Record { 2 | return typeof val === 'object' && val !== null 3 | } 4 | -------------------------------------------------------------------------------- /src/general/isPlainObject.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isPlainObject(val: unknown): val is Record { 4 | return toRawType(val) === 'Object' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isPrimitive.ts: -------------------------------------------------------------------------------- 1 | export function isPrimitive(val: unknown): boolean { 2 | return val == null || (typeof val !== 'object' && typeof val !== 'function') 3 | } 4 | -------------------------------------------------------------------------------- /src/general/isPromise.ts: -------------------------------------------------------------------------------- 1 | import { isFunction } from './isFunction' 2 | import { isObject } from './isObject' 3 | 4 | export function isPromise(val: unknown): val is Promise { 5 | return isObject(val) && isFunction(val.then) && isFunction(val.catch) 6 | } 7 | -------------------------------------------------------------------------------- /src/general/isRegExp.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isRegExp(val: unknown): val is RegExp { 4 | return toRawType(val) === 'RegExp' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isSet.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isSet(val: unknown): val is Set { 4 | return toRawType(val) === 'Set' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isString.ts: -------------------------------------------------------------------------------- 1 | export function isString(val: unknown): val is string { 2 | return typeof val === 'string' 3 | } 4 | -------------------------------------------------------------------------------- /src/general/isSymbol.ts: -------------------------------------------------------------------------------- 1 | export function isSymbol(val: unknown): val is symbol { 2 | return typeof val === 'symbol' 3 | } 4 | -------------------------------------------------------------------------------- /src/general/isTruthy.ts: -------------------------------------------------------------------------------- 1 | export function isTruthy(v: T): v is NonNullable { 2 | return Boolean(v) 3 | } 4 | -------------------------------------------------------------------------------- /src/general/isTypedArray.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isTypedArray( 4 | val: unknown, 5 | ): val is 6 | | Int8Array 7 | | Uint8Array 8 | | Uint8ClampedArray 9 | | Int16Array 10 | | Uint16Array 11 | | Int32Array 12 | | Uint32Array 13 | | Float32Array 14 | | Float64Array 15 | | BigInt64Array 16 | | BigUint64Array { 17 | return [ 18 | 'Int8Array', 19 | 'Uint8Array', 20 | 'Uint8ClampedArray', 21 | 'Int16Array', 22 | 'Uint16Array', 23 | 'Int32Array', 24 | 'Uint32Array', 25 | 'Float32Array', 26 | 'Float64Array', 27 | 'BigInt64Array', 28 | 'BigUint64Array', 29 | ].includes(toRawType(val)) 30 | } 31 | -------------------------------------------------------------------------------- /src/general/isWeakMap.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isWeakMap(val: unknown): val is WeakMap { 4 | return toRawType(val) === 'WeakMap' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isWeakSet.ts: -------------------------------------------------------------------------------- 1 | import { toRawType } from './toRawType' 2 | 3 | export function isWeakSet(val: unknown): val is WeakSet { 4 | return toRawType(val) === 'WeakSet' 5 | } 6 | -------------------------------------------------------------------------------- /src/general/isWindow.ts: -------------------------------------------------------------------------------- 1 | export function isWindow(val: unknown): val is Window { 2 | return val === window 3 | } 4 | -------------------------------------------------------------------------------- /src/general/supportTouch.ts: -------------------------------------------------------------------------------- 1 | import { inBrowser } from './inBrowser' 2 | 3 | export function supportTouch() { 4 | return inBrowser() && 'ontouchstart' in window 5 | } 6 | -------------------------------------------------------------------------------- /src/general/toRawType.ts: -------------------------------------------------------------------------------- 1 | import { toTypeString } from './toTypeString' 2 | 3 | export function toRawType(value: unknown): string { 4 | return toTypeString(value).slice(8, -1) 5 | } 6 | -------------------------------------------------------------------------------- /src/general/toTypeString.ts: -------------------------------------------------------------------------------- 1 | export const objectToString: typeof Object.prototype.toString = Object.prototype.toString 2 | 3 | export function toTypeString(value: unknown): string { 4 | return objectToString.call(value) 5 | } 6 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './array' 2 | export * from './object' 3 | export * from './util' 4 | export * from './function' 5 | export * from './general' 6 | export * from './number' 7 | export * from './string' 8 | export * from './collection' 9 | export * from './file' 10 | export * from './math' 11 | -------------------------------------------------------------------------------- /src/math/ceil.ts: -------------------------------------------------------------------------------- 1 | import { baseRound } from './round' 2 | 3 | export function ceil(val: number, precision: number = 0) { 4 | return baseRound(val, precision, Math.ceil) 5 | } 6 | -------------------------------------------------------------------------------- /src/math/floor.ts: -------------------------------------------------------------------------------- 1 | import { baseRound } from './round' 2 | 3 | export function floor(val: number, precision: number = 0) { 4 | return baseRound(val, precision, Math.floor) 5 | } 6 | -------------------------------------------------------------------------------- /src/math/index.ts: -------------------------------------------------------------------------------- 1 | export * from './maxBy' 2 | export * from './minBy' 3 | export * from './sum' 4 | export * from './sumBy' 5 | export * from './sumHash' 6 | export * from './mean' 7 | export * from './meanBy' 8 | export * from './sample' 9 | export * from './round' 10 | export * from './floor' 11 | export * from './ceil' 12 | -------------------------------------------------------------------------------- /src/math/maxBy.ts: -------------------------------------------------------------------------------- 1 | export function maxBy(arr: T[], fn: (val: T) => number) { 2 | return arr.reduce((result, item) => (fn(result) > fn(item) ? result : item), arr[0]) 3 | } 4 | -------------------------------------------------------------------------------- /src/math/mean.ts: -------------------------------------------------------------------------------- 1 | import { sum } from './sum' 2 | 3 | export function mean(arr: number[]) { 4 | return sum(arr) / arr.length 5 | } 6 | -------------------------------------------------------------------------------- /src/math/meanBy.ts: -------------------------------------------------------------------------------- 1 | import { sumBy } from './sumBy' 2 | 3 | export function meanBy(arr: T[], fn: (val: T) => number) { 4 | return sumBy(arr, fn) / arr.length 5 | } 6 | -------------------------------------------------------------------------------- /src/math/minBy.ts: -------------------------------------------------------------------------------- 1 | export function minBy(arr: T[], fn: (val: T) => number) { 2 | return arr.reduce((result, item) => (fn(result) < fn(item) ? result : item), arr[0]) 3 | } 4 | -------------------------------------------------------------------------------- /src/math/round.ts: -------------------------------------------------------------------------------- 1 | import { clamp } from '../number' 2 | 3 | export function round(val: number, precision: number = 0) { 4 | return baseRound(val, precision, Math.round) 5 | } 6 | 7 | export function baseRound(val: number, precision: number, fn: (val: number) => number) { 8 | precision = clamp(precision ?? 0, -292, 292) 9 | 10 | if (!precision) { 11 | return fn(val) 12 | } 13 | 14 | const value = fn(`${val}e${precision}` as any) 15 | return +`${value}e${-precision}` 16 | } 17 | -------------------------------------------------------------------------------- /src/math/sample.ts: -------------------------------------------------------------------------------- 1 | import { randomNumber } from '../number' 2 | 3 | export function sample(arr: T[]) { 4 | if (!arr.length) { 5 | return 6 | } 7 | 8 | return arr[randomNumber(0, arr.length - 1)] 9 | } 10 | -------------------------------------------------------------------------------- /src/math/sum.ts: -------------------------------------------------------------------------------- 1 | export function sum(arr: number[]) { 2 | return arr.reduce((ret, val) => ret + val, 0) 3 | } 4 | -------------------------------------------------------------------------------- /src/math/sumBy.ts: -------------------------------------------------------------------------------- 1 | export function sumBy(arr: T[], fn: (val: T) => number) { 2 | return arr.reduce((ret, val) => ret + fn(val), 0) 3 | } 4 | -------------------------------------------------------------------------------- /src/number/clamp.ts: -------------------------------------------------------------------------------- 1 | export function clamp(num: number, min: number, max: number) { 2 | return Math.min(max, Math.max(min, num)) 3 | } 4 | -------------------------------------------------------------------------------- /src/number/clampArrayRange.ts: -------------------------------------------------------------------------------- 1 | import { clamp } from './clamp' 2 | 3 | export function clampArrayRange(index: number, arr: unknown[]) { 4 | return clamp(index, 0, arr.length - 1) 5 | } 6 | -------------------------------------------------------------------------------- /src/number/delay.ts: -------------------------------------------------------------------------------- 1 | export function delay(time: number) { 2 | return new Promise((resolve) => { 3 | setTimeout(resolve, time) 4 | }) 5 | } 6 | -------------------------------------------------------------------------------- /src/number/genNumberKey.ts: -------------------------------------------------------------------------------- 1 | let key = 0 2 | 3 | export function genNumberKey() { 4 | return key++ 5 | } 6 | -------------------------------------------------------------------------------- /src/number/index.ts: -------------------------------------------------------------------------------- 1 | export * from './clamp' 2 | export * from './clampArrayRange' 3 | export * from './delay' 4 | export * from './randomNumber' 5 | export * from './times' 6 | export * from './toNumber' 7 | export * from './genNumberKey' 8 | -------------------------------------------------------------------------------- /src/number/randomNumber.ts: -------------------------------------------------------------------------------- 1 | export function randomNumber(min = 0, max = 100) { 2 | return Math.floor(Math.random() * (max - min + 1)) + min 3 | } 4 | -------------------------------------------------------------------------------- /src/number/times.ts: -------------------------------------------------------------------------------- 1 | export function times(num: number, fn: (index: number) => T): T[] { 2 | return Array.from({ length: num }, (_, index) => fn(index)) 3 | } 4 | -------------------------------------------------------------------------------- /src/number/toNumber.ts: -------------------------------------------------------------------------------- 1 | import { isBoolean, isString } from '../general' 2 | 3 | export function toNumber(val: number | string | boolean | undefined | null): number { 4 | if (val == null) { 5 | return 0 6 | } 7 | 8 | if (isString(val)) { 9 | val = parseFloat(val) 10 | val = Number.isNaN(val) ? 0 : val 11 | return val 12 | } 13 | 14 | if (isBoolean(val)) { 15 | return Number(val) 16 | } 17 | 18 | return val 19 | } 20 | -------------------------------------------------------------------------------- /src/object/index.ts: -------------------------------------------------------------------------------- 1 | export * from './pick' 2 | export * from './pickBy' 3 | export * from './omit' 4 | export * from './omitBy' 5 | export * from './mapObject' 6 | export * from './promiseWithResolvers' 7 | -------------------------------------------------------------------------------- /src/object/mapObject.ts: -------------------------------------------------------------------------------- 1 | import { isArray } from '../general' 2 | 3 | export function mapObject( 4 | object: Record, 5 | fn: (key: K, value: V) => [PropertyKey, NV] | undefined, 6 | ): Record { 7 | return Object.entries(object).reduce( 8 | (result, [key, value]) => { 9 | const entry = fn(key as K, value as V) 10 | 11 | if (isArray(entry)) { 12 | const [newKey, newValue] = entry 13 | result[newKey as NK] = newValue 14 | } 15 | 16 | return result 17 | }, 18 | {} as Record, 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /src/object/omit.ts: -------------------------------------------------------------------------------- 1 | export function omit(object: T, keys: K[]): Omit { 2 | const ownKeys = [...Object.keys(object), ...Object.getOwnPropertySymbols(object)] 3 | 4 | return ownKeys.reduce( 5 | (result, key) => { 6 | if (!keys.includes(key as K)) { 7 | result[key as keyof typeof result] = object[key as keyof typeof result] 8 | } 9 | 10 | return result 11 | }, 12 | {} as Omit, 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/object/omitBy.ts: -------------------------------------------------------------------------------- 1 | export function omitBy(object: T, fn: (value: any, key: keyof T) => any): Partial { 2 | const ownKeys = [...Object.keys(object), ...Object.getOwnPropertySymbols(object)] 3 | 4 | return ownKeys.reduce((result, key) => { 5 | const value = object[key as keyof typeof object] 6 | 7 | if (!fn(value, key as keyof T)) { 8 | result[key as keyof typeof result] = value 9 | } 10 | 11 | return result 12 | }, {} as Partial) 13 | } 14 | -------------------------------------------------------------------------------- /src/object/pick.ts: -------------------------------------------------------------------------------- 1 | export function pick(object: T, keys: K[]): Pick { 2 | return keys.reduce( 3 | (result, key) => { 4 | result[key] = object[key] 5 | return result 6 | }, 7 | {} as Pick, 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /src/object/pickBy.ts: -------------------------------------------------------------------------------- 1 | export function pickBy(object: T, fn: (value: any, key: keyof T) => any): Partial { 2 | const ownKeys = [...Object.keys(object), ...Object.getOwnPropertySymbols(object)] 3 | 4 | return ownKeys.reduce((result, key) => { 5 | const value = object[key as keyof typeof object] 6 | 7 | if (fn(value, key as keyof T)) { 8 | result[key as keyof typeof result] = value 9 | } 10 | 11 | return result 12 | }, {} as Partial) 13 | } 14 | -------------------------------------------------------------------------------- /src/object/promiseWithResolvers.ts: -------------------------------------------------------------------------------- 1 | export type PromiseWithResolvers = { 2 | promise: Promise 3 | resolve: (value: T | PromiseLike) => void 4 | reject: (reason?: any) => void 5 | } 6 | 7 | export function promiseWithResolvers(): PromiseWithResolvers { 8 | let resolve: any 9 | let reject: any 10 | 11 | const promise = new Promise((_resolver, _reject) => { 12 | resolve = _resolver 13 | reject = _reject 14 | }) 15 | 16 | return { promise, resolve, reject } 17 | } 18 | -------------------------------------------------------------------------------- /src/string/camelize.ts: -------------------------------------------------------------------------------- 1 | export function camelize(s: string): string { 2 | s = s.replace(/[-_](\w)/g, (_: any, p: string) => p.toUpperCase()) 3 | return s.replace(s.charAt(0), s.charAt(0).toLowerCase()) 4 | } 5 | -------------------------------------------------------------------------------- /src/string/ensurePrefix.ts: -------------------------------------------------------------------------------- 1 | export function ensurePrefix(s: string, prefix: string) { 2 | return s.startsWith(prefix) ? s : prefix + s 3 | } 4 | -------------------------------------------------------------------------------- /src/string/ensureSuffix.ts: -------------------------------------------------------------------------------- 1 | export function ensureSuffix(s: string, suffix: string) { 2 | return s.endsWith(suffix) ? s : s + suffix 3 | } 4 | -------------------------------------------------------------------------------- /src/string/genStringKey.ts: -------------------------------------------------------------------------------- 1 | let key = 0 2 | 3 | export function genStringKey() { 4 | return `generated-key-${key++}` 5 | } 6 | -------------------------------------------------------------------------------- /src/string/index.ts: -------------------------------------------------------------------------------- 1 | export * from './camelize' 2 | export * from './ensurePrefix' 3 | export * from './ensureSuffix' 4 | export * from './genStringKey' 5 | export * from './kebabCase' 6 | export * from './pascalCase' 7 | export * from './lowerFirst' 8 | export * from './upperFirst' 9 | export * from './randomColor' 10 | export * from './randomString' 11 | export * from './slash' 12 | -------------------------------------------------------------------------------- /src/string/kebabCase.ts: -------------------------------------------------------------------------------- 1 | export function kebabCase(s: string): string { 2 | const ret = s 3 | .replace(/([A-Z])/g, ' $1') 4 | .replace(/[_\s]+/g, '-') 5 | .trim() 6 | return ret.replace(/^-/, '').toLowerCase() 7 | } 8 | -------------------------------------------------------------------------------- /src/string/lowerFirst.ts: -------------------------------------------------------------------------------- 1 | export function lowerFirst(s: string) { 2 | return s.charAt(0).toLowerCase() + s.slice(1) 3 | } 4 | -------------------------------------------------------------------------------- /src/string/pascalCase.ts: -------------------------------------------------------------------------------- 1 | import { camelize } from './camelize' 2 | 3 | export function pascalCase(s: string): string { 4 | const ret = camelize(s) 5 | return ret.replace(ret.charAt(0), ret.charAt(0).toUpperCase()) 6 | } 7 | -------------------------------------------------------------------------------- /src/string/randomColor.ts: -------------------------------------------------------------------------------- 1 | export function randomColor() { 2 | const letters = '0123456789abcdef' 3 | let color = '#' 4 | 5 | for (let i = 0; i < 6; i++) { 6 | color += letters[Math.floor(Math.random() * 16)] 7 | } 8 | 9 | return color 10 | } 11 | -------------------------------------------------------------------------------- /src/string/randomString.ts: -------------------------------------------------------------------------------- 1 | export function randomString(length = 10) { 2 | let str = baseRandomString() 3 | 4 | while (str.length < length) { 5 | str += baseRandomString() 6 | } 7 | 8 | function baseRandomString() { 9 | return Math.random().toString(36).slice(2) 10 | } 11 | 12 | return str.slice(0, length) 13 | } 14 | -------------------------------------------------------------------------------- /src/string/slash.ts: -------------------------------------------------------------------------------- 1 | export function slash(path: string) { 2 | const isExtendedLengthPath = path.startsWith('\\\\?\\') 3 | 4 | if (isExtendedLengthPath) { 5 | return path 6 | } 7 | 8 | return path.replace(/\\/g, '/') 9 | } 10 | -------------------------------------------------------------------------------- /src/string/upperFirst.ts: -------------------------------------------------------------------------------- 1 | export function upperFirst(s: string) { 2 | return s.charAt(0).toUpperCase() + s.slice(1) 3 | } 4 | -------------------------------------------------------------------------------- /src/util/cancelAnimationFrame.ts: -------------------------------------------------------------------------------- 1 | import { getGlobalThis } from '../general' 2 | 3 | export function cancelAnimationFrame(handle: number) { 4 | const globalThis = getGlobalThis() 5 | 6 | globalThis.cancelAnimationFrame ? globalThis.cancelAnimationFrame(handle) : globalThis.clearTimeout(handle) 7 | } 8 | -------------------------------------------------------------------------------- /src/util/classes.ts: -------------------------------------------------------------------------------- 1 | import { isArray } from '../general' 2 | 3 | export type ClassName = string | undefined | null 4 | 5 | export type Classes = (ClassName | [any, ClassName, ClassName?])[] 6 | 7 | export function classes(...classes: Classes): any[] { 8 | return classes.map((className) => { 9 | if (isArray(className)) { 10 | const [condition, truthy, falsy = null] = className 11 | return condition ? truthy : falsy 12 | } 13 | 14 | return className 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /src/util/copyText.ts: -------------------------------------------------------------------------------- 1 | export function copyText(value: string) { 2 | if (!value) { 3 | return 4 | } 5 | 6 | const textArea = document.createElement('textarea') 7 | textArea.value = value 8 | textArea.style.position = 'fixed' 9 | textArea.style.opacity = '0' 10 | document.body.appendChild(textArea) 11 | textArea.select() 12 | document.execCommand('copy') 13 | document.body.removeChild(textArea) 14 | } 15 | -------------------------------------------------------------------------------- /src/util/doubleRaf.ts: -------------------------------------------------------------------------------- 1 | import { requestAnimationFrame } from './requestAnimationFrame' 2 | 3 | export function doubleRaf() { 4 | return new Promise((resolve) => { 5 | requestAnimationFrame(() => { 6 | requestAnimationFrame(resolve) 7 | }) 8 | }) 9 | } 10 | -------------------------------------------------------------------------------- /src/util/download.ts: -------------------------------------------------------------------------------- 1 | import { isString } from '../general' 2 | 3 | export function download(val: string | Blob | File, filename: string = 'file') { 4 | const a = document.createElement('a') 5 | a.style.display = 'none' 6 | a.href = isString(val) ? val : URL.createObjectURL(val) 7 | a.download = filename 8 | 9 | document.body.appendChild(a) 10 | a.click() 11 | URL.revokeObjectURL(a.href) 12 | document.body.removeChild(a) 13 | } 14 | -------------------------------------------------------------------------------- /src/util/getAllParentScroller.ts: -------------------------------------------------------------------------------- 1 | import { isWindow } from '../general' 2 | import { getParentScroller } from './getParentScroller' 3 | 4 | export function getAllParentScroller(el: HTMLElement): (HTMLElement | Window)[] { 5 | const allParentScroller: (HTMLElement | Window)[] = [] 6 | let element: HTMLElement | Window = el 7 | 8 | while (!isWindow(element)) { 9 | element = getParentScroller(element) 10 | allParentScroller.push(element) 11 | } 12 | 13 | return allParentScroller 14 | } 15 | -------------------------------------------------------------------------------- /src/util/getParentScroller.ts: -------------------------------------------------------------------------------- 1 | import { getStyle } from './getStyle' 2 | 3 | export function getParentScroller(el: HTMLElement): HTMLElement | Window { 4 | let element = el 5 | 6 | while (element) { 7 | if (!element.parentNode) { 8 | break 9 | } 10 | 11 | element = element.parentNode as HTMLElement 12 | 13 | if (element === document.body || element === document.documentElement) { 14 | break 15 | } 16 | 17 | const scrollRE = /(scroll|auto)/ 18 | const { overflowY, overflow } = getStyle(element) 19 | 20 | if (scrollRE.test(overflowY) || scrollRE.test(overflow)) { 21 | return element 22 | } 23 | } 24 | 25 | return window 26 | } 27 | -------------------------------------------------------------------------------- /src/util/getRect.ts: -------------------------------------------------------------------------------- 1 | import { isWindow } from '../general' 2 | 3 | export function getRect(element: Element | Window): DOMRect { 4 | if (isWindow(element)) { 5 | const width = element.innerWidth 6 | const height = element.innerHeight 7 | const rect = { 8 | x: 0, 9 | y: 0, 10 | top: 0, 11 | left: 0, 12 | right: width, 13 | bottom: height, 14 | width, 15 | height, 16 | } 17 | 18 | return { 19 | ...rect, 20 | toJSON: () => rect, 21 | } 22 | } 23 | 24 | return element.getBoundingClientRect() 25 | } 26 | -------------------------------------------------------------------------------- /src/util/getScrollLeft.ts: -------------------------------------------------------------------------------- 1 | export function getScrollLeft(element: Element | Window) { 2 | const left = 'scrollLeft' in element ? element.scrollLeft : element.scrollX 3 | 4 | return Math.max(left, 0) 5 | } 6 | -------------------------------------------------------------------------------- /src/util/getScrollTop.ts: -------------------------------------------------------------------------------- 1 | export function getScrollTop(element: Element | Window) { 2 | const top = 'scrollTop' in element ? element.scrollTop : element.scrollY 3 | 4 | // iOS scroll bounce cause minus scrollTop 5 | return Math.max(top, 0) 6 | } 7 | -------------------------------------------------------------------------------- /src/util/getStyle.ts: -------------------------------------------------------------------------------- 1 | export function getStyle(element: Element) { 2 | return window.getComputedStyle(element) 3 | } 4 | -------------------------------------------------------------------------------- /src/util/inViewport.ts: -------------------------------------------------------------------------------- 1 | import { getRect } from './getRect' 2 | 3 | export function inViewport(element: HTMLElement) { 4 | const { top, bottom, left, right } = getRect(element) 5 | const { width, height } = getRect(window) 6 | 7 | const xInViewport = left <= width && right >= 0 8 | const yInViewport = top <= height && bottom >= 0 9 | 10 | return xInViewport && yInViewport 11 | } 12 | -------------------------------------------------------------------------------- /src/util/index.ts: -------------------------------------------------------------------------------- 1 | export * from './cancelAnimationFrame' 2 | export * from './classes' 3 | export * from './copyText' 4 | export * from './createNamespaceFn' 5 | export * from './doubleRaf' 6 | export * from './getAllParentScroller' 7 | export * from './getParentScroller' 8 | export * from './getRect' 9 | export * from './getScrollLeft' 10 | export * from './getScrollTop' 11 | export * from './getStyle' 12 | export * from './inViewport' 13 | export * from './prettyJSONObject' 14 | export * from './preventDefault' 15 | export * from './raf' 16 | export * from './requestAnimationFrame' 17 | export * from './storage' 18 | export * from './tryParseJSON' 19 | export * from './download' 20 | export * from './motion' 21 | export * from 'mitt' 22 | export { default as mitt } from 'mitt' 23 | -------------------------------------------------------------------------------- /src/util/prettyJSONObject.ts: -------------------------------------------------------------------------------- 1 | export function prettyJSONObject(jsonObject: Record) { 2 | return JSON.stringify(jsonObject, null, 2) 3 | } 4 | -------------------------------------------------------------------------------- /src/util/preventDefault.ts: -------------------------------------------------------------------------------- 1 | export function preventDefault(event: Event) { 2 | if (event.cancelable === false) { 3 | return 4 | } 5 | 6 | event.preventDefault() 7 | } 8 | -------------------------------------------------------------------------------- /src/util/raf.ts: -------------------------------------------------------------------------------- 1 | import { requestAnimationFrame } from './requestAnimationFrame' 2 | 3 | export function raf() { 4 | return new Promise((resolve) => { 5 | requestAnimationFrame(resolve) 6 | }) 7 | } 8 | -------------------------------------------------------------------------------- /src/util/requestAnimationFrame.ts: -------------------------------------------------------------------------------- 1 | import { getGlobalThis } from '../general' 2 | 3 | export function requestAnimationFrame(fn: FrameRequestCallback): number { 4 | const globalThis = getGlobalThis() 5 | 6 | return globalThis.requestAnimationFrame ? globalThis.requestAnimationFrame(fn) : globalThis.setTimeout(fn) 7 | } 8 | -------------------------------------------------------------------------------- /src/util/tryParseJSON.ts: -------------------------------------------------------------------------------- 1 | export function tryParseJSON(json: string): T | undefined { 2 | try { 3 | return JSON.parse(json) 4 | } catch { 5 | return undefined 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "strict": true, 5 | "declaration": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "downlevelIteration": true, 9 | "resolveJsonModule": true, 10 | "jsx": "preserve", 11 | "lib": ["esnext", "dom"], 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "outDir": "./lib" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config' 2 | 3 | export default defineConfig({ 4 | test: { 5 | environment: 'jsdom', 6 | coverage: { 7 | provider: 'istanbul', 8 | include: ['src/**/*.ts'], 9 | exclude: ['src/function/NOOP.ts', 'src/general/getGlobalThis.ts'], 10 | }, 11 | }, 12 | }) 13 | --------------------------------------------------------------------------------