wip: migrate to bun

This commit is contained in:
jdalton
2023-09-16 14:47:50 -07:00
parent 2da024c3b4
commit 97d4a2fe19
1052 changed files with 30244 additions and 26856 deletions

29
.commitlintrc.js Normal file
View File

@@ -0,0 +1,29 @@
'use strict';
module.exports = {
extends: [
'@commitlint/config-conventional', // scoped packages are not prefixed
],
rules: {
'type-enum': [
2,
'always',
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'perf',
'proposal',
'refactor',
'release',
'revert',
'style',
'test',
'wip',
],
],
},
};

5
.eslintignore Normal file
View File

@@ -0,0 +1,5 @@
coverage/
coverage-merged/
dist/
node_modules/
types/

98
.eslintrc Normal file
View File

@@ -0,0 +1,98 @@
{
"extends": ["airbnb-base", "prettier"],
"root": true,
"env": {
"amd": true,
"browser": true,
"es6": true,
"jest": true,
"node": true
},
"globals": {
"BigInt": "readonly",
"BigInt64Array": "readonly",
"BigUint64Array": "readonly",
"globalThis": "readonly"
},
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": [
"prettier"
],
"rules": {
"prettier/prettier": "error",
// Overridden
"no-eval": "off",
"camelcase": ["error", { "properties": "never", "allow": [ "W[0-9]+_"] }],
"import/extensions": "off",
// @TODO: Fix the following rules progressively.
"arrow-body-style": "warn",
"prefer-arrow-callback": "warn",
"prefer-object-spread": "off",
"max-classes-per-file": "off",
"dot-notation": "off",
"object-shorthand": "off",
"no-param-reassign": "off",
"no-cond-assign": "off",
"prefer-destructuring": "off",
"func-names": "off",
"no-nested-ternary": "off",
"no-plusplus": "off",
"strict": "off",
"no-restricted-syntax": "off",
"import/no-mutable-exports": "off",
"guard-for-in": "off",
"import/prefer-default-export": "off",
"prefer-rest-params": "off",
"one-var": "off",
"prefer-spread": "off",
"no-lonely-if": "off",
"no-prototype-builtins": "off",
"no-continue": "off",
"no-shadow": "off",
// Rules up for discussion.
"no-multi-assign": "off",
"new-cap": "off"
},
"overrides": [
{
"files": ["**/*.ts"],
"parserOptions": {
"project": "./tsconfig.json"
},
"extends": [
"airbnb-typescript/base",
"prettier"
],
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/no-unused-vars": [
"warn",
{
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true,
"argsIgnorePattern": "^_" // For tsc compatibility.
}
],
"comma-dangle": "off",
"implicit-arrow-linebreak": "off", // Conflicts with prettier.
"import/extensions": "off",
"import/prefer-default-export": "off",
"operator-linebreak": "off",
"object-curly-newline": "off",
"prefer-rest-params": "off", // We need to use params.
"prettier/prettier": "error",
"@typescript-eslint/no-shadow": "warn",
"@typescript-eslint/no-use-before-define": ["warn", { "functions": false }],
"import/no-cycle": "warn",
"no-bitwise": "off",
"no-unsafe-finally": "warn",
"no-param-reassign": "off",
"no-shadow": "warn"
}
}
]
}

View File

