├── .github
├── actions
│ └── setup
│ │ └── action.yml
├── dependabot.yml
└── workflows
│ ├── lint-pr.yml
│ ├── test-and-release.yml
│ └── test.yml
├── .gitignore
├── .nvmrc
├── .releaserc
├── .vscode
├── extensions.json
└── settings.json
├── LICENSE
├── README.md
├── assets
├── banner.gif
├── banner_alt-pixelated.gif
├── banner_alt-pixelated_bounce.gif
├── banner_taller.gif
├── grid-only_landscape.mp4
├── grid-only_portrait.mp4
├── grid-with-text_portrait.mp4
├── meta.jpg
└── meta_pixelated.jpg
├── benchmark
└── results
│ └── make-matrix-ci.json
├── biome.json
├── package.json
├── pnpm-lock.yaml
├── scripts
├── build.ts
├── run-benchmark.ts
└── update-badges.ts
├── src
├── __tests__
│ ├── __snapshots__
│ │ └── index.test.ts.snap
│ ├── index.test.ts
│ └── types.test.ts
├── index.ts
└── types.ts
└── tsconfig.json
/.github/actions/setup/action.yml:
--------------------------------------------------------------------------------
1 | name: "Set up repository"
2 | description: "Sets up the repository for CI, by installing packages, and configuring the cache"
3 |
4 | runs:
5 | using: "composite"
6 | steps:
7 | - name: Get Node Version from .nvmrc
8 | id: nvm
9 | run: echo "node_version=$(cat .nvmrc)" >> $GITHUB_OUTPUT
10 | shell: bash
11 | - uses: pnpm/action-setup@v4
12 | - name: Set up Node
13 | uses: actions/setup-node@v4
14 | with:
15 | node-version: "${{ steps.nvm.outputs.node_version }}"
16 | cache: "pnpm"
17 | - name: Load cached node modules
18 | uses: actions/cache@v4
19 | id: cache-node_modules
20 | with:
21 | path: node_modules
22 | key: ${{ runner.os }}-node_modules-${{ hashFiles('pnpm-lock.yaml') }}
23 | restore-keys: |
24 | ${{ runner.os }}-node_modules-
25 | - name: Install node_modules (on cache miss)
26 | if: steps.cache-node_modules.outputs.cache-hit != 'true'
27 | run: pnpm i
28 | shell: bash
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "npm"
4 | directory: "/"
5 | schedule:
6 | interval: "monthly"
7 | commit-message:
8 | prefix: fix
9 | prefix-development: chore
10 | include: scope
11 | groups:
12 | dev-dependencies:
13 | dependency-type: "development"
14 | patterns:
15 | - "*"
16 | update-types:
17 | - "minor"
18 | - "patch"
19 | commitlint-monorepo:
20 | dependency-type: "development"
21 | patterns:
22 | - "@commitlint/*"
23 | update-types:
24 | - "major"
25 | - package-ecosystem: github-actions
26 | directory: "/"
27 | schedule:
28 | interval: "monthly"
29 |
--------------------------------------------------------------------------------
/.github/workflows/lint-pr.yml:
--------------------------------------------------------------------------------
1 | name: "Lint PR"
2 |
3 | on:
4 | pull_request_target:
5 | types:
6 | - opened
7 | - edited
8 | - synchronize
9 |
10 | permissions:
11 | pull-requests: read
12 |
13 | jobs:
14 | main:
15 | name: Validate PR title
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: amannn/action-semantic-pull-request@v5
19 | env:
20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/test-and-release.yml:
--------------------------------------------------------------------------------
1 | name: Test & Release
2 |
3 | on:
4 | push:
5 | branches:
6 | - "main"
7 |
8 | jobs:
9 | release:
10 | name: Test & Release
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v4
15 | with:
16 | fetch-depth: 2
17 | - name: Set up repo
18 | uses: ./.github/actions/setup
19 | - name: Check
20 | run: pnpm run check
21 | - name: Typecheck
22 | run: pnpm run typecheck
23 | - name: Test
24 | run: pnpm run test
25 | - name: Validate current commit (last commit) with commitlint
26 | run: pnpm run commitlint -- --from HEAD~1 --to HEAD --verbose
27 | - name: Release
28 | run: npx semantic-release
29 | env:
30 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
31 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
32 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | pull_request:
5 |
6 | jobs:
7 | test:
8 | name: Test
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v4
13 | - name: Set up repo
14 | uses: ./.github/actions/setup
15 | - name: Check
16 | run: pnpm run check
17 | - name: Typecheck
18 | run: pnpm run typecheck
19 | - name: Test
20 | run: pnpm run test
21 | - name: Has src changed
22 | if: github.event_name == 'pull_request'
23 | id: src_changed
24 | uses: tj-actions/changed-files@v46
25 | with:
26 | files: src/index.ts
27 | - name: Benchmark against current release
28 | if: steps.src_changed.outputs.any_changed == 'true'
29 | id: benchmark
30 | run: pnpm run benchmark:diff:ci
31 | env:
32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33 | - name: Validate PR commits with commitlint
34 | run: pnpm run commitlint -- --from ${{ github.event.pull_request.head.sha }}~${{ github.event.pull_request.commits }} --to ${{ github.event.pull_request.head.sha }} --verbose
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .git/
2 | node_modules/
3 | lib/
4 | dist/
5 | coverage/
6 | .jest-cache/
7 | benchmark/results/make-matrix-local.json
8 | .DS_Store
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v20.16.0
--------------------------------------------------------------------------------
/.releaserc:
--------------------------------------------------------------------------------
1 | {
2 | "branches": [
3 | "main"
4 | ],
5 | "plugins": [
6 | "@semantic-release/commit-analyzer",
7 | "@semantic-release/release-notes-generator",
8 | "@semantic-release/npm",
9 | [
10 | "@semantic-release/github",
11 | {
12 | "assets": [
13 | {
14 | "path": "dist/index.cjs",
15 | "label": "make-matrix.js"
16 | },
17 | {
18 | "path": "dist/index.js",
19 | "label": "make-matrix.mjs"
20 | },
21 | {
22 | "path": "dist/index.min.cjs",
23 | "label": "make-matrix.min.js"
24 | },
25 | {
26 | "path": "dist/index.min.js",
27 | "label": "make-matrix.min.mjs"
28 | }
29 | ]
30 | }
31 | ],
32 | [
33 | "@semantic-release/git",
34 | {
35 | "assets": [
36 | "README.md",
37 | "package.json",
38 | "package-lock.json",
39 | "benchmark/results/make-matrix-ci.json"
40 | ],
41 | "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
42 | }
43 | ]
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["biomejs.biome"]
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/typescript/lib",
3 | "biome.enabled": true,
4 | "editor.defaultFormatter": "biomejs.biome",
5 | "editor.formatOnSave": true,
6 | "editor.codeActionsOnSave": {
7 | "quickfix.biome": "explicit",
8 | "source.fixAll": "always",
9 | "source.organizeImports.biome": "explicit"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Neef Rehman
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 |
2 |
3 | [](https://github.com/neefrehman/make-matrix/actions "View the build actions for this project")
4 | [](https://npmjs.org/package/make-matrix "View this project on npm")
5 | [](https://npmjs.org/package/make-matrix "Types are included in this package")
6 | [](https://bundlephobia.com/result?p=make-matrix "View this project on bundlephobia")
7 |
8 | A simple, type-safe way to create multi-dimensional arrays
9 |
10 | ## Features
11 |
12 | - 🛸 Easily create multi-dimensional arrays, with as many dimensions as needed
13 | - 🎛 Define exact dimensions to create an array of specified size
14 | - 🔢 Initialise every point in the array to a custom or self-aware starting value
15 | - 📜 Comes with [TypeScript](https://www.typescriptlang.org) definitions and type-safe returns
16 | - 🔬 Tiny size, with no external dependencies
17 |
18 | ## Installation
19 |
20 | Install the package from NPM, and import it into your JavaScript or TypeScript file:
21 |
22 | ```bash
23 | npm install make-matrix
24 | ```
25 |
26 | ```js
27 | import { makeMatrix } from "make-matrix";
28 | ```
29 |
30 | ## Usage
31 |
32 | ### Create a matrix
33 |
34 | To create a matrix, pass in an array with the desired dimensions.
35 |
36 | ```js
37 | // create an array of size 3x3x2
38 | const threeByThreeByTwoArray = makeMatrix([3, 3, 2]);
39 | ```
40 |
41 | ### Initialise the matrix with set values
42 |
43 | By default each point in the matrix will be initialised to `null` (so that if reading a point returns `undefined`, you know that it exists outside the current bounds of the matrix). To fill each point with a custom initial value, pass that value as the function's second parameter, `initialValues`:
44 |
45 | ```js
46 | // create a 3x5 array, with each point equal to 0
47 | const twoDNumberArray = makeMatrix([3, 5], 0);
48 |
49 | // create a 2x6x5 array, with each point equal to "value"
50 | const threeDStringArray = makeMatrix([2, 6, 5], "value");
51 | ```
52 |
53 | ### Pass a callback for dynamic initial values
54 |
55 | The `initialValues` parameter can also be a callback, which you can use to dynamically create items for each position in the matrix. The callback can also accept an argument which will resolve to the current vector co-ordinates at each point in the matrix. This will allow you to populate your matrix in a "self-aware" fashion.
56 |
57 | ```js
58 | // create a 10x10x10 array, with each point a different random number between 0 and 9
59 | const twoDRandomNumberArray = makeMatrix([10, 10, 10], () => Math.floor(Math.random() * 10));
60 |
61 | // create a 5x5 array, with each point self-described by a string
62 | const twoDVectorStringArray = makeMatrix([5, 5], (vector) => `I am at position ${vector.join()}`);
63 |
64 | // create a 7x3x8 array, with each point transformed into a vector object
65 | const twoDVectorObjectArray = makeMatrix([7, 3, 8], ([x, y, z]) => ({ x, y, z }));
66 | ```
67 |
68 | ## With TypeScript
69 |
70 | This package comes with type definitions to provide type-safety when working with the returned arrays.
71 |
72 | Returned Matrices will be given a specific type dictated by `T` and the number of dimensions, where `T` is the type of the value passed to the functions `initialValues` parameter (or `unknown`, if not set).
73 |
74 | For example, a three-dimensional array of numbers will be of type `number[][][]`. Points within the matrix can then only be reassigned to numbers. TypeScript's compiler will present errors when any reassignments are of the wrong type, including if they are at an incorrect depth in the array. This type-safety also occurs when callbacks are used to dynamically populate your matrix.
75 |
76 | ```ts
77 | const threeDNumberArray = makeMatrix([2, 6, 5], 0); // return type of number[][][]
78 |
79 | threeDNumberArray[2][1][2] = 10; // ✅ OK
80 |
81 | threeDNumberArray[2][1][2] = false; // 🚨 error: Type 'boolean' is not assignable to type 'number'
82 | threeDNumberArray[2][1] = 10; // 🚨 error: Type 'number' is not assignable to type 'number[]'
83 | threeDNumberArray[2][1][2][0] = 10; // 🚨 error: Property '0' does not exist on type 'Number'
84 | ```
85 |
86 | Please be aware that when using this function with a primitive instead of a literal type—such as when creating matrices of dynamic size—the exact return type cannot be determined and will instead resolve to `unknown[]`. This ensures an array of at least one dimension is returned, but is unable to provide any more safety than that. You must type the resulting matrix yourself, if you are able to provide more information than the compiler can infer. If not, then an explicit return type of `any[]` will provide the most 'relaxed' typing experience.
87 |
88 | ```ts
89 | const createDynamicMatrix = (dimensions: number[]) => makeMatrix(dimensions, 0); // return type of unknown[]
90 | ```
91 |
92 | ## Example
93 |
94 | To easily create a 3D grid using [p5.js](https://github.com/processing/p5.js/), make-matrix can be used like below. The source code for the grid at the top of this readme [can be seen here](https://github.com/neefrehman/Generative/blob/master/src/sketches/20/05/120520.tsx), and an [interactive demo of it here](https://generative.neef.co/120520).
95 |
96 | ```js
97 | const res = 10; // 10px grid resolution
98 | const matrix = makeMatrix([5, 5, 5]); // A 5x5x5 cube grid
99 |
100 | for (let x = 0; x < matrix.length; x += res) {
101 | for (let y = 0; y < matrix[x].length; y += res) {
102 | for (let z = 0; z < matrix[x][y].length; z += res) {
103 | line(x, y, z, x + res, y, z);
104 | line(x, y, z, x, y + res, z);
105 | line(x, y, z, x, y, z + res);
106 | }
107 | }
108 | }
109 | ```
110 |
111 | ## Complexity
112 |
113 | The `makeMatrix` algorithm is recursive and takes exponential time, or $O(2^n)$, to complete. This means that adding new dimensions dramatically increases the amount of time taken to create a matrix. While creating a matrix of 7 dimensions will happen in around a millisecond, doing the same with 10 dimensions will verge into the hundreds of milliseconds. Please bear this in mind when creating matrices.
114 |
115 | ## API
116 |
117 | ```ts
118 | makeMatrix(
119 | dimensions: VectorOfLength,
120 | initialValues?: T | ((vector: VectorOfLength) => T) = null
121 | ): Matrix;
122 | ```
123 |
124 | ### Parameters
125 |
126 | | Name | Description |
127 | | --------------- | ----------- |
128 | | `dimensions` | The desired dimensions of the matrix. An array of numbers. |
129 | | `initialValues` | The value that each point in the matrix will initialise to. Can take any value. If a callback is passed, it will be run for each point in the matrix, which will be initialised to the callbacks returned value. (Optional — defaults to `null`). |
130 |
131 | ### Returns
132 |
133 | | Name | Description |
134 | | -------- | ----------- |
135 | | `Matrix` | A multidimensional array of your desired dimensions, with each point initialised to equal the `initialValues` parameter (or its returned value). |
136 |
137 | ## Contributing
138 |
139 | This project welcomes contributions. To get started, please [open an issue](https://github.com/neefrehman/make-matrix/issues) to do discuss the change you'd like to make. Then fork the repo, open it in your editor, and run `pnpm install` in your terminal. This will get everything set up for you to start making changes.
140 |
141 | ### Testing, linting and commit style
142 |
143 | This project uses [Biome](https://biomejs.dev/), [commitlint](https://github.com/conventional-changelog/commitlint) and [vitest](https://vitest.dev/) — in combination with [lint-staged](https://github.com/okonet/lint-staged) and [simple-git-hooks](https://github.com/toplenboren/simple-git-hooks) — to enforce code quality, consistency and changelog style. These tools will check changed files, and cancel a commit with logging if any of the following are true:
144 |
145 | 1. Biome has found non-fixable issues in the code
146 | 2. The Vitest testing suites haven't all passed
147 | 3. The commit message doesn't meet the [conventional commit format](https://www.conventionalcommits.org/en/v1.0.0/) (run `pnpm run commitizen` in terminal for help formatting your commit message)
148 |
149 | Open your git logs to debug commit errors.
150 |
151 | ## License
152 |
153 | This package is [MIT Licensed](https://github.com/neefrehman/make-matrix/blob/main/LICENSE).
154 |
--------------------------------------------------------------------------------
/assets/banner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neefrehman/make-matrix/27a0c0f2f992bb84eaf1058d56e06f69267a6c9d/assets/banner.gif
--------------------------------------------------------------------------------
/assets/banner_alt-pixelated.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neefrehman/make-matrix/27a0c0f2f992bb84eaf1058d56e06f69267a6c9d/assets/banner_alt-pixelated.gif
--------------------------------------------------------------------------------
/assets/banner_alt-pixelated_bounce.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neefrehman/make-matrix/27a0c0f2f992bb84eaf1058d56e06f69267a6c9d/assets/banner_alt-pixelated_bounce.gif
--------------------------------------------------------------------------------
/assets/banner_taller.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neefrehman/make-matrix/27a0c0f2f992bb84eaf1058d56e06f69267a6c9d/assets/banner_taller.gif
--------------------------------------------------------------------------------
/assets/grid-only_landscape.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neefrehman/make-matrix/27a0c0f2f992bb84eaf1058d56e06f69267a6c9d/assets/grid-only_landscape.mp4
--------------------------------------------------------------------------------
/assets/grid-only_portrait.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neefrehman/make-matrix/27a0c0f2f992bb84eaf1058d56e06f69267a6c9d/assets/grid-only_portrait.mp4
--------------------------------------------------------------------------------
/assets/grid-with-text_portrait.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neefrehman/make-matrix/27a0c0f2f992bb84eaf1058d56e06f69267a6c9d/assets/grid-with-text_portrait.mp4
--------------------------------------------------------------------------------
/assets/meta.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neefrehman/make-matrix/27a0c0f2f992bb84eaf1058d56e06f69267a6c9d/assets/meta.jpg
--------------------------------------------------------------------------------
/assets/meta_pixelated.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neefrehman/make-matrix/27a0c0f2f992bb84eaf1058d56e06f69267a6c9d/assets/meta_pixelated.jpg
--------------------------------------------------------------------------------
/benchmark/results/make-matrix-ci.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "make-matrix",
3 | "date": "2025-05-22T21:02:45.710Z",
4 | "version": "4.0.2",
5 | "results": [
6 | {
7 | "name": "base",
8 | "ops": 186481,
9 | "margin": 1.26,
10 | "percentSlower": 0
11 | },
12 | {
13 | "name": "with callback",
14 | "ops": 37542,
15 | "margin": 0.73,
16 | "percentSlower": 79.87
17 | }
18 | ],
19 | "fastest": {
20 | "name": "base",
21 | "index": 0
22 | },
23 | "slowest": {
24 | "name": "with callback",
25 | "index": 1
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
3 | "vcs": {
4 | "enabled": true,
5 | "clientKind": "git",
6 | "useIgnoreFile": true,
7 | "defaultBranch": "main"
8 | },
9 | "formatter": {
10 | "enabled": true,
11 | "formatWithErrors": false,
12 | "indentStyle": "space",
13 | "indentWidth": 2,
14 | "lineEnding": "lf",
15 | "lineWidth": 90,
16 | "attributePosition": "auto",
17 | "bracketSpacing": true
18 | },
19 | "organizeImports": {
20 | "enabled": true
21 | },
22 | "linter": {
23 | "enabled": true,
24 | "rules": {
25 | "recommended": true,
26 | "correctness": {
27 | "noUnusedVariables": "error",
28 | "useArrayLiterals": "error"
29 | },
30 | "style": {
31 | "noNamespace": "error",
32 | "useBlockStatements": "error"
33 | },
34 | "suspicious": {
35 | "noConsole": "error"
36 | }
37 | }
38 | },
39 | "javascript": {
40 | "formatter": {
41 | "jsxQuoteStyle": "double",
42 | "quoteProperties": "asNeeded",
43 | "trailingCommas": "es5",
44 | "semicolons": "always",
45 | "arrowParentheses": "asNeeded",
46 | "bracketSameLine": false,
47 | "quoteStyle": "double",
48 | "attributePosition": "auto",
49 | "bracketSpacing": true
50 | }
51 | },
52 | "overrides": [
53 | {
54 | "include": ["./scripts/run-benchmark.ts"],
55 | "linter": { "rules": { "suspicious": { "noConsole": "off" } } }
56 | }
57 | ]
58 | }
59 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "make-matrix",
3 | "version": "4.0.2",
4 | "license": "MIT",
5 | "description": "A simple, type-safe way to create multi-dimensional arrays",
6 | "author": "Neef Rehman",
7 | "keywords": [
8 | "matrix",
9 | "nth dimension",
10 | "array",
11 | "multidimensional",
12 | "math",
13 | "typescript"
14 | ],
15 | "homepage": "https://github.com/neefrehman/make-matrix",
16 | "repository": {
17 | "type": "git",
18 | "url": "git+https://github.com/neefrehman/make-matrix.git"
19 | },
20 | "bugs": {
21 | "url": "https://github.com/neefrehman/make-matrix/issues"
22 | },
23 | "files": ["src/**/*", "dist/**/*"],
24 | "type": "module",
25 | "sideEffects": false,
26 | "exports": {
27 | ".": {
28 | "types": "./dist/index.d.ts",
29 | "require": "./dist/index.cjs",
30 | "import": "./dist/index.js",
31 | "development": "./src/index.ts"
32 | }
33 | },
34 | "main": "./dist/index.cjs",
35 | "types": "./dist/index.d.ts",
36 | "scripts": {
37 | "check": "biome check",
38 | "check:fix": "biome check --write",
39 | "format:fix": "biome format --write",
40 | "typecheck": "tsc",
41 | "test": "vitest run",
42 | "build": "tsdown --config='scripts/build.ts'",
43 | "preversion": "pnpm run check",
44 | "version": "pnpm run build && pnpm run format:fix && git add -A src",
45 | "postversion": "pnpm run benchmark:ci && pnpm run updateBadges && git push && git push --tags",
46 | "updateBadges": "tsx scripts/update-badges.ts",
47 | "pre-commit": "lint-staged",
48 | "commit-msg": "commitlint -e",
49 | "commitizen": "cz",
50 | "commitlint": "commitlint",
51 | "benchmark": "tsx scripts/run-benchmark.ts current",
52 | "benchmark:ci": "tsx scripts/run-benchmark.ts current ci",
53 | "benchmark:diff": "tsx scripts/run-benchmark.ts diff",
54 | "benchmark:diff:ci": "tsx scripts/run-benchmark.ts diff ci"
55 | },
56 | "devDependencies": {
57 | "@actions/github": "6.0.1",
58 | "@biomejs/biome": "1.9.4",
59 | "@commitlint/cli": "19.8.1",
60 | "@commitlint/config-conventional": "19.8.1",
61 | "@semantic-release/git": "10.0.1",
62 | "benny": "3.7.1",
63 | "commitizen": "4.3.1",
64 | "cz-conventional-changelog": "3.3.0",
65 | "lint-staged": "15.5.2",
66 | "semantic-release": "24.2.4",
67 | "simple-git-hooks": "2.13.0",
68 | "terser": "5.39.2",
69 | "tsdown": "0.12.2",
70 | "tsx": "^4.19.4",
71 | "typescript": "5.8.3",
72 | "vitest": "3.1.4"
73 | },
74 | "lint-staged": {
75 | "*": [],
76 | "*.(js|ts|tsx)": ["biome check --write", "vitest related --run --passWithNoTests"]
77 | },
78 | "simple-git-hooks": {
79 | "commit-msg": "npm run commit-msg",
80 | "pre-commit": "npm run pre-commit"
81 | },
82 | "commitlint": {
83 | "extends": ["@commitlint/config-conventional"],
84 | "rules": {
85 | "body-max-line-length": [1, "always", 100]
86 | }
87 | },
88 | "config": {
89 | "commitizen": {
90 | "path": "./node_modules/cz-conventional-changelog"
91 | }
92 | },
93 | "packageManager": "pnpm@9.9.0"
94 | }
95 |
--------------------------------------------------------------------------------
/scripts/build.ts:
--------------------------------------------------------------------------------
1 | import { type Options, defineConfig } from "tsdown";
2 |
3 | const baseConfig: Options = {
4 | entry: ["src/index.ts"],
5 | format: ["cjs", "es"],
6 | platform: "neutral",
7 | };
8 |
9 | export default defineConfig([
10 | {
11 | ...baseConfig,
12 | sourcemap: true,
13 | },
14 | {
15 | ...baseConfig,
16 | minify: true,
17 | outExtensions: ({ format }) => ({
18 | js: format === "es" ? ".min.js" : `.min.${format}`,
19 | }),
20 | },
21 | ]);
22 |
--------------------------------------------------------------------------------
/scripts/run-benchmark.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "node:fs";
2 |
3 | import { context, getOctokit } from "@actions/github";
4 | import benny from "benny";
5 |
6 | import packageJson from "../package.json" with { type: "json" };
7 | import { makeMatrix } from "../src/index.js";
8 |
9 | const { name: packageName, version } = packageJson;
10 |
11 | const isDiff = process.argv[2] === "diff";
12 | const isInCI = process.argv[3] === "ci";
13 | const file = `${packageName}-${isInCI ? "ci" : "local"}`;
14 |
15 | const directionEmojiMapping = { [-1]: "🚨", 0: "🔄", 1: "✅" };
16 | const getEmoji = (diff: number) => directionEmojiMapping[Math.sign(diff)];
17 |
18 | type Diff = {
19 | name: string;
20 | delta: number;
21 | old?: number | undefined;
22 | new?: number;
23 | };
24 |
25 | benny
26 | .suite(
27 | "make-matrix",
28 | benny.add("base", () => {
29 | makeMatrix([2, 4, 2, 4, 2]);
30 | }),
31 | benny.add("with callback", () => {
32 | makeMatrix([2, 4, 2, 4, 2], vector => `my position is ${vector.join()}`);
33 | }),
34 | benny.cycle(),
35 | benny.complete(),
36 | isDiff ? { name: "skip" } : benny.save({ file, version })
37 | )
38 | .then(async ({ results }) => {
39 | if (!isDiff || !fs.existsSync(`./benchmark/results/${file}.json`)) {
40 | return;
41 | }
42 |
43 | const oldBenchmarkText = fs.readFileSync(`./benchmark/results/${file}.json`);
44 | const oldBenchmark = JSON.parse(oldBenchmarkText.toString());
45 | const oldResults: typeof results = oldBenchmark.results;
46 |
47 | const diffs: Diff[] = results.map(result => {
48 | const oldRes = oldResults.find(oldResult => oldResult.name === result.name);
49 | const delta = oldRes ? ((result.ops - oldRes.ops) / oldRes.ops) * 100 : 0;
50 | return { name: result.name, delta, old: oldRes?.ops, new: result.ops };
51 | });
52 |
53 | const changed = diffs.filter(item => item.delta !== 0);
54 | const average = changed.reduce((a, b) => a + b.delta, 0) / changed.length;
55 | diffs.push({ name: "Average", delta: average });
56 |
57 | const prettyDiffs = diffs.map(diff => ({
58 | ...diff,
59 | new: diff.new ? `${diff.new.toLocaleString()} ops/s` : "",
60 | old: diff.old ? `${diff.old.toLocaleString()} ops/s` : "",
61 | delta: `${getEmoji(diff.delta)} ${diff.delta.toFixed(2)}% ${
62 | diff.delta > 0 ? "faster" : diff.delta < 0 ? "slower" : "same"
63 | }`,
64 | }));
65 |
66 | console.log("\n");
67 | console.log(`Benchmark against currently published version (${version}):\n`);
68 | console.table(
69 | prettyDiffs.reduce<{ [name: string]: Record }>(
70 | (acc, { name, ...diff }) => {
71 | acc[name] = diff;
72 | return acc;
73 | },
74 | {}
75 | ),
76 | ["new", "old", "delta"]
77 | );
78 |
79 | if (!isInCI || !process.env.GITHUB_TOKEN) {
80 | return;
81 | }
82 |
83 | const body = ["### Benchmark against currently published version:"];
84 | body.push("| Key | Current PR | Published version | Difference |");
85 | body.push("| :--- | :--------: | :---------------: | :--------: |");
86 | for (const diff of prettyDiffs) {
87 | body.push(`| ${diff.name} | ${diff.new}| ${diff.old} | ${diff.delta} |`);
88 | }
89 |
90 | await getOctokit(process.env.GITHUB_TOKEN).rest.issues.createComment({
91 | issue_number: context.issue.number,
92 | owner: context.repo.owner,
93 | repo: context.repo.repo,
94 | body: body.join("\n"),
95 | });
96 | });
97 |
--------------------------------------------------------------------------------
/scripts/update-badges.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Script that will get the current version number and minzipped size of the package,
3 | * And use them to update the badges in this repo's README. I'm doing this in response
4 | * to issues with the runtime-determined badges that I used to use: they weren't that
5 | * accurate and would often not load. Upfronting this badge generation to time of
6 | * versioning is more reliable.
7 | *
8 | * @remarks
9 | * This work was initially planned to be shell-only, but due to some issues getting `sed`
10 | * to work, performing the write in javascript was a more reliable option.
11 | */
12 |
13 | import { exec } from "node:child_process";
14 | import * as fs from "node:fs";
15 | import { promisify } from "node:util";
16 |
17 | const execAsync = promisify(exec);
18 | const getStdOut = async (sh: string) => (await execAsync(sh)).stdout.trim();
19 |
20 | /*
21 | * With sed command that I couldn't quite get the regex working for:
22 | * grep -m 1 \"version\" package.json | awk -F: '{ print $2 }' | sed 's/[",]//g' | (read VERSION && sed -i '' "/v(\d+\.)?(\d+\.)?(\*|\d+)/v$VERSION/" README.md)
23 | */
24 | const getVersionCommand = `grep -m 1 \"version\" package.json | awk -F: '{ print $2 }' | sed 's/[",]//g'`;
25 |
26 | /*
27 | * With sed command that I couldn't quite get the regex working for:
28 | * gzip dist/index.min.js -kf && wc -c < dist/index.min.js.gz | (read MINZIPPED_SIZE && sed -i '' "s/\d+_B/$MINZIPPED_SIZE\_B/" README.md)
29 | */
30 | const getMinZippedSizeCommand =
31 | "gzip dist/index.min.js -kf && wc -c < dist/index.min.js.gz";
32 |
33 | const main = async () => {
34 | const currentReadme = fs.readFileSync("./README.md", "utf-8");
35 |
36 | const newVersion = await getStdOut(getVersionCommand);
37 | const newMinzippedSize = await getStdOut(getMinZippedSizeCommand);
38 |
39 | const newReadme = currentReadme
40 | .replace(/v(\d+\.)?(\d+\.)?(\*|\d+)/, `v${newVersion}`)
41 | .replace(/\d+_B/, `${newMinzippedSize}_B`);
42 |
43 | fs.writeFileSync("./README.md", newReadme);
44 | };
45 |
46 | main();
47 |
--------------------------------------------------------------------------------
/src/__tests__/__snapshots__/index.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`makeMatrix > callback initial values — math > %p [ 1, 1 ] 1`] = `
4 | [
5 | [
6 | 8,
7 | ],
8 | ]
9 | `;
10 |
11 | exports[`makeMatrix > callback initial values — math > %p [ 1, 4, 5, 2 ] 1`] = `
12 | [
13 | [
14 | [
15 | [
16 | 8,
17 | 8,
18 | ],
19 | [
20 | 8,
21 | 8,
22 | ],
23 | [
24 | 8,
25 | 8,
26 | ],
27 | [
28 | 8,
29 | 8,
30 | ],
31 | [
32 | 8,
33 | 8,
34 | ],
35 | ],
36 | [
37 | [
38 | 8,
39 | 8,
40 | ],
41 | [
42 | 8,
43 | 8,
44 | ],
45 | [
46 | 8,
47 | 8,
48 | ],
49 | [
50 | 8,
51 | 8,
52 | ],
53 | [
54 | 8,
55 | 8,
56 | ],
57 | ],
58 | [
59 | [
60 | 8,
61 | 8,
62 | ],
63 | [
64 | 8,
65 | 8,
66 | ],
67 | [
68 | 8,
69 | 8,
70 | ],
71 | [
72 | 8,
73 | 8,
74 | ],
75 | [
76 | 8,
77 | 8,
78 | ],
79 | ],
80 | [
81 | [
82 | 8,
83 | 8,
84 | ],
85 | [
86 | 8,
87 | 8,
88 | ],
89 | [
90 | 8,
91 | 8,
92 | ],
93 | [
94 | 8,
95 | 8,
96 | ],
97 | [
98 | 8,
99 | 8,
100 | ],
101 | ],
102 | ],
103 | ]
104 | `;
105 |
106 | exports[`makeMatrix > callback initial values — math > %p [ 2, 4, 2, 4, 2 ] 1`] = `
107 | [
108 | [
109 | [
110 | [
111 | [
112 | 8,
113 | 8,
114 | ],
115 | [
116 | 8,
117 | 8,
118 | ],
119 | [
120 | 8,
121 | 8,
122 | ],
123 | [
124 | 8,
125 | 8,
126 | ],
127 | ],
128 | [
129 | [
130 | 8,
131 | 8,
132 | ],
133 | [
134 | 8,
135 | 8,
136 | ],
137 | [
138 | 8,
139 | 8,
140 | ],
141 | [
142 | 8,
143 | 8,
144 | ],
145 | ],
146 | ],
147 | [
148 | [
149 | [
150 | 8,
151 | 8,
152 | ],
153 | [
154 | 8,
155 | 8,
156 | ],
157 | [
158 | 8,
159 | 8,
160 | ],
161 | [
162 | 8,
163 | 8,
164 | ],
165 | ],
166 | [
167 | [
168 | 8,
169 | 8,
170 | ],
171 | [
172 | 8,
173 | 8,
174 | ],
175 | [
176 | 8,
177 | 8,
178 | ],
179 | [
180 | 8,
181 | 8,
182 | ],
183 | ],
184 | ],
185 | [
186 | [
187 | [
188 | 8,
189 | 8,
190 | ],
191 | [
192 | 8,
193 | 8,
194 | ],
195 | [
196 | 8,
197 | 8,
198 | ],
199 | [
200 | 8,
201 | 8,
202 | ],
203 | ],
204 | [
205 | [
206 | 8,
207 | 8,
208 | ],
209 | [
210 | 8,
211 | 8,
212 | ],
213 | [
214 | 8,
215 | 8,
216 | ],
217 | [
218 | 8,
219 | 8,
220 | ],
221 | ],
222 | ],
223 | [
224 | [
225 | [
226 | 8,
227 | 8,
228 | ],
229 | [
230 | 8,
231 | 8,
232 | ],
233 | [
234 | 8,
235 | 8,
236 | ],
237 | [
238 | 8,
239 | 8,
240 | ],
241 | ],
242 | [
243 | [
244 | 8,
245 | 8,
246 | ],
247 | [
248 | 8,
249 | 8,
250 | ],
251 | [
252 | 8,
253 | 8,
254 | ],
255 | [
256 | 8,
257 | 8,
258 | ],
259 | ],
260 | ],
261 | ],
262 | [
263 | [
264 | [
265 | [
266 | 8,
267 | 8,
268 | ],
269 | [
270 | 8,
271 | 8,
272 | ],
273 | [
274 | 8,
275 | 8,
276 | ],
277 | [
278 | 8,
279 | 8,
280 | ],
281 | ],
282 | [
283 | [
284 | 8,
285 | 8,
286 | ],
287 | [
288 | 8,
289 | 8,
290 | ],
291 | [
292 | 8,
293 | 8,
294 | ],
295 | [
296 | 8,
297 | 8,
298 | ],
299 | ],
300 | ],
301 | [
302 | [
303 | [
304 | 8,
305 | 8,
306 | ],
307 | [
308 | 8,
309 | 8,
310 | ],
311 | [
312 | 8,
313 | 8,
314 | ],
315 | [
316 | 8,
317 | 8,
318 | ],
319 | ],
320 | [
321 | [
322 | 8,
323 | 8,
324 | ],
325 | [
326 | 8,
327 | 8,
328 | ],
329 | [
330 | 8,
331 | 8,
332 | ],
333 | [
334 | 8,
335 | 8,
336 | ],
337 | ],
338 | ],
339 | [
340 | [
341 | [
342 | 8,
343 | 8,
344 | ],
345 | [
346 | 8,
347 | 8,
348 | ],
349 | [
350 | 8,
351 | 8,
352 | ],
353 | [
354 | 8,
355 | 8,
356 | ],
357 | ],
358 | [
359 | [
360 | 8,
361 | 8,
362 | ],
363 | [
364 | 8,
365 | 8,
366 | ],
367 | [
368 | 8,
369 | 8,
370 | ],
371 | [
372 | 8,
373 | 8,
374 | ],
375 | ],
376 | ],
377 | [
378 | [
379 | [
380 | 8,
381 | 8,
382 | ],
383 | [
384 | 8,
385 | 8,
386 | ],
387 | [
388 | 8,
389 | 8,
390 | ],
391 | [
392 | 8,
393 | 8,
394 | ],
395 | ],
396 | [
397 | [
398 | 8,
399 | 8,
400 | ],
401 | [
402 | 8,
403 | 8,
404 | ],
405 | [
406 | 8,
407 | 8,
408 | ],
409 | [
410 | 8,
411 | 8,
412 | ],
413 | ],
414 | ],
415 | ],
416 | ]
417 | `;
418 |
419 | exports[`makeMatrix > callback initial values — math > %p [ 3, 2, 3 ] 1`] = `
420 | [
421 | [
422 | [
423 | 8,
424 | 8,
425 | 8,
426 | ],
427 | [
428 | 8,
429 | 8,
430 | 8,
431 | ],
432 | ],
433 | [
434 | [
435 | 8,
436 | 8,
437 | 8,
438 | ],
439 | [
440 | 8,
441 | 8,
442 | 8,
443 | ],
444 | ],
445 | [
446 | [
447 | 8,
448 | 8,
449 | 8,
450 | ],
451 | [
452 | 8,
453 | 8,
454 | 8,
455 | ],
456 | ],
457 | ]
458 | `;
459 |
460 | exports[`makeMatrix > callback initial values — math > %p [ 6 ] 1`] = `
461 | [
462 | 8,
463 | 8,
464 | 8,
465 | 8,
466 | 8,
467 | 8,
468 | ]
469 | `;
470 |
471 | exports[`makeMatrix > no initial values > %p [ 1, 1 ] 1`] = `
472 | [
473 | [
474 | null,
475 | ],
476 | ]
477 | `;
478 |
479 | exports[`makeMatrix > no initial values > %p [ 1, 4, 5, 2 ] 1`] = `
480 | [
481 | [
482 | [
483 | [
484 | null,
485 | null,
486 | ],
487 | [
488 | null,
489 | null,
490 | ],
491 | [
492 | null,
493 | null,
494 | ],
495 | [
496 | null,
497 | null,
498 | ],
499 | [
500 | null,
501 | null,
502 | ],
503 | ],
504 | [
505 | [
506 | null,
507 | null,
508 | ],
509 | [
510 | null,
511 | null,
512 | ],
513 | [
514 | null,
515 | null,
516 | ],
517 | [
518 | null,
519 | null,
520 | ],
521 | [
522 | null,
523 | null,
524 | ],
525 | ],
526 | [
527 | [
528 | null,
529 | null,
530 | ],
531 | [
532 | null,
533 | null,
534 | ],
535 | [
536 | null,
537 | null,
538 | ],
539 | [
540 | null,
541 | null,
542 | ],
543 | [
544 | null,
545 | null,
546 | ],
547 | ],
548 | [
549 | [
550 | null,
551 | null,
552 | ],
553 | [
554 | null,
555 | null,
556 | ],
557 | [
558 | null,
559 | null,
560 | ],
561 | [
562 | null,
563 | null,
564 | ],
565 | [
566 | null,
567 | null,
568 | ],
569 | ],
570 | ],
571 | ]
572 | `;
573 |
574 | exports[`makeMatrix > no initial values > %p [ 2, 4, 2, 4, 2 ] 1`] = `
575 | [
576 | [
577 | [
578 | [
579 | [
580 | null,
581 | null,
582 | ],
583 | [
584 | null,
585 | null,
586 | ],
587 | [
588 | null,
589 | null,
590 | ],
591 | [
592 | null,
593 | null,
594 | ],
595 | ],
596 | [
597 | [
598 | null,
599 | null,
600 | ],
601 | [
602 | null,
603 | null,
604 | ],
605 | [
606 | null,
607 | null,
608 | ],
609 | [
610 | null,
611 | null,
612 | ],
613 | ],
614 | ],
615 | [
616 | [
617 | [
618 | null,
619 | null,
620 | ],
621 | [
622 | null,
623 | null,
624 | ],
625 | [
626 | null,
627 | null,
628 | ],
629 | [
630 | null,
631 | null,
632 | ],
633 | ],
634 | [
635 | [
636 | null,
637 | null,
638 | ],
639 | [
640 | null,
641 | null,
642 | ],
643 | [
644 | null,
645 | null,
646 | ],
647 | [
648 | null,
649 | null,
650 | ],
651 | ],
652 | ],
653 | [
654 | [
655 | [
656 | null,
657 | null,
658 | ],
659 | [
660 | null,
661 | null,
662 | ],
663 | [
664 | null,
665 | null,
666 | ],
667 | [
668 | null,
669 | null,
670 | ],
671 | ],
672 | [
673 | [
674 | null,
675 | null,
676 | ],
677 | [
678 | null,
679 | null,
680 | ],
681 | [
682 | null,
683 | null,
684 | ],
685 | [
686 | null,
687 | null,
688 | ],
689 | ],
690 | ],
691 | [
692 | [
693 | [
694 | null,
695 | null,
696 | ],
697 | [
698 | null,
699 | null,
700 | ],
701 | [
702 | null,
703 | null,
704 | ],
705 | [
706 | null,
707 | null,
708 | ],
709 | ],
710 | [
711 | [
712 | null,
713 | null,
714 | ],
715 | [
716 | null,
717 | null,
718 | ],
719 | [
720 | null,
721 | null,
722 | ],
723 | [
724 | null,
725 | null,
726 | ],
727 | ],
728 | ],
729 | ],
730 | [
731 | [
732 | [
733 | [
734 | null,
735 | null,
736 | ],
737 | [
738 | null,
739 | null,
740 | ],
741 | [
742 | null,
743 | null,
744 | ],
745 | [
746 | null,
747 | null,
748 | ],
749 | ],
750 | [
751 | [
752 | null,
753 | null,
754 | ],
755 | [
756 | null,
757 | null,
758 | ],
759 | [
760 | null,
761 | null,
762 | ],
763 | [
764 | null,
765 | null,
766 | ],
767 | ],
768 | ],
769 | [
770 | [
771 | [
772 | null,
773 | null,
774 | ],
775 | [
776 | null,
777 | null,
778 | ],
779 | [
780 | null,
781 | null,
782 | ],
783 | [
784 | null,
785 | null,
786 | ],
787 | ],
788 | [
789 | [
790 | null,
791 | null,
792 | ],
793 | [
794 | null,
795 | null,
796 | ],
797 | [
798 | null,
799 | null,
800 | ],
801 | [
802 | null,
803 | null,
804 | ],
805 | ],
806 | ],
807 | [
808 | [
809 | [
810 | null,
811 | null,
812 | ],
813 | [
814 | null,
815 | null,
816 | ],
817 | [
818 | null,
819 | null,
820 | ],
821 | [
822 | null,
823 | null,
824 | ],
825 | ],
826 | [
827 | [
828 | null,
829 | null,
830 | ],
831 | [
832 | null,
833 | null,
834 | ],
835 | [
836 | null,
837 | null,
838 | ],
839 | [
840 | null,
841 | null,
842 | ],
843 | ],
844 | ],
845 | [
846 | [
847 | [
848 | null,
849 | null,
850 | ],
851 | [
852 | null,
853 | null,
854 | ],
855 | [
856 | null,
857 | null,
858 | ],
859 | [
860 | null,
861 | null,
862 | ],
863 | ],
864 | [
865 | [
866 | null,
867 | null,
868 | ],
869 | [
870 | null,
871 | null,
872 | ],
873 | [
874 | null,
875 | null,
876 | ],
877 | [
878 | null,
879 | null,
880 | ],
881 | ],
882 | ],
883 | ],
884 | ]
885 | `;
886 |
887 | exports[`makeMatrix > no initial values > %p [ 3, 2, 3 ] 1`] = `
888 | [
889 | [
890 | [
891 | null,
892 | null,
893 | null,
894 | ],
895 | [
896 | null,
897 | null,
898 | null,
899 | ],
900 | ],
901 | [
902 | [
903 | null,
904 | null,
905 | null,
906 | ],
907 | [
908 | null,
909 | null,
910 | null,
911 | ],
912 | ],
913 | [
914 | [
915 | null,
916 | null,
917 | null,
918 | ],
919 | [
920 | null,
921 | null,
922 | null,
923 | ],
924 | ],
925 | ]
926 | `;
927 |
928 | exports[`makeMatrix > no initial values > %p [ 6 ] 1`] = `
929 | [
930 | null,
931 | null,
932 | null,
933 | null,
934 | null,
935 | null,
936 | ]
937 | `;
938 |
939 | exports[`makeMatrix > number initial values > %p [ 1, 1 ] 1`] = `
940 | [
941 | [
942 | 0,
943 | ],
944 | ]
945 | `;
946 |
947 | exports[`makeMatrix > number initial values > %p [ 1, 4, 5, 2 ] 1`] = `
948 | [
949 | [
950 | [
951 | [
952 | 0,
953 | 0,
954 | ],
955 | [
956 | 0,
957 | 0,
958 | ],
959 | [
960 | 0,
961 | 0,
962 | ],
963 | [
964 | 0,
965 | 0,
966 | ],
967 | [
968 | 0,
969 | 0,
970 | ],
971 | ],
972 | [
973 | [
974 | 0,
975 | 0,
976 | ],
977 | [
978 | 0,
979 | 0,
980 | ],
981 | [
982 | 0,
983 | 0,
984 | ],
985 | [
986 | 0,
987 | 0,
988 | ],
989 | [
990 | 0,
991 | 0,
992 | ],
993 | ],
994 | [
995 | [
996 | 0,
997 | 0,
998 | ],
999 | [
1000 | 0,
1001 | 0,
1002 | ],
1003 | [
1004 | 0,
1005 | 0,
1006 | ],
1007 | [
1008 | 0,
1009 | 0,
1010 | ],
1011 | [
1012 | 0,
1013 | 0,
1014 | ],
1015 | ],
1016 | [
1017 | [
1018 | 0,
1019 | 0,
1020 | ],
1021 | [
1022 | 0,
1023 | 0,
1024 | ],
1025 | [
1026 | 0,
1027 | 0,
1028 | ],
1029 | [
1030 | 0,
1031 | 0,
1032 | ],
1033 | [
1034 | 0,
1035 | 0,
1036 | ],
1037 | ],
1038 | ],
1039 | ]
1040 | `;
1041 |
1042 | exports[`makeMatrix > number initial values > %p [ 2, 4, 2, 4, 2 ] 1`] = `
1043 | [
1044 | [
1045 | [
1046 | [
1047 | [
1048 | 0,
1049 | 0,
1050 | ],
1051 | [
1052 | 0,
1053 | 0,
1054 | ],
1055 | [
1056 | 0,
1057 | 0,
1058 | ],
1059 | [
1060 | 0,
1061 | 0,
1062 | ],
1063 | ],
1064 | [
1065 | [
1066 | 0,
1067 | 0,
1068 | ],
1069 | [
1070 | 0,
1071 | 0,
1072 | ],
1073 | [
1074 | 0,
1075 | 0,
1076 | ],
1077 | [
1078 | 0,
1079 | 0,
1080 | ],
1081 | ],
1082 | ],
1083 | [
1084 | [
1085 | [
1086 | 0,
1087 | 0,
1088 | ],
1089 | [
1090 | 0,
1091 | 0,
1092 | ],
1093 | [
1094 | 0,
1095 | 0,
1096 | ],
1097 | [
1098 | 0,
1099 | 0,
1100 | ],
1101 | ],
1102 | [
1103 | [
1104 | 0,
1105 | 0,
1106 | ],
1107 | [
1108 | 0,
1109 | 0,
1110 | ],
1111 | [
1112 | 0,
1113 | 0,
1114 | ],
1115 | [
1116 | 0,
1117 | 0,
1118 | ],
1119 | ],
1120 | ],
1121 | [
1122 | [
1123 | [
1124 | 0,
1125 | 0,
1126 | ],
1127 | [
1128 | 0,
1129 | 0,
1130 | ],
1131 | [
1132 | 0,
1133 | 0,
1134 | ],
1135 | [
1136 | 0,
1137 | 0,
1138 | ],
1139 | ],
1140 | [
1141 | [
1142 | 0,
1143 | 0,
1144 | ],
1145 | [
1146 | 0,
1147 | 0,
1148 | ],
1149 | [
1150 | 0,
1151 | 0,
1152 | ],
1153 | [
1154 | 0,
1155 | 0,
1156 | ],
1157 | ],
1158 | ],
1159 | [
1160 | [
1161 | [
1162 | 0,
1163 | 0,
1164 | ],
1165 | [
1166 | 0,
1167 | 0,
1168 | ],
1169 | [
1170 | 0,
1171 | 0,
1172 | ],
1173 | [
1174 | 0,
1175 | 0,
1176 | ],
1177 | ],
1178 | [
1179 | [
1180 | 0,
1181 | 0,
1182 | ],
1183 | [
1184 | 0,
1185 | 0,
1186 | ],
1187 | [
1188 | 0,
1189 | 0,
1190 | ],
1191 | [
1192 | 0,
1193 | 0,
1194 | ],
1195 | ],
1196 | ],
1197 | ],
1198 | [
1199 | [
1200 | [
1201 | [
1202 | 0,
1203 | 0,
1204 | ],
1205 | [
1206 | 0,
1207 | 0,
1208 | ],
1209 | [
1210 | 0,
1211 | 0,
1212 | ],
1213 | [
1214 | 0,
1215 | 0,
1216 | ],
1217 | ],
1218 | [
1219 | [
1220 | 0,
1221 | 0,
1222 | ],
1223 | [
1224 | 0,
1225 | 0,
1226 | ],
1227 | [
1228 | 0,
1229 | 0,
1230 | ],
1231 | [
1232 | 0,
1233 | 0,
1234 | ],
1235 | ],
1236 | ],
1237 | [
1238 | [
1239 | [
1240 | 0,
1241 | 0,
1242 | ],
1243 | [
1244 | 0,
1245 | 0,
1246 | ],
1247 | [
1248 | 0,
1249 | 0,
1250 | ],
1251 | [
1252 | 0,
1253 | 0,
1254 | ],
1255 | ],
1256 | [
1257 | [
1258 | 0,
1259 | 0,
1260 | ],
1261 | [
1262 | 0,
1263 | 0,
1264 | ],
1265 | [
1266 | 0,
1267 | 0,
1268 | ],
1269 | [
1270 | 0,
1271 | 0,
1272 | ],
1273 | ],
1274 | ],
1275 | [
1276 | [
1277 | [
1278 | 0,
1279 | 0,
1280 | ],
1281 | [
1282 | 0,
1283 | 0,
1284 | ],
1285 | [
1286 | 0,
1287 | 0,
1288 | ],
1289 | [
1290 | 0,
1291 | 0,
1292 | ],
1293 | ],
1294 | [
1295 | [
1296 | 0,
1297 | 0,
1298 | ],
1299 | [
1300 | 0,
1301 | 0,
1302 | ],
1303 | [
1304 | 0,
1305 | 0,
1306 | ],
1307 | [
1308 | 0,
1309 | 0,
1310 | ],
1311 | ],
1312 | ],
1313 | [
1314 | [
1315 | [
1316 | 0,
1317 | 0,
1318 | ],
1319 | [
1320 | 0,
1321 | 0,
1322 | ],
1323 | [
1324 | 0,
1325 | 0,
1326 | ],
1327 | [
1328 | 0,
1329 | 0,
1330 | ],
1331 | ],
1332 | [
1333 | [
1334 | 0,
1335 | 0,
1336 | ],
1337 | [
1338 | 0,
1339 | 0,
1340 | ],
1341 | [
1342 | 0,
1343 | 0,
1344 | ],
1345 | [
1346 | 0,
1347 | 0,
1348 | ],
1349 | ],
1350 | ],
1351 | ],
1352 | ]
1353 | `;
1354 |
1355 | exports[`makeMatrix > number initial values > %p [ 3, 2, 3 ] 1`] = `
1356 | [
1357 | [
1358 | [
1359 | 0,
1360 | 0,
1361 | 0,
1362 | ],
1363 | [
1364 | 0,
1365 | 0,
1366 | 0,
1367 | ],
1368 | ],
1369 | [
1370 | [
1371 | 0,
1372 | 0,
1373 | 0,
1374 | ],
1375 | [
1376 | 0,
1377 | 0,
1378 | 0,
1379 | ],
1380 | ],
1381 | [
1382 | [
1383 | 0,
1384 | 0,
1385 | 0,
1386 | ],
1387 | [
1388 | 0,
1389 | 0,
1390 | 0,
1391 | ],
1392 | ],
1393 | ]
1394 | `;
1395 |
1396 | exports[`makeMatrix > number initial values > %p [ 6 ] 1`] = `
1397 | [
1398 | 0,
1399 | 0,
1400 | 0,
1401 | 0,
1402 | 0,
1403 | 0,
1404 | ]
1405 | `;
1406 |
1407 | exports[`makeMatrix > self aware callback initial values > %p [ 1, 1 ] 1`] = `
1408 | [
1409 | [
1410 | [
1411 | 0,
1412 | 0,
1413 | ],
1414 | ],
1415 | ]
1416 | `;
1417 |
1418 | exports[`makeMatrix > self aware callback initial values > %p [ 1, 4, 5, 2 ] 1`] = `
1419 | [
1420 | [
1421 | [
1422 | [
1423 | [
1424 | 0,
1425 | 0,
1426 | 0,
1427 | 0,
1428 | ],
1429 | [
1430 | 0,
1431 | 0,
1432 | 0,
1433 | 1,
1434 | ],
1435 | ],
1436 | [
1437 | [
1438 | 0,
1439 | 0,
1440 | 1,
1441 | 0,
1442 | ],
1443 | [
1444 | 0,
1445 | 0,
1446 | 1,
1447 | 1,
1448 | ],
1449 | ],
1450 | [
1451 | [
1452 | 0,
1453 | 0,
1454 | 2,
1455 | 0,
1456 | ],
1457 | [
1458 | 0,
1459 | 0,
1460 | 2,
1461 | 1,
1462 | ],
1463 | ],
1464 | [
1465 | [
1466 | 0,
1467 | 0,
1468 | 3,
1469 | 0,
1470 | ],
1471 | [
1472 | 0,
1473 | 0,
1474 | 3,
1475 | 1,
1476 | ],
1477 | ],
1478 | [
1479 | [
1480 | 0,
1481 | 0,
1482 | 4,
1483 | 0,
1484 | ],
1485 | [
1486 | 0,
1487 | 0,
1488 | 4,
1489 | 1,
1490 | ],
1491 | ],
1492 | ],
1493 | [
1494 | [
1495 | [
1496 | 0,
1497 | 1,
1498 | 0,
1499 | 0,
1500 | ],
1501 | [
1502 | 0,
1503 | 1,
1504 | 0,
1505 | 1,
1506 | ],
1507 | ],
1508 | [
1509 | [
1510 | 0,
1511 | 1,
1512 | 1,
1513 | 0,
1514 | ],
1515 | [
1516 | 0,
1517 | 1,
1518 | 1,
1519 | 1,
1520 | ],
1521 | ],
1522 | [
1523 | [
1524 | 0,
1525 | 1,
1526 | 2,
1527 | 0,
1528 | ],
1529 | [
1530 | 0,
1531 | 1,
1532 | 2,
1533 | 1,
1534 | ],
1535 | ],
1536 | [
1537 | [
1538 | 0,
1539 | 1,
1540 | 3,
1541 | 0,
1542 | ],
1543 | [
1544 | 0,
1545 | 1,
1546 | 3,
1547 | 1,
1548 | ],
1549 | ],
1550 | [
1551 | [
1552 | 0,
1553 | 1,
1554 | 4,
1555 | 0,
1556 | ],
1557 | [
1558 | 0,
1559 | 1,
1560 | 4,
1561 | 1,
1562 | ],
1563 | ],
1564 | ],
1565 | [
1566 | [
1567 | [
1568 | 0,
1569 | 2,
1570 | 0,
1571 | 0,
1572 | ],
1573 | [
1574 | 0,
1575 | 2,
1576 | 0,
1577 | 1,
1578 | ],
1579 | ],
1580 | [
1581 | [
1582 | 0,
1583 | 2,
1584 | 1,
1585 | 0,
1586 | ],
1587 | [
1588 | 0,
1589 | 2,
1590 | 1,
1591 | 1,
1592 | ],
1593 | ],
1594 | [
1595 | [
1596 | 0,
1597 | 2,
1598 | 2,
1599 | 0,
1600 | ],
1601 | [
1602 | 0,
1603 | 2,
1604 | 2,
1605 | 1,
1606 | ],
1607 | ],
1608 | [
1609 | [
1610 | 0,
1611 | 2,
1612 | 3,
1613 | 0,
1614 | ],
1615 | [
1616 | 0,
1617 | 2,
1618 | 3,
1619 | 1,
1620 | ],
1621 | ],
1622 | [
1623 | [
1624 | 0,
1625 | 2,
1626 | 4,
1627 | 0,
1628 | ],
1629 | [
1630 | 0,
1631 | 2,
1632 | 4,
1633 | 1,
1634 | ],
1635 | ],
1636 | ],
1637 | [
1638 | [
1639 | [
1640 | 0,
1641 | 3,
1642 | 0,
1643 | 0,
1644 | ],
1645 | [
1646 | 0,
1647 | 3,
1648 | 0,
1649 | 1,
1650 | ],
1651 | ],
1652 | [
1653 | [
1654 | 0,
1655 | 3,
1656 | 1,
1657 | 0,
1658 | ],
1659 | [
1660 | 0,
1661 | 3,
1662 | 1,
1663 | 1,
1664 | ],
1665 | ],
1666 | [
1667 | [
1668 | 0,
1669 | 3,
1670 | 2,
1671 | 0,
1672 | ],
1673 | [
1674 | 0,
1675 | 3,
1676 | 2,
1677 | 1,
1678 | ],
1679 | ],
1680 | [
1681 | [
1682 | 0,
1683 | 3,
1684 | 3,
1685 | 0,
1686 | ],
1687 | [
1688 | 0,
1689 | 3,
1690 | 3,
1691 | 1,
1692 | ],
1693 | ],
1694 | [
1695 | [
1696 | 0,
1697 | 3,
1698 | 4,
1699 | 0,
1700 | ],
1701 | [
1702 | 0,
1703 | 3,
1704 | 4,
1705 | 1,
1706 | ],
1707 | ],
1708 | ],
1709 | ],
1710 | ]
1711 | `;
1712 |
1713 | exports[`makeMatrix > self aware callback initial values > %p [ 2, 4, 2, 4, 2 ] 1`] = `
1714 | [
1715 | [
1716 | [
1717 | [
1718 | [
1719 | [
1720 | 0,
1721 | 0,
1722 | 0,
1723 | 0,
1724 | 0,
1725 | ],
1726 | [
1727 | 0,
1728 | 0,
1729 | 0,
1730 | 0,
1731 | 1,
1732 | ],
1733 | ],
1734 | [
1735 | [
1736 | 0,
1737 | 0,
1738 | 0,
1739 | 1,
1740 | 0,
1741 | ],
1742 | [
1743 | 0,
1744 | 0,
1745 | 0,
1746 | 1,
1747 | 1,
1748 | ],
1749 | ],
1750 | [
1751 | [
1752 | 0,
1753 | 0,
1754 | 0,
1755 | 2,
1756 | 0,
1757 | ],
1758 | [
1759 | 0,
1760 | 0,
1761 | 0,
1762 | 2,
1763 | 1,
1764 | ],
1765 | ],
1766 | [
1767 | [
1768 | 0,
1769 | 0,
1770 | 0,
1771 | 3,
1772 | 0,
1773 | ],
1774 | [
1775 | 0,
1776 | 0,
1777 | 0,
1778 | 3,
1779 | 1,
1780 | ],
1781 | ],
1782 | ],
1783 | [
1784 | [
1785 | [
1786 | 0,
1787 | 0,
1788 | 1,
1789 | 0,
1790 | 0,
1791 | ],
1792 | [
1793 | 0,
1794 | 0,
1795 | 1,
1796 | 0,
1797 | 1,
1798 | ],
1799 | ],
1800 | [
1801 | [
1802 | 0,
1803 | 0,
1804 | 1,
1805 | 1,
1806 | 0,
1807 | ],
1808 | [
1809 | 0,
1810 | 0,
1811 | 1,
1812 | 1,
1813 | 1,
1814 | ],
1815 | ],
1816 | [
1817 | [
1818 | 0,
1819 | 0,
1820 | 1,
1821 | 2,
1822 | 0,
1823 | ],
1824 | [
1825 | 0,
1826 | 0,
1827 | 1,
1828 | 2,
1829 | 1,
1830 | ],
1831 | ],
1832 | [
1833 | [
1834 | 0,
1835 | 0,
1836 | 1,
1837 | 3,
1838 | 0,
1839 | ],
1840 | [
1841 | 0,
1842 | 0,
1843 | 1,
1844 | 3,
1845 | 1,
1846 | ],
1847 | ],
1848 | ],
1849 | ],
1850 | [
1851 | [
1852 | [
1853 | [
1854 | 0,
1855 | 1,
1856 | 0,
1857 | 0,
1858 | 0,
1859 | ],
1860 | [
1861 | 0,
1862 | 1,
1863 | 0,
1864 | 0,
1865 | 1,
1866 | ],
1867 | ],
1868 | [
1869 | [
1870 | 0,
1871 | 1,
1872 | 0,
1873 | 1,
1874 | 0,
1875 | ],
1876 | [
1877 | 0,
1878 | 1,
1879 | 0,
1880 | 1,
1881 | 1,
1882 | ],
1883 | ],
1884 | [
1885 | [
1886 | 0,
1887 | 1,
1888 | 0,
1889 | 2,
1890 | 0,
1891 | ],
1892 | [
1893 | 0,
1894 | 1,
1895 | 0,
1896 | 2,
1897 | 1,
1898 | ],
1899 | ],
1900 | [
1901 | [
1902 | 0,
1903 | 1,
1904 | 0,
1905 | 3,
1906 | 0,
1907 | ],
1908 | [
1909 | 0,
1910 | 1,
1911 | 0,
1912 | 3,
1913 | 1,
1914 | ],
1915 | ],
1916 | ],
1917 | [
1918 | [
1919 | [
1920 | 0,
1921 | 1,
1922 | 1,
1923 | 0,
1924 | 0,
1925 | ],
1926 | [
1927 | 0,
1928 | 1,
1929 | 1,
1930 | 0,
1931 | 1,
1932 | ],
1933 | ],
1934 | [
1935 | [
1936 | 0,
1937 | 1,
1938 | 1,
1939 | 1,
1940 | 0,
1941 | ],
1942 | [
1943 | 0,
1944 | 1,
1945 | 1,
1946 | 1,
1947 | 1,
1948 | ],
1949 | ],
1950 | [
1951 | [
1952 | 0,
1953 | 1,
1954 | 1,
1955 | 2,
1956 | 0,
1957 | ],
1958 | [
1959 | 0,
1960 | 1,
1961 | 1,
1962 | 2,
1963 | 1,
1964 | ],
1965 | ],
1966 | [
1967 | [
1968 | 0,
1969 | 1,
1970 | 1,
1971 | 3,
1972 | 0,
1973 | ],
1974 | [
1975 | 0,
1976 | 1,
1977 | 1,
1978 | 3,
1979 | 1,
1980 | ],
1981 | ],
1982 | ],
1983 | ],
1984 | [
1985 | [
1986 | [
1987 | [
1988 | 0,
1989 | 2,
1990 | 0,
1991 | 0,
1992 | 0,
1993 | ],
1994 | [
1995 | 0,
1996 | 2,
1997 | 0,
1998 | 0,
1999 | 1,
2000 | ],
2001 | ],
2002 | [
2003 | [
2004 | 0,
2005 | 2,
2006 | 0,
2007 | 1,
2008 | 0,
2009 | ],
2010 | [
2011 | 0,
2012 | 2,
2013 | 0,
2014 | 1,
2015 | 1,
2016 | ],
2017 | ],
2018 | [
2019 | [
2020 | 0,
2021 | 2,
2022 | 0,
2023 | 2,
2024 | 0,
2025 | ],
2026 | [
2027 | 0,
2028 | 2,
2029 | 0,
2030 | 2,
2031 | 1,
2032 | ],
2033 | ],
2034 | [
2035 | [
2036 | 0,
2037 | 2,
2038 | 0,
2039 | 3,
2040 | 0,
2041 | ],
2042 | [
2043 | 0,
2044 | 2,
2045 | 0,
2046 | 3,
2047 | 1,
2048 | ],
2049 | ],
2050 | ],
2051 | [
2052 | [
2053 | [
2054 | 0,
2055 | 2,
2056 | 1,
2057 | 0,
2058 | 0,
2059 | ],
2060 | [
2061 | 0,
2062 | 2,
2063 | 1,
2064 | 0,
2065 | 1,
2066 | ],
2067 | ],
2068 | [
2069 | [
2070 | 0,
2071 | 2,
2072 | 1,
2073 | 1,
2074 | 0,
2075 | ],
2076 | [
2077 | 0,
2078 | 2,
2079 | 1,
2080 | 1,
2081 | 1,
2082 | ],
2083 | ],
2084 | [
2085 | [
2086 | 0,
2087 | 2,
2088 | 1,
2089 | 2,
2090 | 0,
2091 | ],
2092 | [
2093 | 0,
2094 | 2,
2095 | 1,
2096 | 2,
2097 | 1,
2098 | ],
2099 | ],
2100 | [
2101 | [
2102 | 0,
2103 | 2,
2104 | 1,
2105 | 3,
2106 | 0,
2107 | ],
2108 | [
2109 | 0,
2110 | 2,
2111 | 1,
2112 | 3,
2113 | 1,
2114 | ],
2115 | ],
2116 | ],
2117 | ],
2118 | [
2119 | [
2120 | [
2121 | [
2122 | 0,
2123 | 3,
2124 | 0,
2125 | 0,
2126 | 0,
2127 | ],
2128 | [
2129 | 0,
2130 | 3,
2131 | 0,
2132 | 0,
2133 | 1,
2134 | ],
2135 | ],
2136 | [
2137 | [
2138 | 0,
2139 | 3,
2140 | 0,
2141 | 1,
2142 | 0,
2143 | ],
2144 | [
2145 | 0,
2146 | 3,
2147 | 0,
2148 | 1,
2149 | 1,
2150 | ],
2151 | ],
2152 | [
2153 | [
2154 | 0,
2155 | 3,
2156 | 0,
2157 | 2,
2158 | 0,
2159 | ],
2160 | [
2161 | 0,
2162 | 3,
2163 | 0,
2164 | 2,
2165 | 1,
2166 | ],
2167 | ],
2168 | [
2169 | [
2170 | 0,
2171 | 3,
2172 | 0,
2173 | 3,
2174 | 0,
2175 | ],
2176 | [
2177 | 0,
2178 | 3,
2179 | 0,
2180 | 3,
2181 | 1,
2182 | ],
2183 | ],
2184 | ],
2185 | [
2186 | [
2187 | [
2188 | 0,
2189 | 3,
2190 | 1,
2191 | 0,
2192 | 0,
2193 | ],
2194 | [
2195 | 0,
2196 | 3,
2197 | 1,
2198 | 0,
2199 | 1,
2200 | ],
2201 | ],
2202 | [
2203 | [
2204 | 0,
2205 | 3,
2206 | 1,
2207 | 1,
2208 | 0,
2209 | ],
2210 | [
2211 | 0,
2212 | 3,
2213 | 1,
2214 | 1,
2215 | 1,
2216 | ],
2217 | ],
2218 | [
2219 | [
2220 | 0,
2221 | 3,
2222 | 1,
2223 | 2,
2224 | 0,
2225 | ],
2226 | [
2227 | 0,
2228 | 3,
2229 | 1,
2230 | 2,
2231 | 1,
2232 | ],
2233 | ],
2234 | [
2235 | [
2236 | 0,
2237 | 3,
2238 | 1,
2239 | 3,
2240 | 0,
2241 | ],
2242 | [
2243 | 0,
2244 | 3,
2245 | 1,
2246 | 3,
2247 | 1,
2248 | ],
2249 | ],
2250 | ],
2251 | ],
2252 | ],
2253 | [
2254 | [
2255 | [
2256 | [
2257 | [
2258 | 1,
2259 | 0,
2260 | 0,
2261 | 0,
2262 | 0,
2263 | ],
2264 | [
2265 | 1,
2266 | 0,
2267 | 0,
2268 | 0,
2269 | 1,
2270 | ],
2271 | ],
2272 | [
2273 | [
2274 | 1,
2275 | 0,
2276 | 0,
2277 | 1,
2278 | 0,
2279 | ],
2280 | [
2281 | 1,
2282 | 0,
2283 | 0,
2284 | 1,
2285 | 1,
2286 | ],
2287 | ],
2288 | [
2289 | [
2290 | 1,
2291 | 0,
2292 | 0,
2293 | 2,
2294 | 0,
2295 | ],
2296 | [
2297 | 1,
2298 | 0,
2299 | 0,
2300 | 2,
2301 | 1,
2302 | ],
2303 | ],
2304 | [
2305 | [
2306 | 1,
2307 | 0,
2308 | 0,
2309 | 3,
2310 | 0,
2311 | ],
2312 | [
2313 | 1,
2314 | 0,
2315 | 0,
2316 | 3,
2317 | 1,
2318 | ],
2319 | ],
2320 | ],
2321 | [
2322 | [
2323 | [
2324 | 1,
2325 | 0,
2326 | 1,
2327 | 0,
2328 | 0,
2329 | ],
2330 | [
2331 | 1,
2332 | 0,
2333 | 1,
2334 | 0,
2335 | 1,
2336 | ],
2337 | ],
2338 | [
2339 | [
2340 | 1,
2341 | 0,
2342 | 1,
2343 | 1,
2344 | 0,
2345 | ],
2346 | [
2347 | 1,
2348 | 0,
2349 | 1,
2350 | 1,
2351 | 1,
2352 | ],
2353 | ],
2354 | [
2355 | [
2356 | 1,
2357 | 0,
2358 | 1,
2359 | 2,
2360 | 0,
2361 | ],
2362 | [
2363 | 1,
2364 | 0,
2365 | 1,
2366 | 2,
2367 | 1,
2368 | ],
2369 | ],
2370 | [
2371 | [
2372 | 1,
2373 | 0,
2374 | 1,
2375 | 3,
2376 | 0,
2377 | ],
2378 | [
2379 | 1,
2380 | 0,
2381 | 1,
2382 | 3,
2383 | 1,
2384 | ],
2385 | ],
2386 | ],
2387 | ],
2388 | [
2389 | [
2390 | [
2391 | [
2392 | 1,
2393 | 1,
2394 | 0,
2395 | 0,
2396 | 0,
2397 | ],
2398 | [
2399 | 1,
2400 | 1,
2401 | 0,
2402 | 0,
2403 | 1,
2404 | ],
2405 | ],
2406 | [
2407 | [
2408 | 1,
2409 | 1,
2410 | 0,
2411 | 1,
2412 | 0,
2413 | ],
2414 | [
2415 | 1,
2416 | 1,
2417 | 0,
2418 | 1,
2419 | 1,
2420 | ],
2421 | ],
2422 | [
2423 | [
2424 | 1,
2425 | 1,
2426 | 0,
2427 | 2,
2428 | 0,
2429 | ],
2430 | [
2431 | 1,
2432 | 1,
2433 | 0,
2434 | 2,
2435 | 1,
2436 | ],
2437 | ],
2438 | [
2439 | [
2440 | 1,
2441 | 1,
2442 | 0,
2443 | 3,
2444 | 0,
2445 | ],
2446 | [
2447 | 1,
2448 | 1,
2449 | 0,
2450 | 3,
2451 | 1,
2452 | ],
2453 | ],
2454 | ],
2455 | [
2456 | [
2457 | [
2458 | 1,
2459 | 1,
2460 | 1,
2461 | 0,
2462 | 0,
2463 | ],
2464 | [
2465 | 1,
2466 | 1,
2467 | 1,
2468 | 0,
2469 | 1,
2470 | ],
2471 | ],
2472 | [
2473 | [
2474 | 1,
2475 | 1,
2476 | 1,
2477 | 1,
2478 | 0,
2479 | ],
2480 | [
2481 | 1,
2482 | 1,
2483 | 1,
2484 | 1,
2485 | 1,
2486 | ],
2487 | ],
2488 | [
2489 | [
2490 | 1,
2491 | 1,
2492 | 1,
2493 | 2,
2494 | 0,
2495 | ],
2496 | [
2497 | 1,
2498 | 1,
2499 | 1,
2500 | 2,
2501 | 1,
2502 | ],
2503 | ],
2504 | [
2505 | [
2506 | 1,
2507 | 1,
2508 | 1,
2509 | 3,
2510 | 0,
2511 | ],
2512 | [
2513 | 1,
2514 | 1,
2515 | 1,
2516 | 3,
2517 | 1,
2518 | ],
2519 | ],
2520 | ],
2521 | ],
2522 | [
2523 | [
2524 | [
2525 | [
2526 | 1,
2527 | 2,
2528 | 0,
2529 | 0,
2530 | 0,
2531 | ],
2532 | [
2533 | 1,
2534 | 2,
2535 | 0,
2536 | 0,
2537 | 1,
2538 | ],
2539 | ],
2540 | [
2541 | [
2542 | 1,
2543 | 2,
2544 | 0,
2545 | 1,
2546 | 0,
2547 | ],
2548 | [
2549 | 1,
2550 | 2,
2551 | 0,
2552 | 1,
2553 | 1,
2554 | ],
2555 | ],
2556 | [
2557 | [
2558 | 1,
2559 | 2,
2560 | 0,
2561 | 2,
2562 | 0,
2563 | ],
2564 | [
2565 | 1,
2566 | 2,
2567 | 0,
2568 | 2,
2569 | 1,
2570 | ],
2571 | ],
2572 | [
2573 | [
2574 | 1,
2575 | 2,
2576 | 0,
2577 | 3,
2578 | 0,
2579 | ],
2580 | [
2581 | 1,
2582 | 2,
2583 | 0,
2584 | 3,
2585 | 1,
2586 | ],
2587 | ],
2588 | ],
2589 | [
2590 | [
2591 | [
2592 | 1,
2593 | 2,
2594 | 1,
2595 | 0,
2596 | 0,
2597 | ],
2598 | [
2599 | 1,
2600 | 2,
2601 | 1,
2602 | 0,
2603 | 1,
2604 | ],
2605 | ],
2606 | [
2607 | [
2608 | 1,
2609 | 2,
2610 | 1,
2611 | 1,
2612 | 0,
2613 | ],
2614 | [
2615 | 1,
2616 | 2,
2617 | 1,
2618 | 1,
2619 | 1,
2620 | ],
2621 | ],
2622 | [
2623 | [
2624 | 1,
2625 | 2,
2626 | 1,
2627 | 2,
2628 | 0,
2629 | ],
2630 | [
2631 | 1,
2632 | 2,
2633 | 1,
2634 | 2,
2635 | 1,
2636 | ],
2637 | ],
2638 | [
2639 | [
2640 | 1,
2641 | 2,
2642 | 1,
2643 | 3,
2644 | 0,
2645 | ],
2646 | [
2647 | 1,
2648 | 2,
2649 | 1,
2650 | 3,
2651 | 1,
2652 | ],
2653 | ],
2654 | ],
2655 | ],
2656 | [
2657 | [
2658 | [
2659 | [
2660 | 1,
2661 | 3,
2662 | 0,
2663 | 0,
2664 | 0,
2665 | ],
2666 | [
2667 | 1,
2668 | 3,
2669 | 0,
2670 | 0,
2671 | 1,
2672 | ],
2673 | ],
2674 | [
2675 | [
2676 | 1,
2677 | 3,
2678 | 0,
2679 | 1,
2680 | 0,
2681 | ],
2682 | [
2683 | 1,
2684 | 3,
2685 | 0,
2686 | 1,
2687 | 1,
2688 | ],
2689 | ],
2690 | [
2691 | [
2692 | 1,
2693 | 3,
2694 | 0,
2695 | 2,
2696 | 0,
2697 | ],
2698 | [
2699 | 1,
2700 | 3,
2701 | 0,
2702 | 2,
2703 | 1,
2704 | ],
2705 | ],
2706 | [
2707 | [
2708 | 1,
2709 | 3,
2710 | 0,
2711 | 3,
2712 | 0,
2713 | ],
2714 | [
2715 | 1,
2716 | 3,
2717 | 0,
2718 | 3,
2719 | 1,
2720 | ],
2721 | ],
2722 | ],
2723 | [
2724 | [
2725 | [
2726 | 1,
2727 | 3,
2728 | 1,
2729 | 0,
2730 | 0,
2731 | ],
2732 | [
2733 | 1,
2734 | 3,
2735 | 1,
2736 | 0,
2737 | 1,
2738 | ],
2739 | ],
2740 | [
2741 | [
2742 | 1,
2743 | 3,
2744 | 1,
2745 | 1,
2746 | 0,
2747 | ],
2748 | [
2749 | 1,
2750 | 3,
2751 | 1,
2752 | 1,
2753 | 1,
2754 | ],
2755 | ],
2756 | [
2757 | [
2758 | 1,
2759 | 3,
2760 | 1,
2761 | 2,
2762 | 0,
2763 | ],
2764 | [
2765 | 1,
2766 | 3,
2767 | 1,
2768 | 2,
2769 | 1,
2770 | ],
2771 | ],
2772 | [
2773 | [
2774 | 1,
2775 | 3,
2776 | 1,
2777 | 3,
2778 | 0,
2779 | ],
2780 | [
2781 | 1,
2782 | 3,
2783 | 1,
2784 | 3,
2785 | 1,
2786 | ],
2787 | ],
2788 | ],
2789 | ],
2790 | ],
2791 | ]
2792 | `;
2793 |
2794 | exports[`makeMatrix > self aware callback initial values > %p [ 3, 2, 3 ] 1`] = `
2795 | [
2796 | [
2797 | [
2798 | [
2799 | 0,
2800 | 0,
2801 | 0,
2802 | ],
2803 | [
2804 | 0,
2805 | 0,
2806 | 1,
2807 | ],
2808 | [
2809 | 0,
2810 | 0,
2811 | 2,
2812 | ],
2813 | ],
2814 | [
2815 | [
2816 | 0,
2817 | 1,
2818 | 0,
2819 | ],
2820 | [
2821 | 0,
2822 | 1,
2823 | 1,
2824 | ],
2825 | [
2826 | 0,
2827 | 1,
2828 | 2,
2829 | ],
2830 | ],
2831 | ],
2832 | [
2833 | [
2834 | [
2835 | 1,
2836 | 0,
2837 | 0,
2838 | ],
2839 | [
2840 | 1,
2841 | 0,
2842 | 1,
2843 | ],
2844 | [
2845 | 1,
2846 | 0,
2847 | 2,
2848 | ],
2849 | ],
2850 | [
2851 | [
2852 | 1,
2853 | 1,
2854 | 0,
2855 | ],
2856 | [
2857 | 1,
2858 | 1,
2859 | 1,
2860 | ],
2861 | [
2862 | 1,
2863 | 1,
2864 | 2,
2865 | ],
2866 | ],
2867 | ],
2868 | [
2869 | [
2870 | [
2871 | 2,
2872 | 0,
2873 | 0,
2874 | ],
2875 | [
2876 | 2,
2877 | 0,
2878 | 1,
2879 | ],
2880 | [
2881 | 2,
2882 | 0,
2883 | 2,
2884 | ],
2885 | ],
2886 | [
2887 | [
2888 | 2,
2889 | 1,
2890 | 0,
2891 | ],
2892 | [
2893 | 2,
2894 | 1,
2895 | 1,
2896 | ],
2897 | [
2898 | 2,
2899 | 1,
2900 | 2,
2901 | ],
2902 | ],
2903 | ],
2904 | ]
2905 | `;
2906 |
2907 | exports[`makeMatrix > self aware callback initial values > %p [ 6 ] 1`] = `
2908 | [
2909 | [
2910 | 0,
2911 | ],
2912 | [
2913 | 1,
2914 | ],
2915 | [
2916 | 2,
2917 | ],
2918 | [
2919 | 3,
2920 | ],
2921 | [
2922 | 4,
2923 | ],
2924 | [
2925 | 5,
2926 | ],
2927 | ]
2928 | `;
2929 |
2930 | exports[`makeMatrix > string initial values > %p [ 1, 1 ] 1`] = `
2931 | [
2932 | [
2933 | "string",
2934 | ],
2935 | ]
2936 | `;
2937 |
2938 | exports[`makeMatrix > string initial values > %p [ 1, 4, 5, 2 ] 1`] = `
2939 | [
2940 | [
2941 | [
2942 | [
2943 | "string",
2944 | "string",
2945 | ],
2946 | [
2947 | "string",
2948 | "string",
2949 | ],
2950 | [
2951 | "string",
2952 | "string",
2953 | ],
2954 | [
2955 | "string",
2956 | "string",
2957 | ],
2958 | [
2959 | "string",
2960 | "string",
2961 | ],
2962 | ],
2963 | [
2964 | [
2965 | "string",
2966 | "string",
2967 | ],
2968 | [
2969 | "string",
2970 | "string",
2971 | ],
2972 | [
2973 | "string",
2974 | "string",
2975 | ],
2976 | [
2977 | "string",
2978 | "string",
2979 | ],
2980 | [
2981 | "string",
2982 | "string",
2983 | ],
2984 | ],
2985 | [
2986 | [
2987 | "string",
2988 | "string",
2989 | ],
2990 | [
2991 | "string",
2992 | "string",
2993 | ],
2994 | [
2995 | "string",
2996 | "string",
2997 | ],
2998 | [
2999 | "string",
3000 | "string",
3001 | ],
3002 | [
3003 | "string",
3004 | "string",
3005 | ],
3006 | ],
3007 | [
3008 | [
3009 | "string",
3010 | "string",
3011 | ],
3012 | [
3013 | "string",
3014 | "string",
3015 | ],
3016 | [
3017 | "string",
3018 | "string",
3019 | ],
3020 | [
3021 | "string",
3022 | "string",
3023 | ],
3024 | [
3025 | "string",
3026 | "string",
3027 | ],
3028 | ],
3029 | ],
3030 | ]
3031 | `;
3032 |
3033 | exports[`makeMatrix > string initial values > %p [ 2, 4, 2, 4, 2 ] 1`] = `
3034 | [
3035 | [
3036 | [
3037 | [
3038 | [
3039 | "string",
3040 | "string",
3041 | ],
3042 | [
3043 | "string",
3044 | "string",
3045 | ],
3046 | [
3047 | "string",
3048 | "string",
3049 | ],
3050 | [
3051 | "string",
3052 | "string",
3053 | ],
3054 | ],
3055 | [
3056 | [
3057 | "string",
3058 | "string",
3059 | ],
3060 | [
3061 | "string",
3062 | "string",
3063 | ],
3064 | [
3065 | "string",
3066 | "string",
3067 | ],
3068 | [
3069 | "string",
3070 | "string",
3071 | ],
3072 | ],
3073 | ],
3074 | [
3075 | [
3076 | [
3077 | "string",
3078 | "string",
3079 | ],
3080 | [
3081 | "string",
3082 | "string",
3083 | ],
3084 | [
3085 | "string",
3086 | "string",
3087 | ],
3088 | [
3089 | "string",
3090 | "string",
3091 | ],
3092 | ],
3093 | [
3094 | [
3095 | "string",
3096 | "string",
3097 | ],
3098 | [
3099 | "string",
3100 | "string",
3101 | ],
3102 | [
3103 | "string",
3104 | "string",
3105 | ],
3106 | [
3107 | "string",
3108 | "string",
3109 | ],
3110 | ],
3111 | ],
3112 | [
3113 | [
3114 | [
3115 | "string",
3116 | "string",
3117 | ],
3118 | [
3119 | "string",
3120 | "string",
3121 | ],
3122 | [
3123 | "string",
3124 | "string",
3125 | ],
3126 | [
3127 | "string",
3128 | "string",
3129 | ],
3130 | ],
3131 | [
3132 | [
3133 | "string",
3134 | "string",
3135 | ],
3136 | [
3137 | "string",
3138 | "string",
3139 | ],
3140 | [
3141 | "string",
3142 | "string",
3143 | ],
3144 | [
3145 | "string",
3146 | "string",
3147 | ],
3148 | ],
3149 | ],
3150 | [
3151 | [
3152 | [
3153 | "string",
3154 | "string",
3155 | ],
3156 | [
3157 | "string",
3158 | "string",
3159 | ],
3160 | [
3161 | "string",
3162 | "string",
3163 | ],
3164 | [
3165 | "string",
3166 | "string",
3167 | ],
3168 | ],
3169 | [
3170 | [
3171 | "string",
3172 | "string",
3173 | ],
3174 | [
3175 | "string",
3176 | "string",
3177 | ],
3178 | [
3179 | "string",
3180 | "string",
3181 | ],
3182 | [
3183 | "string",
3184 | "string",
3185 | ],
3186 | ],
3187 | ],
3188 | ],
3189 | [
3190 | [
3191 | [
3192 | [
3193 | "string",
3194 | "string",
3195 | ],
3196 | [
3197 | "string",
3198 | "string",
3199 | ],
3200 | [
3201 | "string",
3202 | "string",
3203 | ],
3204 | [
3205 | "string",
3206 | "string",
3207 | ],
3208 | ],
3209 | [
3210 | [
3211 | "string",
3212 | "string",
3213 | ],
3214 | [
3215 | "string",
3216 | "string",
3217 | ],
3218 | [
3219 | "string",
3220 | "string",
3221 | ],
3222 | [
3223 | "string",
3224 | "string",
3225 | ],
3226 | ],
3227 | ],
3228 | [
3229 | [
3230 | [
3231 | "string",
3232 | "string",
3233 | ],
3234 | [
3235 | "string",
3236 | "string",
3237 | ],
3238 | [
3239 | "string",
3240 | "string",
3241 | ],
3242 | [
3243 | "string",
3244 | "string",
3245 | ],
3246 | ],
3247 | [
3248 | [
3249 | "string",
3250 | "string",
3251 | ],
3252 | [
3253 | "string",
3254 | "string",
3255 | ],
3256 | [
3257 | "string",
3258 | "string",
3259 | ],
3260 | [
3261 | "string",
3262 | "string",
3263 | ],
3264 | ],
3265 | ],
3266 | [
3267 | [
3268 | [
3269 | "string",
3270 | "string",
3271 | ],
3272 | [
3273 | "string",
3274 | "string",
3275 | ],
3276 | [
3277 | "string",
3278 | "string",
3279 | ],
3280 | [
3281 | "string",
3282 | "string",
3283 | ],
3284 | ],
3285 | [
3286 | [
3287 | "string",
3288 | "string",
3289 | ],
3290 | [
3291 | "string",
3292 | "string",
3293 | ],
3294 | [
3295 | "string",
3296 | "string",
3297 | ],
3298 | [
3299 | "string",
3300 | "string",
3301 | ],
3302 | ],
3303 | ],
3304 | [
3305 | [
3306 | [
3307 | "string",
3308 | "string",
3309 | ],
3310 | [
3311 | "string",
3312 | "string",
3313 | ],
3314 | [
3315 | "string",
3316 | "string",
3317 | ],
3318 | [
3319 | "string",
3320 | "string",
3321 | ],
3322 | ],
3323 | [
3324 | [
3325 | "string",
3326 | "string",
3327 | ],
3328 | [
3329 | "string",
3330 | "string",
3331 | ],
3332 | [
3333 | "string",
3334 | "string",
3335 | ],
3336 | [
3337 | "string",
3338 | "string",
3339 | ],
3340 | ],
3341 | ],
3342 | ],
3343 | ]
3344 | `;
3345 |
3346 | exports[`makeMatrix > string initial values > %p [ 3, 2, 3 ] 1`] = `
3347 | [
3348 | [
3349 | [
3350 | "string",
3351 | "string",
3352 | "string",
3353 | ],
3354 | [
3355 | "string",
3356 | "string",
3357 | "string",
3358 | ],
3359 | ],
3360 | [
3361 | [
3362 | "string",
3363 | "string",
3364 | "string",
3365 | ],
3366 | [
3367 | "string",
3368 | "string",
3369 | "string",
3370 | ],
3371 | ],
3372 | [
3373 | [
3374 | "string",
3375 | "string",
3376 | "string",
3377 | ],
3378 | [
3379 | "string",
3380 | "string",
3381 | "string",
3382 | ],
3383 | ],
3384 | ]
3385 | `;
3386 |
3387 | exports[`makeMatrix > string initial values > %p [ 6 ] 1`] = `
3388 | [
3389 | "string",
3390 | "string",
3391 | "string",
3392 | "string",
3393 | "string",
3394 | "string",
3395 | ]
3396 | `;
3397 |
--------------------------------------------------------------------------------
/src/__tests__/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, test } from "vitest";
2 |
3 | import { makeMatrix } from "../index";
4 |
5 | const testCases = [[6], [1, 1], [3, 2, 3], [1, 4, 5, 2], [2, 4, 2, 4, 2]];
6 |
7 | /** So cases can be used as both test titles and test values during a `test.each` run */
8 | const iterativeTestCases = testCases.map(c => [c, c]);
9 |
10 | describe("makeMatrix", () => {
11 | describe("no initial values", () => {
12 | test.each(iterativeTestCases)("%p", dimensions => {
13 | expect(makeMatrix(dimensions)).toMatchSnapshot();
14 | });
15 | });
16 |
17 | describe("string initial values", () => {
18 | test.each(iterativeTestCases)("%p", dimensions => {
19 | expect(makeMatrix(dimensions, "string")).toMatchSnapshot();
20 | });
21 | });
22 |
23 | describe("number initial values", () => {
24 | test.each(iterativeTestCases)("%p", dimensions => {
25 | expect(makeMatrix(dimensions, 0)).toMatchSnapshot();
26 | });
27 | });
28 |
29 | describe("callback initial values — math", () => {
30 | test.each(iterativeTestCases)("%p", dimensions => {
31 | expect(makeMatrix(dimensions, () => 10 - 2)).toMatchSnapshot();
32 | });
33 | });
34 |
35 | describe("self aware callback initial values", () => {
36 | test.each(iterativeTestCases)("%p", dimensions => {
37 | expect(makeMatrix(dimensions, vector => vector)).toMatchSnapshot();
38 | });
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/src/__tests__/types.test.ts:
--------------------------------------------------------------------------------
1 | import { assertType, describe, test } from "vitest";
2 |
3 | import { makeMatrix } from "../index";
4 |
5 | describe("assert types", () => {
6 | test("resolves to the correct type", () => {
7 | assertType(makeMatrix([1, 1, 1, 1], "hello"));
8 | assertType(makeMatrix([4, 5], ([a]) => a));
9 | assertType(makeMatrix([4], v => v[0].toString()));
10 | assertType(makeMatrix([] as number[]));
11 |
12 | assertType<(0 | 1)[]>(
13 | makeMatrix([1], () => (Math.random() > 0.5 ? (0 as const) : (1 as const)))
14 | );
15 |
16 | assertType<{ x: number; y: number; z: number }[][][]>(
17 | makeMatrix([4, 5, 6], ([x, y, z]) => ({ x, y, z }))
18 | );
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import type { Matrix, Vector } from "./types.js";
2 |
3 | /**
4 | * Creates a matrix (multi-dimensional array) with your desired dimensions and values.
5 | *
6 | * @param dimensions The desired dimensions of the matrix.
7 | * @param initialValues The initial value for each point in the matrix. Can also take a callback function—with an argument that resolves to the current point's vector—to fill the matrix dynamically. Defaults to `null`.
8 | *
9 | * @example
10 | * const threeXThreeXTwoArray = makeMatrix([3, 3, 2]); // A 3x3x2 array
11 | * const twoDNumberArray = makeMatrix([3, 5], 0); // A 3x5 array containing 0
12 | * const twoDRandomNumberArray = makeMatrix([1, 4], () => Math.random()); // A 1x4 array containing random numbers
13 | * const twoDVectorArray = makeMatrix([3, 3], vector => vector.join()); // A 3x3 array containing each point's co-ordinate as a string
14 | */
15 | const makeMatrix = (
16 | dimensions: Vector,
17 | initialValues: T | ((currentPosition: Vector) => T) | null = null
18 | ): Matrix => {
19 | const initialPosition = Array(dimensions.length).fill(0) as Vector;
20 | return _makeMatrix(dimensions, initialValues, initialPosition);
21 | };
22 |
23 | /**
24 | * Recursively creates a matrix (depth first), and keeps track of the current position's vector.
25 | */
26 | function _makeMatrix(
27 | dimensions: Vector,
28 | initialValues: T | ((currentPosition: Vector) => T) | null,
29 | currentPosition: Vector
30 | ): Matrix {
31 | const [currentDimensionLength, ...remainingDimensions] = dimensions;
32 | const currentDimension = currentPosition.length - remainingDimensions.length - 1;
33 |
34 | return [...Array(currentDimensionLength)].map((_, i) => {
35 | currentPosition[currentDimension] = i;
36 | return remainingDimensions.length > 0
37 | ? _makeMatrix(remainingDimensions as Vector, initialValues, currentPosition)
38 | : initialValues instanceof Function
39 | ? initialValues(currentPosition.slice() as Vector)
40 | : initialValues;
41 | }) as Matrix;
42 | }
43 |
44 | export { makeMatrix, type Matrix };
45 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * A typed multidimensional array returned by `makeMatrix`.
3 | */
4 | export type Matrix = Brand<_Matrix>;
5 |
6 | /**
7 | * Recursively constructs a `Matrix` type and keeps track of the number of recursions.
8 | *
9 | * @remarks
10 | * When a `_Matrix` is created without knowing it's exact size or number of dimensions, such
11 | * as when creating one dynamically, it's impossible recursively construct a type for it.
12 | * Instead, we short circuit the type to resolve to `unknown[]`. This ensures an array of at
13 | * least one dimension is returned, but is unable to provide any more safety than that.
14 | */
15 | type _Matrix<
16 | D extends number,
17 | T = unknown,
18 | RecursionCountArray extends number[] = [],
19 | > = number extends D
20 | ? unknown[]
21 | : D extends RecursionCountArray["length"]
22 | ? T
23 | : _Matrix;
24 |
25 | /**
26 | * An array of numbers with defined length, corresponding to points in a `Matrix`.
27 | *
28 | * @see {@link https://github.com/microsoft/TypeScript/issues/26223} for discussion and other
29 | * implementations, though this seems to be the only one that works properly for `makeMatrix`'s use case.
30 | *
31 | * @remarks
32 | * When a `Vector` is created without knowing the exact number of dimensions, such as when
33 | * creating one dynamically, we short circuit the type to resolve to `number[]` so that
34 | * `makeMatrix` can accept a dynamically created `dimensions` parameter.
35 | */
36 | export type Vector = Brand<
37 | number extends D ? number[] : [number, ...number[]] & { readonly length: D }
38 | >;
39 |
40 | /**
41 | * Stops intellisense from expanding types and exposing their more complicated internals to users.
42 | *
43 | * @see {@link https://github.com/microsoft/TypeScript/issues/31940} for discussion
44 | */
45 | type Brand = D & {};
46 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | // Taken from @total-typescript/tsconfig/bundler/no-dom/library, which doesn't work well with ts-node
4 | "compilerOptions": {
5 | /* Base Options: */
6 | "esModuleInterop": true,
7 | "skipLibCheck": true,
8 | "target": "es2022",
9 | "allowJs": true,
10 | "resolveJsonModule": true,
11 | "moduleDetection": "force",
12 | "isolatedModules": true,
13 | "verbatimModuleSyntax": true,
14 | /* Strictness */
15 | "strict": true,
16 | "noUncheckedIndexedAccess": true,
17 | "noImplicitOverride": true,
18 | /* If NOT transpiling with TypeScript: */
19 | "module": "preserve",
20 | "noEmit": true,
21 | /* If your code doesn't run in the DOM: */
22 | "lib": ["es2022"]
23 | },
24 | "include": ["src"],
25 | "exclude": ["node_modules", "**/__tests__/*"]
26 | }
27 |
--------------------------------------------------------------------------------