@forthtilliath/ts-kit 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/dist/array/index.d.ts +1 -0
- package/dist/array/index.d.ts.map +1 -1
- package/dist/array/index.js +1 -0
- package/dist/array/swapItems.d.ts +16 -0
- package/dist/array/swapItems.d.ts.map +1 -0
- package/dist/array/swapItems.js +24 -0
- package/dist/image/compressImage.d.ts +12 -0
- package/dist/image/compressImage.d.ts.map +1 -0
- package/dist/image/compressImage.js +43 -0
- package/dist/image/index.d.ts +2 -0
- package/dist/image/index.d.ts.map +1 -0
- package/dist/image/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -46,6 +46,9 @@ import { chunk } from "@forthtilliath/ts-kit/array/chunk";
|
|
|
46
46
|
- `rankByNameMatch(items, query, getName)` — ranks `items` by relevance to
|
|
47
47
|
`query`: earlier match position first, then shorter name — for a
|
|
48
48
|
search-as-you-type list.
|
|
49
|
+
- `swapItems(items, i, j)` — copy of `items` with the elements at `i` and `j`
|
|
50
|
+
swapped (e.g. moving an item up/down) — a plain copy if either position is
|
|
51
|
+
out of bounds.
|
|
49
52
|
|
|
50
53
|
### `async`
|
|
51
54
|
|
|
@@ -103,6 +106,13 @@ import { chunk } from "@forthtilliath/ts-kit/array/chunk";
|
|
|
103
106
|
- `randomId()` — `crypto.randomUUID()` with fallbacks for older/insecure
|
|
104
107
|
contexts.
|
|
105
108
|
|
|
109
|
+
### `image`
|
|
110
|
+
|
|
111
|
+
- `compressImage(file, { maxWidth?, quality? })` — browser-side compression
|
|
112
|
+
via the Canvas API: scales down to `maxWidth` (default 2400px, aspect ratio
|
|
113
|
+
kept) and converts to WebP (default quality 0.82). Non-image files are
|
|
114
|
+
returned unchanged.
|
|
115
|
+
|
|
106
116
|
### `markdown`
|
|
107
117
|
|
|
108
118
|
- `parseChangelogNotes(notes)` — parses a small subset of Markdown
|
package/dist/array/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/array/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/array/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC"}
|
package/dist/array/index.js
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a copy of `items` with the elements at positions `i` and `j`
|
|
3
|
+
* swapped (e.g. moving an item up or down in a reorderable list). Never
|
|
4
|
+
* mutates `items`, and stays sound under `noUncheckedIndexedAccess`.
|
|
5
|
+
*
|
|
6
|
+
* @param items - The array to copy.
|
|
7
|
+
* @param i - The position of the first element.
|
|
8
|
+
* @param j - The position of the second element.
|
|
9
|
+
* @returns A new array with both elements swapped, or a plain copy if either
|
|
10
|
+
* position is out of bounds.
|
|
11
|
+
* @example
|
|
12
|
+
* swapItems(["a", "b", "c"], 0, 2); // => ["c", "b", "a"]
|
|
13
|
+
* swapItems(["a", "b", "c"], 0, 5); // => ["a", "b", "c"]
|
|
14
|
+
*/
|
|
15
|
+
export declare function swapItems<T>(items: readonly T[], i: number, j: number): T[];
|
|
16
|
+
//# sourceMappingURL=swapItems.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swapItems.d.ts","sourceRoot":"","sources":["../../src/array/swapItems.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,CAQ3E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a copy of `items` with the elements at positions `i` and `j`
|
|
3
|
+
* swapped (e.g. moving an item up or down in a reorderable list). Never
|
|
4
|
+
* mutates `items`, and stays sound under `noUncheckedIndexedAccess`.
|
|
5
|
+
*
|
|
6
|
+
* @param items - The array to copy.
|
|
7
|
+
* @param i - The position of the first element.
|
|
8
|
+
* @param j - The position of the second element.
|
|
9
|
+
* @returns A new array with both elements swapped, or a plain copy if either
|
|
10
|
+
* position is out of bounds.
|
|
11
|
+
* @example
|
|
12
|
+
* swapItems(["a", "b", "c"], 0, 2); // => ["c", "b", "a"]
|
|
13
|
+
* swapItems(["a", "b", "c"], 0, 5); // => ["a", "b", "c"]
|
|
14
|
+
*/
|
|
15
|
+
export function swapItems(items, i, j) {
|
|
16
|
+
const next = [...items];
|
|
17
|
+
const a = next[i];
|
|
18
|
+
const b = next[j];
|
|
19
|
+
if (a === undefined || b === undefined)
|
|
20
|
+
return next;
|
|
21
|
+
next[i] = b;
|
|
22
|
+
next[j] = a;
|
|
23
|
+
return next;
|
|
24
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CompressImageOptions {
|
|
2
|
+
/** Images wider than this are scaled down, keeping their aspect ratio. */
|
|
3
|
+
maxWidth?: number;
|
|
4
|
+
/** WebP quality, between 0 and 1. */
|
|
5
|
+
quality?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Compresses an image in the browser via the Canvas API and converts it to WebP.
|
|
9
|
+
* Non-image files are returned unchanged.
|
|
10
|
+
*/
|
|
11
|
+
export declare function compressImage(file: File, { maxWidth, quality }?: CompressImageOptions): Promise<File>;
|
|
12
|
+
//# sourceMappingURL=compressImage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressImage.d.ts","sourceRoot":"","sources":["../../src/image/compressImage.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,IAAI,EACV,EAAE,QAAe,EAAE,OAAc,EAAE,GAAE,oBAAyB,GAC7D,OAAO,CAAC,IAAI,CAAC,CAiDf"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compresses an image in the browser via the Canvas API and converts it to WebP.
|
|
3
|
+
* Non-image files are returned unchanged.
|
|
4
|
+
*/
|
|
5
|
+
export async function compressImage(file, { maxWidth = 2400, quality = 0.82 } = {}) {
|
|
6
|
+
if (!file.type.startsWith("image/"))
|
|
7
|
+
return file;
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
const img = new Image();
|
|
10
|
+
const objectUrl = URL.createObjectURL(file);
|
|
11
|
+
img.onload = () => {
|
|
12
|
+
URL.revokeObjectURL(objectUrl);
|
|
13
|
+
let width = img.naturalWidth;
|
|
14
|
+
let height = img.naturalHeight;
|
|
15
|
+
if (width > maxWidth) {
|
|
16
|
+
height = Math.round((height * maxWidth) / width);
|
|
17
|
+
width = maxWidth;
|
|
18
|
+
}
|
|
19
|
+
const canvas = document.createElement("canvas");
|
|
20
|
+
canvas.width = width;
|
|
21
|
+
canvas.height = height;
|
|
22
|
+
const ctx = canvas.getContext("2d");
|
|
23
|
+
if (!ctx) {
|
|
24
|
+
reject(new Error("Canvas 2D context is not supported"));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
28
|
+
canvas.toBlob((blob) => {
|
|
29
|
+
if (!blob) {
|
|
30
|
+
reject(new Error("Image compression failed"));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const name = file.name.replace(/\.[^.]+$/, ".webp");
|
|
34
|
+
resolve(new File([blob], name, { type: "image/webp" }));
|
|
35
|
+
}, "image/webp", quality);
|
|
36
|
+
};
|
|
37
|
+
img.onerror = () => {
|
|
38
|
+
URL.revokeObjectURL(objectUrl);
|
|
39
|
+
reject(new Error("Failed to load image"));
|
|
40
|
+
};
|
|
41
|
+
img.src = objectUrl;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/image/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./compressImage.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./classes/index.js";
|
|
|
4
4
|
export * from "./date/index.js";
|
|
5
5
|
export * from "./files/index.js";
|
|
6
6
|
export * from "./id/index.js";
|
|
7
|
+
export * from "./image/index.js";
|
|
7
8
|
export * from "./markdown/index.js";
|
|
8
9
|
export * from "./maths/index.js";
|
|
9
10
|
export * from "./number/index.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./classes/index.js";
|
|
|
9
9
|
export * from "./date/index.js";
|
|
10
10
|
export * from "./files/index.js";
|
|
11
11
|
export * from "./id/index.js";
|
|
12
|
+
export * from "./image/index.js";
|
|
12
13
|
export * from "./markdown/index.js";
|
|
13
14
|
export * from "./maths/index.js";
|
|
14
15
|
export * from "./number/index.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forthtilliath/ts-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -21,12 +21,13 @@
|
|
|
21
21
|
"./*": "./dist/*.js"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
+
"@vitest/coverage-v8": "4.1.10",
|
|
24
25
|
"eslint": "10.7.0",
|
|
25
26
|
"jsdom": "^29.1.1",
|
|
26
27
|
"typescript": "^5.9.3",
|
|
27
28
|
"vitest": "^4.1.10",
|
|
28
|
-
"@forthtilliath/
|
|
29
|
-
"@forthtilliath/
|
|
29
|
+
"@forthtilliath/typescript-config": "0.1.1",
|
|
30
|
+
"@forthtilliath/eslint-config": "0.7.0"
|
|
30
31
|
},
|
|
31
32
|
"scripts": {
|
|
32
33
|
"dev": "tsc --watch -p tsconfig.build.json",
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
"lint": "eslint . --max-warnings 0",
|
|
36
37
|
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
|
|
37
38
|
"test": "vitest run",
|
|
38
|
-
"test:watch": "vitest"
|
|
39
|
+
"test:watch": "vitest",
|
|
40
|
+
"coverage": "vitest run --coverage"
|
|
39
41
|
}
|
|
40
42
|
}
|