├── .eslintrc
├── .github
├── FUNDING.yml
└── workflows
│ ├── node-aught.yml
│ ├── node-pretest.yml
│ ├── node-tens.yml
│ ├── rebase.yml
│ └── require-allow-edits.yml
├── .gitignore
├── .npmrc
├── .nycrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── auto.js
├── implementation.js
├── index.js
├── package.json
├── polyfill.js
├── shim.js
└── test
├── implementation.js
├── index.js
├── shimmed.js
└── tests.js
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 |
4 | "extends": "@ljharb",
5 |
6 | "rules": {
7 | "id-length": "off",
8 | "new-cap": ["error", {
9 | "capIsNewExceptions": [
10 | "ArrayCreate",
11 | "CompareArrayElements",
12 | "CreateDataPropertyOrThrow",
13 | "GetIntrinsic",
14 | "IsCallable",
15 | "LengthOfArrayLike",
16 | "SortIndexedProperties",
17 | "ToObject",
18 | "ToString",
19 | ],
20 | }],
21 | },
22 |
23 | "overrides": [
24 | {
25 | "files": "test/**",
26 | "rules": {
27 | "max-lines-per-function": "off",
28 | },
29 | },
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [ljharb]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: npm/array.prototype.tosorted
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/workflows/node-aught.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: node.js < 10'
2 |
3 | on: [pull_request, push]
4 |
5 | jobs:
6 | tests:
7 | uses: ljharb/actions/.github/workflows/node.yml@main
8 | with:
9 | range: '< 10'
10 | type: minors
11 | command: npm run tests-only
12 |
13 | node:
14 | name: 'node < 10'
15 | needs: [tests]
16 | runs-on: ubuntu-latest
17 | steps:
18 | - run: 'echo tests completed'
19 |
--------------------------------------------------------------------------------
/.github/workflows/node-pretest.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: pretest/posttest'
2 |
3 | on: [pull_request, push]
4 |
5 | jobs:
6 | tests:
7 | uses: ljharb/actions/.github/workflows/pretest.yml@main
8 |
--------------------------------------------------------------------------------
/.github/workflows/node-tens.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: node.js >= 10'
2 |
3 | on: [pull_request, push]
4 |
5 | jobs:
6 | tests:
7 | uses: ljharb/actions/.github/workflows/node.yml@main
8 | with:
9 | range: '>= 10'
10 | type: minors
11 | command: npm run tests-only
12 |
13 | node:
14 | name: 'node >= 10'
15 | needs: [tests]
16 | runs-on: ubuntu-latest
17 | steps:
18 | - run: 'echo tests completed'
19 |
--------------------------------------------------------------------------------
/.github/workflows/rebase.yml:
--------------------------------------------------------------------------------
1 | name: Automatic Rebase
2 |
3 | on: [pull_request_target]
4 |
5 | jobs:
6 | _:
7 | uses: ljharb/actions/.github/workflows/rebase.yml@main
8 | secrets:
9 | token: ${{ secrets.GITHUB_TOKEN }}
10 |
--------------------------------------------------------------------------------
/.github/workflows/require-allow-edits.yml:
--------------------------------------------------------------------------------
1 | name: Require “Allow Edits”
2 |
3 | on: [pull_request_target]
4 |
5 | jobs:
6 | _:
7 | name: "Require “Allow Edits”"
8 |
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - uses: ljharb/require-allow-edits@main
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
106 | # Only apps should have lockfiles
107 | npm-shrinkwrap.json
108 | package-lock.json
109 | yarn.lock
110 |
111 | .npmignore
112 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
2 | allow-same-version=true
3 | message=v%s
4 |
--------------------------------------------------------------------------------
/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "all": true,
3 | "check-coverage": false,
4 | "reporter": ["text-summary", "text", "html", "json"],
5 | "exclude": [
6 | "coverage",
7 | "test"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [v1.1.4](https://github.com/es-shims/Array.prototype.toSorted/compare/v1.1.3...v1.1.4) - 2024-06-02
9 |
10 | ### Fixed
11 |
12 | - [Refactor] update implementation to match latest spec [`#3`](https://github.com/es-shims/Array.prototype.toSorted/issues/3)
13 |
14 | ### Commits
15 |
16 | - [Dev Deps] update `@es-shims/api`, `@ljharb/eslint-config`, `hasown`, `tape` [`159d118`](https://github.com/es-shims/Array.prototype.toSorted/commit/159d11848629e0468f9f10a1e36001f937c0c6ea)
17 | - [Deps] update `call-bind`, `es-abstract`, `es-errors` [`7d32e67`](https://github.com/es-shims/Array.prototype.toSorted/commit/7d32e67417f436d5e8a66bf8286b9ead9296c4f1)
18 | - [meta] add missing `engines.node` [`b49466b`](https://github.com/es-shims/Array.prototype.toSorted/commit/b49466b473d116b5a53209491163bfd2c3aa89bc)
19 |
20 | ## [v1.1.3](https://github.com/es-shims/Array.prototype.toSorted/compare/v1.1.2...v1.1.3) - 2024-02-04
21 |
22 | ### Commits
23 |
24 | - [Refactor] use `es-errors` where possible, so things that only need those do not need `get-intrinsic` [`6c089a5`](https://github.com/es-shims/Array.prototype.toSorted/commit/6c089a5712a25008daa5d3d9dbc9d4fa7c908a64)
25 | - [Deps] update `call-bind`, `define-properties`, `es-abstract`, `es-shim-unscopables`, `get-intrinsic` [`d096b56`](https://github.com/es-shims/Array.prototype.toSorted/commit/d096b56d30bb5f5b09649f285eee21e22e2db8f9)
26 | - [Dev Deps] update `aud`, `npmignore`, `tape` [`43cea6d`](https://github.com/es-shims/Array.prototype.toSorted/commit/43cea6dfaa05669f6a60bef860f2d6fbf86f167e)
27 | - [Dev Deps] use `hasown` instead of `has` [`cefe5dc`](https://github.com/es-shims/Array.prototype.toSorted/commit/cefe5dc1bbc2699ca03c3e4ae9ce7fc696a76ca8)
28 | - [Dev Deps] update `tape` [`ad8446e`](https://github.com/es-shims/Array.prototype.toSorted/commit/ad8446ecbca6f724458af81da3aa3ffcd3552825)
29 |
30 | ## [v1.1.2](https://github.com/es-shims/Array.prototype.toSorted/compare/v1.1.1...v1.1.2) - 2023-09-07
31 |
32 | ### Commits
33 |
34 | - [actions] use reusable workflows [`b3d4f1d`](https://github.com/es-shims/Array.prototype.toSorted/commit/b3d4f1dff2d0fcd30e5bb7591836f5c5133ef9be)
35 | - [Deps] update `define-properties`, `es-abstract`, `get-intrinsic` [`35ce967`](https://github.com/es-shims/Array.prototype.toSorted/commit/35ce96705f9201f9a416629446c7f8b739a3d0a7)
36 | - [Dev Deps] update `@es-shims/api`, `@ljharb/eslint-config`, `aud`, `tape` [`1a17c6a`](https://github.com/es-shims/Array.prototype.toSorted/commit/1a17c6a3492fbbb99f3543c70036c02e981d974a)
37 |
38 | ## [v1.1.1](https://github.com/es-shims/Array.prototype.toSorted/compare/v1.1.0...v1.1.1) - 2022-11-03
39 |
40 | ### Commits
41 |
42 | - [Deps] update `es-abstract`, `get-intrinsic` [`b10a2a3`](https://github.com/es-shims/Array.prototype.toSorted/commit/b10a2a30772369ed3640741345225799af108e97)
43 | - [actions] update rebase action to use reusable workflow [`8f49d78`](https://github.com/es-shims/Array.prototype.toSorted/commit/8f49d78ac5d679c052d544a7051c3b8e5c449052)
44 | - [Dev Deps] update `aud`, `tape` [`2d2741b`](https://github.com/es-shims/Array.prototype.toSorted/commit/2d2741b6a0e08d1b2dbe675759f33dc3db4924a2)
45 |
46 | ## [v1.1.0](https://github.com/es-shims/Array.prototype.toSorted/compare/v1.0.0...v1.1.0) - 2022-08-14
47 |
48 | ### Commits
49 |
50 | - [Tests] add coverage from https://github.com/tc39/test262/pull/3464 [`2172830`](https://github.com/es-shims/Array.prototype.toSorted/commit/21728306e552c80868753b0147dc5637e57ffd2b)
51 | - [meta] use `npmignore` to autogenerate an npmignore file [`972f761`](https://github.com/es-shims/Array.prototype.toSorted/commit/972f761599aaf97049a005974caa2d9b24581119)
52 | - [New] `shim`/`auto`: add `toSorted` to `Symbol.unscopables` [`2ad9bad`](https://github.com/es-shims/Array.prototype.toSorted/commit/2ad9bad51ab7d2e7cc579f6681809fe495682163)
53 | - [Deps] update `define-properties`, `es-abstract`, `get-intrinsic` [`e7b229d`](https://github.com/es-shims/Array.prototype.toSorted/commit/e7b229dbb0c199661f785dfa0d5403b81ed7811e)
54 | - [Dev Deps] update `@ljharb/eslint-config`, `functions-have-names`, `tape` [`2bccb92`](https://github.com/es-shims/Array.prototype.toSorted/commit/2bccb92d5314e3b86bb3ffc1144f0c86cdca285a)
55 | - [readme] fix link to spec [`0d024e6`](https://github.com/es-shims/Array.prototype.toSorted/commit/0d024e68e3d41b3ec8dbc8aa47e99d8987c91fea)
56 |
57 | ## v1.0.0 - 2022-03-31
58 |
59 | ### Commits
60 |
61 | - initial implementation, tests, readme [`a2882bf`](https://github.com/es-shims/Array.prototype.toSorted/commit/a2882bf9f2a5d0533450a37df13ca3c1b8178bef)
62 | - Initial commit [`f9d05c4`](https://github.com/es-shims/Array.prototype.toSorted/commit/f9d05c4275eeeb841f357c487606cf7c83235651)
63 | - [meta] do not publish workflow files [`ceed80a`](https://github.com/es-shims/Array.prototype.toSorted/commit/ceed80acc95688c872dd8c69292a30589a8a9020)
64 | - [Tests] temporarily use actions instead of composable workflows [`496789b`](https://github.com/es-shims/Array.prototype.toSorted/commit/496789bbfb7da7e2b2cac3398491e6b58b1f169f)
65 | - npm init [`9405760`](https://github.com/es-shims/Array.prototype.toSorted/commit/9405760c2f52001035087a0d60f4e06465e82546)
66 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `tape` [`474180c`](https://github.com/es-shims/Array.prototype.toSorted/commit/474180c1250ec0a0ffabc80aa2733fe4abe65036)
67 | - [meta] add version script [`49a3b80`](https://github.com/es-shims/Array.prototype.toSorted/commit/49a3b802020c54ead862d49365555a67ac786636)
68 | - Only apps should have lockfiles [`0db3a5a`](https://github.com/es-shims/Array.prototype.toSorted/commit/0db3a5a7607be2a7d11fa78ae9c43907e59bdf92)
69 | - [Deps] update `es-abstract` [`35de1c5`](https://github.com/es-shims/Array.prototype.toSorted/commit/35de1c532245469b50bd7296ca8c19470385c622)
70 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 ECMAScript Shims
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # array.prototype.tosorted [![Version Badge][npm-version-svg]][package-url]
2 |
3 | [![dependency status][deps-svg]][deps-url]
4 | [![dev dependency status][dev-deps-svg]][dev-deps-url]
5 | [![License][license-image]][license-url]
6 | [![Downloads][downloads-image]][downloads-url]
7 |
8 | [![npm badge][npm-badge-png]][package-url]
9 |
10 | An ESnext spec-compliant `Array.prototype.toSorted` shim/polyfill/replacement that works as far down as ES3.
11 |
12 | This package implements the [es-shim API](https://github.com/es-shims/api) interface. It works in an ES3-supported environment and complies with the proposed [spec](https://tc39.es/proposal-change-array-by-copy/#sec-array.prototype.toSorted).
13 |
14 | Because `Array.prototype.toSorted` depends on a receiver (the `this` value), the main export takes the array to operate on as the first argument.
15 |
16 | ## Getting started
17 |
18 | ```sh
19 | npm install --save array.prototype.tosorted
20 | ```
21 |
22 | ## Usage/Examples
23 |
24 | ```js
25 | var toSorted = require('array.prototype.tosorted');
26 | var assert = require('assert');
27 |
28 | var input = [5, 4, 3, 2, 1, 0];
29 |
30 | var output = toSorted(input);
31 |
32 | assert.deepEqual(output, [0, 1, 2, 3, 4, 5]);
33 | assert.notEqual(output, input);
34 | assert.deepEqual(input, [5, 4, 3, 2, 1, 0]);
35 | ```
36 |
37 | ```js
38 | var toSorted = require('array.prototype.tosorted');
39 | var assert = require('assert');
40 | /* when Array#toSorted is not present */
41 | delete Array.prototype.toSorted;
42 | var shimmed = toSorted.shim();
43 |
44 | assert.equal(shimmed, toSorted.getPolyfill());
45 | assert.deepEqual(input.toSorted(), toSorted(input));
46 | ```
47 |
48 | ```js
49 | var toSorted = require('array.prototype.tosorted');
50 | var assert = require('assert');
51 | /* when Array#toSorted is present */
52 | var shimmed = toSorted.shim();
53 |
54 | assert.equal(shimmed, Array.prototype.toSorted);
55 | assert.deepEqual(input.toSorted(), toSorted(input));
56 | ```
57 |
58 | ## Tests
59 | Simply clone the repo, `npm install`, and run `npm test`
60 |
61 | [package-url]: https://npmjs.org/package/array.prototype.tosorted
62 | [npm-version-svg]: https://versionbadg.es/es-shims/Array.prototype.toSorted.svg
63 | [deps-svg]: https://david-dm.org/es-shims/Array.prototype.toSorted.svg
64 | [deps-url]: https://david-dm.org/es-shims/Array.prototype.toSorted
65 | [dev-deps-svg]: https://david-dm.org/es-shims/Array.prototype.toSorted/dev-status.svg
66 | [dev-deps-url]: https://david-dm.org/es-shims/Array.prototype.toSorted#info=devDependencies
67 | [npm-badge-png]: https://nodei.co/npm/array.prototype.tosorted.png?downloads=true&stars=true
68 | [license-image]: https://img.shields.io/npm/l/array.prototype.tosorted.svg
69 | [license-url]: LICENSE
70 | [downloads-image]: https://img.shields.io/npm/dm/array.prototype.tosorted.svg
71 | [downloads-url]: https://npm-stat.com/charts.html?package=array.prototype.tosorted
72 |
--------------------------------------------------------------------------------
/auto.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | require('./shim')();
4 |
--------------------------------------------------------------------------------
/implementation.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var ArrayCreate = require('es-abstract/2024/ArrayCreate');
4 | var CompareArrayElements = require('es-abstract/2024/CompareArrayElements');
5 | var CreateDataPropertyOrThrow = require('es-abstract/2024/CreateDataPropertyOrThrow');
6 | var IsCallable = require('es-abstract/2024/IsCallable');
7 | var LengthOfArrayLike = require('es-abstract/2024/LengthOfArrayLike');
8 | var SortIndexedProperties = require('es-abstract/2024/SortIndexedProperties');
9 | var ToObject = require('es-abstract/2024/ToObject');
10 | var ToString = require('es-abstract/2024/ToString');
11 |
12 | var $TypeError = require('es-errors/type');
13 |
14 | module.exports = function toSorted(comparefn) {
15 | if (typeof comparefn !== 'undefined' && !IsCallable(comparefn)) {
16 | throw new $TypeError('`comparefn` must be a function'); // step 1
17 | }
18 |
19 | var O = ToObject(this); // step 2
20 | var len = LengthOfArrayLike(O); // step 3
21 | var A = ArrayCreate(len); // step 4
22 |
23 | // eslint-disable-next-line no-sequences
24 | var SortCompare = (0, function (x, y) { // step 5
25 | return CompareArrayElements(x, y, comparefn); // step 5.a
26 | });
27 |
28 | var sortedList = SortIndexedProperties(O, len, SortCompare, 'read-through-holes'); // step 6
29 |
30 | var j = 0; // step 7
31 | while (j < len) { // step 8
32 | CreateDataPropertyOrThrow(A, ToString(j), sortedList[j]); // step 8.a
33 | j += 1; // step 8.b
34 | }
35 |
36 | return A; // step 9
37 | };
38 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var define = require('define-properties');
4 | var callBind = require('call-bind');
5 |
6 | var implementation = require('./implementation');
7 | var getPolyfill = require('./polyfill');
8 | var polyfill = getPolyfill();
9 | var shim = require('./shim');
10 |
11 | var bound = callBind(polyfill);
12 |
13 | define(bound, {
14 | getPolyfill: getPolyfill,
15 | implementation: implementation,
16 | shim: shim
17 | });
18 |
19 | module.exports = bound;
20 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "array.prototype.tosorted",
3 | "version": "1.1.4",
4 | "description": "An ESnext spec-compliant `Array.prototype.toSorted` shim/polyfill/replacement that works as far down as ES3.",
5 | "main": "index.js",
6 | "exports": {
7 | ".": "./index.js",
8 | "./auto": "./auto.js",
9 | "./polyfill": "./polyfill.js",
10 | "./implementation": "./implementation.js",
11 | "./shim": "./shim.js",
12 | "./package.json": "./package.json"
13 | },
14 | "scripts": {
15 | "prepack": "npmignore --auto --commentLines=autogenerated",
16 | "prepublish": "not-in-publish || npm run prepublishOnly",
17 | "prepublishOnly": "safe-publish-latest",
18 | "lint": "eslint --ext=js,mjs .",
19 | "postlint": "es-shim-api --bound && evalmd README.md",
20 | "pretest": "npm run --silent lint",
21 | "test": "npm run tests-only",
22 | "posttest": "aud --production",
23 | "tests-only": "nyc tape 'test/**/*.js'",
24 | "version": "auto-changelog && git add CHANGELOG.md",
25 | "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
26 | },
27 | "repository": {
28 | "type": "git",
29 | "url": "git+https://github.com/es-shims/Array.prototype.toSorted.git"
30 | },
31 | "keywords": [
32 | "javascript",
33 | "ecmascript",
34 | "shim",
35 | "polyfill",
36 | "es-shim API",
37 | "array",
38 | "sort",
39 | "sorted",
40 | "toSorted"
41 | ],
42 | "author": "Jordan Harband ",
43 | "license": "MIT",
44 | "bugs": {
45 | "url": "https://github.com/es-shims/Array.prototype.toSorted/issues"
46 | },
47 | "homepage": "https://github.com/es-shims/Array.prototype.toSorted#readme",
48 | "dependencies": {
49 | "call-bind": "^1.0.7",
50 | "define-properties": "^1.2.1",
51 | "es-abstract": "^1.23.3",
52 | "es-errors": "^1.3.0",
53 | "es-shim-unscopables": "^1.0.2"
54 | },
55 | "devDependencies": {
56 | "@es-shims/api": "^2.5.0",
57 | "@ljharb/eslint-config": "^21.1.1",
58 | "aud": "^2.0.4",
59 | "auto-changelog": "^2.4.0",
60 | "eslint": "=8.8.0",
61 | "evalmd": "^0.0.19",
62 | "functions-have-names": "^1.2.3",
63 | "has-strict-mode": "^1.0.1",
64 | "hasown": "^2.0.2",
65 | "in-publish": "^2.0.1",
66 | "npmignore": "^0.3.1",
67 | "nyc": "^10.3.2",
68 | "safe-publish-latest": "^2.0.0",
69 | "tape": "^5.7.5"
70 | },
71 | "auto-changelog": {
72 | "output": "CHANGELOG.md",
73 | "template": "keepachangelog",
74 | "unreleased": false,
75 | "commitLimit": false,
76 | "backfillLimit": false,
77 | "hideCredit": true
78 | },
79 | "publishConfig": {
80 | "ignore": [
81 | ".github/workflows"
82 | ]
83 | },
84 | "engines": {
85 | "node": ">= 0.4"
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/polyfill.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var implementation = require('./implementation');
4 |
5 | module.exports = function getPolyfill() {
6 | return Array.prototype.toSorted || implementation;
7 | };
8 |
--------------------------------------------------------------------------------
/shim.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var define = require('define-properties');
4 | var shimUnscopables = require('es-shim-unscopables');
5 |
6 | var getPolyfill = require('./polyfill');
7 |
8 | module.exports = function shim() {
9 | var polyfill = getPolyfill();
10 |
11 | define(
12 | Array.prototype,
13 | { toSorted: polyfill },
14 | { toSorted: function () { return Array.prototype.toSorted !== polyfill; } }
15 | );
16 |
17 | shimUnscopables('toSorted');
18 |
19 | return polyfill;
20 | };
21 |
--------------------------------------------------------------------------------
/test/implementation.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var callBind = require('call-bind');
4 | var test = require('tape');
5 | var hasStrictMode = require('has-strict-mode')();
6 |
7 | var implementation = require('../implementation');
8 | var runTests = require('./tests');
9 |
10 | test('as a function', function (t) {
11 | t.test('bad array/this value', { skip: !hasStrictMode }, function (st) {
12 | /* eslint no-useless-call: 0 */
13 | st['throws'](function () { implementation.call(undefined); }, TypeError, 'undefined is not an object');
14 | st['throws'](function () { implementation.call(null); }, TypeError, 'null is not an object');
15 | st.end();
16 | });
17 |
18 | runTests(callBind(implementation), t);
19 |
20 | t.end();
21 | });
22 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var test = require('tape');
4 | var hasStrictMode = require('has-strict-mode')();
5 |
6 | var bound = require('../');
7 | var runTests = require('./tests');
8 |
9 | test('as a function', function (t) {
10 | t.test('bad array/this value', { skip: !hasStrictMode }, function (st) {
11 | /* eslint no-useless-call: 0 */
12 | st['throws'](function () { return bound.call(undefined); }, TypeError, 'undefined is not an object');
13 | st['throws'](function () { return bound.call(null); }, TypeError, 'null is not an object');
14 | st.end();
15 | });
16 |
17 | runTests(bound, t);
18 |
19 | t.end();
20 | });
21 |
--------------------------------------------------------------------------------
/test/shimmed.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | require('../auto');
4 |
5 | var test = require('tape');
6 | var defineProperties = require('define-properties');
7 | var callBind = require('call-bind');
8 | var hasStrictMode = require('has-strict-mode')();
9 | var functionsHaveNames = require('functions-have-names')();
10 |
11 | var isEnumerable = Object.prototype.propertyIsEnumerable;
12 |
13 | var runTests = require('./tests');
14 |
15 | test('shimmed', function (t) {
16 | var fn = Array.prototype.toSorted;
17 | t.equal(fn.length, 1, 'Array#toSorted has a length of 1');
18 | t.test('Function name', { skip: !functionsHaveNames }, function (st) {
19 | st.equal(fn.name, 'toSorted', 'Array#toSorted has name "toSorted"');
20 | st.end();
21 | });
22 |
23 | t.test('enumerability', { skip: !defineProperties.supportsDescriptors }, function (et) {
24 | et.equal(false, isEnumerable.call(Array.prototype, 'toSorted'), 'Array#toSorted is not enumerable');
25 | et.end();
26 | });
27 |
28 | t.test('bad array/this value', { skip: !hasStrictMode }, function (st) {
29 | /* eslint no-useless-call: 0 */
30 | st['throws'](function () { return fn.call(undefined); }, TypeError, 'undefined is not an object');
31 | st['throws'](function () { return fn.call(null); }, TypeError, 'null is not an object');
32 | st.end();
33 | });
34 |
35 | runTests(callBind(fn), t);
36 |
37 | t.end();
38 | });
39 |
--------------------------------------------------------------------------------
/test/tests.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var hasOwn = require('hasown');
4 |
5 | module.exports = function (toSorted, t) {
6 | var nums = [2, 1, 3];
7 | var result = toSorted(nums);
8 | t.deepEqual(
9 | result,
10 | [1, 2, 3],
11 | 'array is sorted'
12 | );
13 | t.notEqual(nums, result, 'original array is not returned');
14 | t.deepEqual(nums, [2, 1, 3], 'original array is unchanged');
15 |
16 | nums.sort();
17 | t.deepEqual(nums, result, 'mutated original matches result');
18 |
19 | t.deepEqual(
20 | toSorted('acab'),
21 | ['a', 'a', 'b', 'c'],
22 | 'string sorts to array'
23 | );
24 |
25 | var halfPoo = '\uD83D';
26 | var endPoo = '\uDCA9';
27 | var poo = halfPoo + endPoo;
28 | t.deepEqual(
29 | toSorted('a' + poo + 'c'),
30 | ['a', 'c', halfPoo, endPoo],
31 | 'code point is sorted as expected'
32 | );
33 |
34 | var arrayLikeLengthValueOf = {
35 | length: {
36 | valueOf: function () { return 2; }
37 | },
38 | 0: 4,
39 | 1: 0,
40 | 2: 1
41 | };
42 | t.deepEqual(toSorted(arrayLikeLengthValueOf), [0, 4]);
43 |
44 | t.test('not positive integer lengths', function (st) {
45 | st.deepEqual(toSorted({ length: -2 }), []);
46 | st.deepEqual(toSorted({ length: 'dog' }), []);
47 | st.deepEqual(toSorted({ length: NaN }), []);
48 |
49 | st.end();
50 | });
51 |
52 | t.test('getters', { skip: !Object.defineProperty }, function (st) {
53 | var getCalls = [];
54 |
55 | var arrayLike = {
56 | 0: 2,
57 | 1: 1,
58 | 2: 3,
59 | length: 3
60 | };
61 | Object.defineProperty(arrayLike, '0', {
62 | get: function () {
63 | getCalls.push(0);
64 | return 2;
65 | }
66 | });
67 | Object.defineProperty(arrayLike, '1', {
68 | get: function () {
69 | getCalls.push(1);
70 | return 1;
71 | }
72 | });
73 | Object.defineProperty(arrayLike, '2', {
74 | get: function () {
75 | getCalls.push(2);
76 | return 3;
77 | }
78 | });
79 |
80 | var up = { gross: true };
81 | st['throws'](
82 | function () {
83 | toSorted(arrayLike, function () {
84 | throw up;
85 | });
86 | },
87 | up
88 | );
89 | st.deepEqual(getCalls, [0, 1, 2]);
90 |
91 | var arr1 = [5, 0, 3];
92 | Object.defineProperty(arr1, '0', {
93 | get: function () {
94 | arr1.push(1);
95 | return 5;
96 | }
97 | });
98 | st.deepEqual(toSorted(arr1), [0, 3, 5]);
99 |
100 | var arr = [5, 1, 4, 6, 3];
101 | Array.prototype[3] = 2; // eslint-disable-line no-extend-native
102 | st.teardown(function () {
103 | delete Array.prototype[3];
104 | });
105 |
106 | Object.defineProperty(arr, '2', {
107 | get: function () {
108 | arr.length = 1;
109 | return 4;
110 | }
111 | });
112 |
113 | st.deepEqual(toSorted(arr), [1, 2, 4, 5, undefined]);
114 |
115 | st.end();
116 | });
117 |
118 | t.test('too-large lengths', function (st) {
119 | var arrayLike = {
120 | 0: 0,
121 | 4294967295: 4294967295,
122 | 4294967296: 4294967296,
123 | length: Math.pow(2, 32)
124 | };
125 |
126 | st['throws'](
127 | function () { toSorted(arrayLike); },
128 | RangeError
129 | );
130 |
131 | st.end();
132 | });
133 |
134 | t.deepEqual(toSorted(true), [], 'true yields empty array');
135 | t.deepEqual(toSorted(false), [], 'false yields empty array');
136 |
137 | t.test('holes', function (st) {
138 | var arr = [3, /* hole */, 4, /* hole */, 1]; // eslint-disable-line no-sparse-arrays
139 | Array.prototype[3] = 2; // eslint-disable-line no-extend-native
140 | st.teardown(function () {
141 | delete Array.prototype[3];
142 | });
143 |
144 | var sorted = toSorted(arr);
145 | st.deepEqual(sorted, [1, 2, 3, 4, undefined]);
146 | st.ok(hasOwn(sorted, 4));
147 |
148 | st.end();
149 | });
150 | };
151 |
--------------------------------------------------------------------------------