chore: documentation and optimization
What a rhyme.
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
import * as esbuild from "esbuild";
|
||||
|
||||
const result = esbuild.buildSync({
|
||||
entryPoints: ["src/index.ts"],
|
||||
bundle: true,
|
||||
minify: true,
|
||||
outdir: "dist",
|
||||
define: {
|
||||
"import.meta.vitest": "undefined",
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,165 @@
|
||||
import { writeFileSync } from "fs";
|
||||
import { relative } from "path";
|
||||
|
||||
function capitalize(/** @type {string} */ s) {
|
||||
return s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase();
|
||||
}
|
||||
|
||||
const script = import.meta.filename;
|
||||
|
||||
const path = "./src/mixin/math/swizzlePermutations.d.ts";
|
||||
const axis = ["x", "y", "z", "w", "v"];
|
||||
|
||||
const property = ["first", "second", "third", "fourth", "fifth"];
|
||||
|
||||
const mixin = "./src/mixin/base/mixin";
|
||||
|
||||
let conditional = "";
|
||||
|
||||
for (let n = 0; n < axis.length; n++) {
|
||||
if (n === axis.length - 1) {
|
||||
conditional += `Swizzle${n + 1}D<T, t>`;
|
||||
break;
|
||||
}
|
||||
const type = new Array(n + 1).fill("number").join(", ");
|
||||
const indent = "\t".repeat(n + 1);
|
||||
conditional += `T extends readonly [${type}]\n`;
|
||||
conditional += `${indent}? Swizzle${n + 1}D<T, t>\n`;
|
||||
conditional += `${indent}: `;
|
||||
}
|
||||
|
||||
const type = new Array(axis.length).fill("number").join(", ");
|
||||
|
||||
let src = `
|
||||
// .d.ts file auto-generated by ${relative(path, script)}
|
||||
// Do not edit
|
||||
|
||||
import type { Props, Return } from '${relative(path, mixin)}';
|
||||
|
||||
type IsValid<T extends readonly number[]> = number extends T['length']
|
||||
? false
|
||||
: T extends readonly []
|
||||
? false
|
||||
: true;
|
||||
|
||||
export type SwizzleProps<T extends readonly number[], t extends Props> =
|
||||
IsValid<T> extends false
|
||||
? {}
|
||||
: ${conditional
|
||||
.split("\n")
|
||||
.map((line) => "\t\t" + line)
|
||||
.join("\n")
|
||||
.trimStart()};
|
||||
|
||||
export interface ISwizzle<
|
||||
T extends readonly [${type}] =
|
||||
readonly [${type}],
|
||||
t extends Props = Props
|
||||
> extends Swizzle${axis.length}D<T, t> {};
|
||||
|
||||
`.trimStart();
|
||||
|
||||
for (let n = 0; n < axis.length; n++) {
|
||||
const state = new Array(axis.length).fill(-1);
|
||||
|
||||
const props = [];
|
||||
|
||||
outer: do {
|
||||
for (let i = state.length - 1; i >= 0; i--)
|
||||
if (++state[i] > n) {
|
||||
state[i] = -1;
|
||||
} else break;
|
||||
|
||||
let nulled = false;
|
||||
for (const item of state) {
|
||||
if (item === -1) {
|
||||
nulled = true;
|
||||
continue;
|
||||
}
|
||||
if (nulled) continue outer;
|
||||
}
|
||||
if (state.every((x) => x === -1)) break;
|
||||
|
||||
const key = state
|
||||
.filter((x) => x !== -1)
|
||||
.map((x) => axis[x])
|
||||
.join("");
|
||||
if (state.slice(1).every((x) => x === -1)) {
|
||||
const arr = [5, 3, 8, 2, 1].map((x) =>
|
||||
Math.abs(x - n - state[0]),
|
||||
);
|
||||
props.push({
|
||||
doc: `
|
||||
/**
|
||||
* Vector-style accessor, ${property[state[0]]} property of the value
|
||||
* @from {@link Math \`Math\`}
|
||||
* @example
|
||||
* \`\`\`ts
|
||||
* const vec = [${arr
|
||||
.slice(0, Math.max(n + 1, 2))
|
||||
.map((n) => n.toString())
|
||||
.join(", ")}] as const;
|
||||
*
|
||||
* const ${axis[state[0]]} = $(vec).${axis[state[0]]}.value;
|
||||
* expect(${axis[state[0]]}).toBe(${arr[state[0]]})
|
||||
* \`\`\`
|
||||
*/`.trimStart(),
|
||||
property: `readonly ${key}: Return<T[${state[0]}], t>`,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
if (state.every((x) => x === count++)) continue;
|
||||
|
||||
const arr = [6, 2, 3, 5, 4, 7].map((x, idx) =>
|
||||
Math.abs(x - state[idx]),
|
||||
);
|
||||
|
||||
const type = state
|
||||
.filter((x) => x !== -1)
|
||||
.map((x) => `T[${x}]`)
|
||||
.join(", ");
|
||||
props.push({
|
||||
doc: `
|
||||
/**
|
||||
* Vector-style swizzle accessor, rearannges the elements of the value
|
||||
*
|
||||
* Equivalent to \`[${state
|
||||
.filter((x) => x !== -1)
|
||||
.map((x) => `vec[${x}]`)
|
||||
.join(", ")}]\`
|
||||
* @from {@link Math \`Math\`}
|
||||
* @example
|
||||
* \`\`\`ts
|
||||
* const vec = [${arr.slice(0, n + 1).join(", ")}] as const;
|
||||
*
|
||||
* const ${key} = $(vec).${key}().value;
|
||||
* expect(${key}).toMatchObject([${state
|
||||
.filter((x) => x !== -1)
|
||||
.map((x) => arr[x])
|
||||
.join(", ")}])
|
||||
* \`\`\`
|
||||
*/
|
||||
`.trimStart(),
|
||||
property: `readonly ${key}: () => Return<[${type}], t>`,
|
||||
});
|
||||
} while (state.some((x) => x !== -1));
|
||||
|
||||
props.sort((a, b) => a.property.length - b.property.length);
|
||||
|
||||
src += `interface Swizzle${n + 1}D<T extends readonly [${new Array(n + 1).fill("number").join(", ")}], t extends Props> {\n`;
|
||||
src += `${props
|
||||
.map((x) =>
|
||||
[x.doc, x.property]
|
||||
.join("\n")
|
||||
.split("\n")
|
||||
.map((line) => "\t" + line)
|
||||
.join("\n"),
|
||||
)
|
||||
.join("\n")}\n`;
|
||||
src += "}\n";
|
||||
src += "\n";
|
||||
}
|
||||
|
||||
writeFileSync(path, src);
|
||||
Reference in New Issue
Block a user