@@ -1,125 +0,0 @@
module.exports = {
'extends': ['plugin:import/errors'],
'plugins': ['import'],
'env': {
'es6': true,
'node': true
},
'parserOptions': {
'ecmaVersion': 6,
'sourceType': 'module',
'ecmaFeatures': {
'impliedStrict': true,
'objectLiteralDuplicateProperties': false
}
},
'rules': {
'array-bracket-spacing': ['error', 'never'],
'camelcase': ['error', {
'properties': 'never'
}],
'comma-dangle': ['error', 'never'],
'curly': ['error', 'all'],
'eol-last': ['error'],
'indent': ['error', 2, {
'SwitchCase': 1
}],
'keyword-spacing': ['error'],
'max-len': ['error', {
'code': 180,
'ignoreComments': true,
'ignoreRegExpLiterals': true
}],
'no-else-return': ['error'],
'no-mixed-spaces-and-tabs': ['error'],
'no-multiple-empty-lines': ['error'],
'no-spaced-func': ['error'],
'no-trailing-spaces': ['error'],
'no-undef': ['error'],
'no-unexpected-multiline': ['error'],
'no-unused-vars': ['error', {
'args': 'none',
'vars': 'all'
}],
'quotes': ['error', 'single', {
'allowTemplateLiterals': true,
'avoidEscape': true
}],
'semi': ['error', 'never'],
'space-before-blocks': ['error', 'always'],
'space-before-function-paren': ['error', 'never'],
'space-in-parens': ['error', 'never'],
'space-unary-ops': ['error', {
'nonwords': false,
'overrides': {}
}],
// 'valid-jsdoc': ['error']
// ECMAScript 6 rules
'arrow-body-style': ['error', 'as-needed', {
'requireReturnForObjectLiteral': false
}],
'arrow-parens': ['error', 'always'],
'arrow-spacing': ['error', {
'after': true,
'before': true
}],
'no-class-assign': ['error'],
'no-const-assign': ['error'],
'no-dupe-class-members': ['error'],
'no-duplicate-imports': ['error'],
'no-new-symbol': ['error'],
'no-useless-rename': ['error'],
'no-var': ['error'],
'object-shorthand': ['error', 'always', {
'avoidQuotes': true,
'ignoreConstructors': false
}],
'prefer-arrow-callback': ['error', {
'allowNamedFunctions': false,
'allowUnboundThis': true
}],
'prefer-const': ['error'],
'prefer-rest-params': ['error'],
'prefer-template': ['error'],
'template-curly-spacing': ['error', 'never']
}
};

1
.gitattributes vendored
View File

@@ -1 +1,2 @@
* text=auto
*.lockb binary diff=lockb

5
.gitignore vendored
View File

@@ -1,7 +1,8 @@
.DS_Store
*.log*
doc/*.html
node_modules
dist/
node_modules/
*.code-workspace
*.lockb
*.sublime-project
*.sublime-workspace

1
.husky/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
_

4
.husky/commit-msg Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
bun run commitlint --edit "$1"

4
.husky/pre-commit Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
bun run lint-staged

5
.prettierignore Normal file
View File

@@ -0,0 +1,5 @@
coverage/
coverage-merged/
dist/
node_modules/
types/

6
.prettierrc Normal file
View File

@@ -0,0 +1,6 @@
{
"printWidth": 100,
"useTabs": false,
"tabWidth": 4,
"singleQuote": true
}

View File

@@ -2,18 +2,14 @@
[Site](https://lodash.com/) |
[Docs](https://lodash.com/docs) |
[FP Guide](https://github.com/lodash/lodash/wiki/FP-Guide) |
[Contributing](https://github.com/lodash/lodash/blob/master/.github/CONTRIBUTING.md) |
[Wiki](https://github.com/lodash/lodash/wiki "Changelog, Roadmap, etc.") |
[Code of Conduct](https://code-of-conduct.openjsf.org) |
[Twitter](https://twitter.com/bestiejs) |
[Chat](https://gitter.im/lodash/lodash)
[Code of Conduct](https://code-of-conduct.openjsf.org)
The [Lodash](https://lodash.com/) library exported as a [UMD](https://github.com/umdjs/umd) module.
Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli):
```shell
$ npm run build
$ bun run build
$ lodash -o ./dist/lodash.js
$ lodash core -o ./dist/lodash.core.js
```
@@ -34,14 +30,12 @@ In a browser:
<script src="lodash.js"></script>
```
Using npm:
Using bun:
```shell
$ npm i -g npm
$ npm i lodash
$ bun i lodash
```
Note: add `--save` if you are using npm < 5.0.0
In Node.js:
In [Bun](https://bun.sh):
```js
// Load the full build.
var _ = require('lodash');
@@ -76,5 +70,3 @@ Lodash is available in a [variety of builds](https://lodash.com/custom-builds) &
* [lodash](https://www.npmjs.com/package/lodash) & [per method packages](https://www.npmjs.com/search?q=keywords:lodash-modularized)
* [lodash-es](https://www.npmjs.com/package/lodash-es), [babel-plugin-lodash](https://www.npmjs.com/package/babel-plugin-lodash), & [lodash-webpack-plugin](https://www.npmjs.com/package/lodash-webpack-plugin)
* [lodash/fp](https://github.com/lodash/lodash/tree/npm/fp)
* [lodash-amd](https://www.npmjs.com/package/lodash-amd)

2
bunfig.toml Normal file
View File

@@ -0,0 +1,2 @@
[install.lockfile]
print = "yarn"

View File

@@ -1,213 +0,0 @@
import isObject from './isObject.js'
import root from './.internal/root.js'
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked, or until the next browser frame is drawn. The debounced function
* comes with a `cancel` method to cancel delayed `func` invocations and a
* `flush` method to immediately invoke them. Provide `options` to indicate
* whether `func` should be invoked on the leading and/or trailing edge of the
* `wait` timeout. The `func` is invoked with the last arguments provided to the
* debounced function. Subsequent calls to the debounced function return the
* result of the last `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the debounced function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until the next tick, similar to `setTimeout` with a timeout of `0`.
*
* If `wait` is omitted in an environment with `requestAnimationFrame`, `func`
* invocation will be deferred until the next frame is drawn (typically about
* 16ms).
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `debounce` and `throttle`.
*
* @since 0.1.0
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0]
* The number of milliseconds to delay; if omitted, `requestAnimationFrame` is
* used (if available).
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=false]
* Specify invoking on the leading edge of the timeout.
* @param {number} [options.maxWait]
* The maximum time `func` is allowed to be delayed before it's invoked.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* // Avoid costly calculations while the window size is in flux.
* jQuery(window).on('resize', debounce(calculateLayout, 150))
*
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
* jQuery(element).on('click', debounce(sendMail, 300, {
* 'leading': true,
* 'trailing': false
* }))
*
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
* const debounced = debounce(batchLog, 250, { 'maxWait': 1000 })
* const source = new EventSource('/stream')
* jQuery(source).on('message', debounced)
*
* // Cancel the trailing debounced invocation.
* jQuery(window).on('popstate', debounced.cancel)
*
* // Check for pending invocations.
* const status = debounced.pending() ? "Pending..." : "Ready"
*/
function debounce(func, wait, options) {
let lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime
let lastInvokeTime = 0
let leading = false
let maxing = false
let trailing = true
// Bypass `requestAnimationFrame` by explicitly setting `wait=0`.
const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function')
if (typeof func !== 'function') {
throw new TypeError('Expected a function')
}
wait = +wait || 0
if (isObject(options)) {
leading = !!options.leading
maxing = 'maxWait' in options
maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait
trailing = 'trailing' in options ? !!options.trailing : trailing
}
function invokeFunc(time) {
const args = lastArgs
const thisArg = lastThis
lastArgs = lastThis = undefined
lastInvokeTime = time
result = func.apply(thisArg, args)
return result
}
function startTimer(pendingFunc, wait) {
if (useRAF) {
root.cancelAnimationFrame(timerId)
return root.requestAnimationFrame(pendingFunc)
}
return setTimeout(pendingFunc, wait)
}
function cancelTimer(id) {
if (useRAF) {
return root.cancelAnimationFrame(id)
}
clearTimeout(id)
}
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTime = time
// Start the timer for the trailing edge.
timerId = startTimer(timerExpired, wait)
// Invoke the leading edge.
return leading ? invokeFunc(time) : result
}
function remainingWait(time) {
const timeSinceLastCall = time - lastCallTime
const timeSinceLastInvoke = time - lastInvokeTime
const timeWaiting = wait - timeSinceLastCall
return maxing
? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting
}
function shouldInvoke(time) {
const timeSinceLastCall = time - lastCallTime
const timeSinceLastInvoke = time - lastInvokeTime
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait))
}
function timerExpired() {
const time = Date.now()
if (shouldInvoke(time)) {
return trailingEdge(time)
}
// Restart the timer.
timerId = startTimer(timerExpired, remainingWait(time))
}
function trailingEdge(time) {
timerId = undefined
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgs) {
return invokeFunc(time)
}
lastArgs = lastThis = undefined
return result
}
function cancel() {
if (timerId !== undefined) {
cancelTimer(timerId)
}
lastInvokeTime = 0
lastArgs = lastCallTime = lastThis = timerId = undefined
}
function flush() {
return timerId === undefined ? result : trailingEdge(Date.now())
}
function pending() {
return timerId !== undefined
}
function debounced(...args) {
const time = Date.now()
const isInvoking = shouldInvoke(time)
lastArgs = args
lastThis = this
lastCallTime = time
if (isInvoking) {
if (timerId === undefined) {
return leadingEdge(lastCallTime)
}
if (maxing) {
// Handle invocations in a tight loop.
timerId = startTimer(timerExpired, wait)
return invokeFunc(lastCallTime)
}
}
if (timerId === undefined) {
timerId = startTimer(timerExpired, wait)
}
return result
}
debounced.cancel = cancel
debounced.flush = flush
debounced.pending = pending
return debounced
}
export default debounce

View File

@@ -1 +0,0 @@
export { default } from './forEach.js'

View File

@@ -1 +0,0 @@
export { default } from './forEachRight.js'

View File

@@ -1 +0,0 @@
export { default } from './head.js'

View File

@@ -1,53 +0,0 @@
import castPath from './.internal/castPath.js'
import isArguments from './isArguments.js'
import isIndex from './.internal/isIndex.js'
import isLength from './isLength.js'
import toKey from './.internal/toKey.js'
/** Used to check objects for own properties. */
const hasOwnProperty = Object.prototype.hasOwnProperty
/**
* Checks if `path` is a direct property of `object`.
*
* @since 5.0.0
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path to check.
* @returns {boolean} Returns `true` if `path` exists, else `false`.
* @see has, hasIn, hasPathIn
* @example
*
* const object = { 'a': { 'b': 2 } }
* const other = create({ 'a': create({ 'b': 2 }) })
*
* hasPath(object, 'a.b')
* // => true
*
* hasPath(object, ['a', 'b'])
* // => true
*/
function hasPath(object, path) {
path = castPath(path, object)
let index = -1
let { length } = path
let result = false
let key
while (++index < length) {
key = toKey(path[index])
if (!(result = object != null && hasOwnProperty.call(object, key))) {
break
}
object = object[key]
}
if (result || ++index != length) {
return result
}
length = object == null ? 0 : object.length
return !!length && isLength(length) && isIndex(key, length) &&
(Array.isArray(object) || isArguments(object))
}
export default hasPath

View File

@@ -1,50 +0,0 @@
import castPath from './.internal/castPath.js'
import isArguments from './isArguments.js'
import isIndex from './.internal/isIndex.js'
import isLength from './isLength.js'
import toKey from './.internal/toKey.js'
/**
* Checks if `path` is a direct property of `object`.
*
* @since 5.0.0
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path to check.
* @returns {boolean} Returns `true` if `path` exists, else `false`.
* @see has, hasIn hasPath
* @example
*
* const object = { 'a': { 'b': 2 } }
* const other = create({ 'a': create({ 'b': 2 }) })
*
* hasPathIn(object, 'a.b')
* // => true
*
* hasPathIn(object, ['a', 'b'])
* // => true
*/
function hasPathIn(object, path) {
path = castPath(path, object)
let index = -1
let { length } = path
let result = false
let key
while (++index < length) {
key = toKey(path[index])
if (!(result = object != null && key in Object(object))) {
break
}
object = object[key]
}
if (result || ++index != length) {
return result
}
length = object == null ? 0 : object.length
return !!length && isLength(length) && isIndex(key, length) &&
(Array.isArray(object) || isArguments(object))
}
export default hasPathIn

View File

@@ -1,35 +0,0 @@
import root from './.internal/root.js'
/** Detect free variable `exports`. */
const freeExports = typeof exports === 'object' && exports !== null && !exports.nodeType && exports
/** Detect free variable `module`. */
const freeModule = freeExports && typeof module === 'object' && module !== null && !module.nodeType && module
/** Detect the popular CommonJS extension `module.exports`. */
const moduleExports = freeModule && freeModule.exports === freeExports
/** Built-in value references. */
const Buffer = moduleExports ? root.Buffer : undefined
/* Built-in method references for those with the same name as other `lodash` methods. */
const nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined
/**
* Checks if `value` is a buffer.
*
* @since 4.3.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
* @example
*
* isBuffer(new Buffer(2))
* // => true
*
* isBuffer(new Uint8Array(2))
* // => false
*/
const isBuffer = nativeIsBuffer || (() => false)
export default isBuffer

View File

@@ -1,69 +0,0 @@
import getTag from './.internal/getTag.js'
import isArguments from './isArguments.js'
import isArrayLike from './isArrayLike.js'
import isBuffer from './isBuffer.js'
import isPrototype from './.internal/isPrototype.js'
import isTypedArray from './isTypedArray.js'
/** Used to check objects for own properties. */
const hasOwnProperty = Object.prototype.hasOwnProperty
/**
* Checks if `value` is an empty object, collection, map, or set.
*
* Objects are considered empty if they have no own enumerable string keyed
* properties.
*
* Array-like values such as `arguments` objects, arrays, buffers, strings, or
* jQuery-like collections are considered empty if they have a `length` of `0`.
* Similarly, maps and sets are considered empty if they have a `size` of `0`.
*
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is empty, else `false`.
* @example
*
* isEmpty(null)
* // => true
*
* isEmpty(true)
* // => true
*
* isEmpty(1)
* // => true
*
* isEmpty([1, 2, 3])
* // => false
*
* isEmpty('abc')
* // => false
*
* isEmpty({ 'a': 1 })
* // => false
*/
function isEmpty(value) {
if (value == null) {
return true
}
if (isArrayLike(value) &&
(Array.isArray(value) || typeof value === 'string' || typeof value.splice === 'function' ||
isBuffer(value) || isTypedArray(value) || isArguments(value))) {
return !value.length
}
const tag = getTag(value)
if (tag == '[object Map]' || tag == '[object Set]') {
return !value.size
}
if (isPrototype(value)) {
return !Object.keys(value).length
}
for (const key in value) {
if (hasOwnProperty.call(value, key)) {
return false
}
}
return true
}
export default isEmpty

View File

@@ -1,30 +0,0 @@
import getTag from './.internal/getTag.js'
import isObjectLike from './isObjectLike.js'
import isPlainObject from './isPlainObject.js'
/**
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
* `SyntaxError`, `TypeError`, or `URIError` object.
*
* @since 3.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an error object, else `false`.
* @example
*
* isError(new Error)
* // => true
*
* isError(Error)
* // => false
*/
function isError(value) {
if (!isObjectLike(value)) {
return false
}
const tag = getTag(value)
return tag == '[object Error]' || tag == '[object DOMException]' ||
(typeof value.message === 'string' && typeof value.name === 'string' && !isPlainObject(value))
}
export default isError

1697
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,21 +3,48 @@
"version": "5.0.0",
"license": "MIT",
"private": true,
"main": "lodash.js",
"engines": {
"node": ">=4.0.0"
},
"main": "dist/lodash.js",
"sideEffects": false,
"scripts": {
"style": "eslint *.js .internal/**/*.js",
"test": "mocha -r esm test/*.test.js",
"validate": "npm run style && npm run test"
"prepare": "husky install",
"lint": "eslint ./src/**/*.ts ./test/**/*.ts"
},
"devDependencies": {
"mocha": "^5.2.0",
"eslint": "^7.16.0",
"eslint-plugin-import": "^2.22.1",
"lodash": "4.17.20",
"esm": "^3.2.25"
}
"@commitlint/cli": "17.7.1",
"@commitlint/config-conventional": "17.7.0",
"@types/eslint": "8.44.2",
"@types/jest": "29.5.5",
"@typescript-eslint/eslint-plugin": "6.7.0",
"@typescript-eslint/parser": "6.7.0",
"eslint": "8.49.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-config-airbnb-typescript": "17.1.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-prettier": "5.0.0",
"husky": "8.0.3",
"lint-staged": "14.0.1",
"lodash": "4.17.21",
"prettier": "3.0.3"
},
"lint-staged": {
"src/**/*.{ts}": [
"eslint --fix"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "bun run commitlint --edit $1"
}
},
"engines": {
"node": "^18.17.1",
"yarn": "^1.22.19"
},
"volta": {
"node": "18.17.1",
"yarn": "1.22.19"
},
"engineStrict": true
}

View File

@@ -1,40 +0,0 @@
/**
* Repeats the given string `n` times.
*
* @since 3.0.0
* @category String
* @param {string} [string=''] The string to repeat.
* @param {number} [n=1] The number of times to repeat the string.
* @returns {string} Returns the repeated string.
* @example
*
* repeat('*', 3)
* // => '***'
*
* repeat('abc', 2)
* // => 'abcabc'
*
* repeat('abc', 0)
* // => ''
*/
function repeat(string, n) {
let result = ''
if (!string || n < 1 || n > Number.MAX_SAFE_INTEGER) {
return result
}
// Leverage the exponentiation by squaring algorithm for a faster repeat.
// See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
do {
if (n % 2) {
result += string
}
n = Math.floor(n / 2)
if (n) {
string += string
}
} while (n)
return result
}
export default repeat

View File

@@ -1,40 +0,0 @@
import copyArray from './.internal/copyArray.js'
import slice from './slice.js'
/**
* Gets `n` random elements at unique keys from `array` up to the
* size of `array`.
*
* @since 4.0.0
* @category Array
* @param {Array} array The array to sample.
* @param {number} [n=1] The number of elements to sample.
* @returns {Array} Returns the random elements.
* @example
*
* sampleSize([1, 2, 3], 2)
* // => [3, 1]
*
* sampleSize([1, 2, 3], 4)
* // => [2, 3, 1]
*/
function sampleSize(array, n) {
n = n == null ? 1 : n
const length = array == null ? 0 : array.length
if (!length || n < 1) {
return []
}
n = n > length ? length : n
let index = -1
const lastIndex = length - 1
const result = copyArray(array)
while (++index < n) {
const rand = index + Math.floor(Math.random() * (lastIndex - index + 1))
const value = result[rand]
result[rand] = result[index]
result[index] = value
}
return slice(result, 0, n)
}
export default sampleSize

View File

@@ -1,33 +0,0 @@
import copyArray from './.internal/copyArray.js'
/**
* Creates an array of shuffled values, using a version of the
* [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
*
* @since 0.1.0
* @category Array
* @param {Array} array The array to shuffle.
* @returns {Array} Returns the new shuffled array.
* @example
*
* shuffle([1, 2, 3, 4])
* // => [4, 1, 3, 2]
*/
function shuffle(array) {
const length = array == null ? 0 : array.length
if (!length) {
return []
}
let index = -1
const lastIndex = length - 1
const result = copyArray(array)
while (++index < length) {
const rand = index + Math.floor(Math.random() * (lastIndex - index + 1))
const value = result[rand]
result[rand] = result[index]
result[index] = value
}
return result
}
export default shuffle

43
size.js
View File

@@ -1,43 +0,0 @@
import getTag from './.internal/getTag.js'
import isArrayLike from './isArrayLike.js'
import isString from './isString.js'
import stringSize from './.internal/stringSize.js'
/** `Object#toString` result references. */
const mapTag = '[object Map]'
const setTag = '[object Set]'
/**
* Gets the size of `collection` by returning its length for array-like
* values or the number of own enumerable string keyed properties for objects.
*
* @since 0.1.0
* @category Collection
* @param {Array|Object|string} collection The collection to inspect.
* @returns {number} Returns the collection size.
* @example
*
* size([1, 2, 3])
* // => 3
*
* size({ 'a': 1, 'b': 2 })
* // => 2
*
* size('pebbles')
* // => 7
*/
function size(collection) {
if (collection == null) {
return 0
}
if (isArrayLike(collection)) {
return isString(collection) ? stringSize(collection) : collection.length
}
const tag = getTag(collection)
if (tag == mapTag || tag == setTag) {
return collection.size
}
return Object.keys(collection).length
}
export default size

View File

@@ -1,42 +0,0 @@
import castSlice from './.internal/castSlice.js'
import hasUnicode from './.internal/hasUnicode.js'
import isRegExp from './isRegExp.js'
import stringToArray from './.internal/stringToArray.js'
/** Used as references for the maximum length and index of an array. */
const MAX_ARRAY_LENGTH = 4294967295
/**
* Splits `string` by `separator`.
*
* **Note:** This method is based on
* [`String#split`](https://mdn.io/String/split).
*
* @since 4.0.0
* @category String
* @param {string} [string=''] The string to split.
* @param {RegExp|string} separator The separator pattern to split by.
* @param {number} [limit] The length to truncate results to.
* @returns {Array} Returns the string segments.
* @example
*
* split('a-b-c', '-', 2)
* // => ['a', 'b']
*/
function split(string, separator, limit) {
limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0
if (!limit) {
return []
}
if (string && (
typeof separator === 'string' ||
(separator != null && !isRegExp(separator))
)) {
if (!separator && hasUnicode(string)) {
return castSlice(stringToArray(string), 0, limit)
}
}
return string.split(separator, limit)
}
export default split

18
src/.eslintrc.cjs Normal file
View File

@@ -0,0 +1,18 @@
'use strict';
const path = require('node:path');
module.exports = {
overrides: [
{
files: ['**/*.{ts}'],
rules: {
'import/no-extraneous-dependencies': [
'error',
// Use package.json from both this package folder and root.
{ packageDir: [__dirname, path.join(__dirname, '../')] },
],
},
},
],
};

Some files were not shown because too many files have changed in this diff Show More