From aa9f7a5dcd8a5025e07c8b8e2f2853a0303e45e5 Mon Sep 17 00:00:00 2001 From: Jumpei Ogawa Date: Wed, 27 May 2026 14:16:41 +0900 Subject: [PATCH 1/9] feat: remove `sleep()` Replace it with `es-toolkit`'s `delay()`. --- src/universal.ts | 1 - src/universal/sleep.test.ts | 11 ----------- src/universal/sleep.ts | 9 --------- 3 files changed, 21 deletions(-) delete mode 100644 src/universal/sleep.test.ts delete mode 100644 src/universal/sleep.ts diff --git a/src/universal.ts b/src/universal.ts index 3114f34..11ee4a6 100644 --- a/src/universal.ts +++ b/src/universal.ts @@ -4,5 +4,4 @@ export { getLastElementOf } from "./universal/get-last-element-of.ts"; export { npmPackageExists } from "./universal/npm-package-exists.ts"; export { pseudoRandomInt } from "./universal/pseudo-random-int.ts"; export { pseudoRandomString } from "./universal/pseudo-random-string.ts"; -export { sleep } from "./universal/sleep.ts"; export { sortObjects } from "./universal/sort-objects.ts"; diff --git a/src/universal/sleep.test.ts b/src/universal/sleep.test.ts deleted file mode 100644 index c6c7028..0000000 --- a/src/universal/sleep.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { expect, test } from "vitest"; -import { sleep } from "../universal.ts"; - -test("sleep", async () => { - const startAt = new Date(); - await sleep(5000); - const endAt = new Date(); - - expect(+endAt - +startAt).toBeGreaterThan(4900); - expect(+endAt - +startAt).toBeLessThan(5100); -}, 10000); diff --git a/src/universal/sleep.ts b/src/universal/sleep.ts deleted file mode 100644 index cb454f8..0000000 --- a/src/universal/sleep.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Sleep for the specified time. - * @param ms - The time to wait (in milliseconds). - * @returns A promise object. - */ -export const sleep = async (ms: number): Promise => - new Promise((resolve) => { - setTimeout(() => resolve(), ms); - }); From 1fd82bb64105717a4d6b6941e4c1e0d4e765bbb4 Mon Sep 17 00:00:00 2001 From: Jumpei Ogawa Date: Wed, 27 May 2026 14:18:33 +0900 Subject: [PATCH 2/9] feat: rename `pseudoRandomInt()` to `pseudoRandomPositiveInt()` --- src/universal.ts | 2 +- ....test.ts => pseudo-random-positive-int.test.ts} | 14 +++++++------- ...random-int.ts => pseudo-random-positive-int.ts} | 2 +- src/universal/pseudo-random-string.test.ts | 4 ++-- src/universal/pseudo-random-string.ts | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) rename src/universal/{pseudo-random-int.test.ts => pseudo-random-positive-int.test.ts} (78%) rename src/universal/{pseudo-random-int.ts => pseudo-random-positive-int.ts} (86%) diff --git a/src/universal.ts b/src/universal.ts index 11ee4a6..e772704 100644 --- a/src/universal.ts +++ b/src/universal.ts @@ -2,6 +2,6 @@ export { deduplicate } from "./universal/deduplicate.ts"; export { trimLines } from "./universal/trim-lines.ts"; export { getLastElementOf } from "./universal/get-last-element-of.ts"; export { npmPackageExists } from "./universal/npm-package-exists.ts"; -export { pseudoRandomInt } from "./universal/pseudo-random-int.ts"; +export { pseudoRandomPositiveInt } from "./universal/pseudo-random-positive-int.ts"; export { pseudoRandomString } from "./universal/pseudo-random-string.ts"; export { sortObjects } from "./universal/sort-objects.ts"; diff --git a/src/universal/pseudo-random-int.test.ts b/src/universal/pseudo-random-positive-int.test.ts similarity index 78% rename from src/universal/pseudo-random-int.test.ts rename to src/universal/pseudo-random-positive-int.test.ts index f94d260..bf479d0 100644 --- a/src/universal/pseudo-random-int.test.ts +++ b/src/universal/pseudo-random-positive-int.test.ts @@ -1,10 +1,10 @@ import { ok } from "node:assert"; import { describe, expect, test } from "vitest"; -import { pseudoRandomInt } from "./pseudo-random-int.ts"; +import { pseudoRandomPositiveInt } from "./pseudo-random-positive-int.ts"; describe("pseudoRandomInt()", () => { test("returns a number within valid range", () => { - const generatedNumber = pseudoRandomInt(100); + const generatedNumber = pseudoRandomPositiveInt(100); expect(generatedNumber).toBeLessThanOrEqual(100); expect(generatedNumber).toBeGreaterThanOrEqual(0); @@ -12,17 +12,17 @@ describe("pseudoRandomInt()", () => { }); test("returns an integer (no decimals)", () => { - const generatedNumber = pseudoRandomInt(100); + const generatedNumber = pseudoRandomPositiveInt(100); ok(Number.isInteger(generatedNumber)); }); test("handles max value of 0 (returns 0)", () => { - const generatedNumber = pseudoRandomInt(0); + const generatedNumber = pseudoRandomPositiveInt(0); expect(generatedNumber).toBe(0); }); test("returns 0 or 1 for max value of 1", () => { - const generatedNumber = pseudoRandomInt(1); + const generatedNumber = pseudoRandomPositiveInt(1); expect([ 0, 1 ]).toContain(generatedNumber); }); @@ -32,7 +32,7 @@ describe("pseudoRandomInt()", () => { // Generate multiple random numbers to test distribution for (let i = 0; i < 100; i++) { - const generatedNumber = pseudoRandomInt(max); + const generatedNumber = pseudoRandomPositiveInt(max); results.add(generatedNumber); expect(generatedNumber).toBeGreaterThanOrEqual(0); expect(generatedNumber).toBeLessThanOrEqual(max); @@ -47,7 +47,7 @@ describe("pseudoRandomInt()", () => { const max = 1000000; for (let i = 0; i < 100; i++) { - const generatedNumber = pseudoRandomInt(max); + const generatedNumber = pseudoRandomPositiveInt(max); expect(generatedNumber).toBeGreaterThanOrEqual(0); expect(generatedNumber).toBeLessThanOrEqual(max); expect(Number.isInteger(generatedNumber)).toBe(true); diff --git a/src/universal/pseudo-random-int.ts b/src/universal/pseudo-random-positive-int.ts similarity index 86% rename from src/universal/pseudo-random-int.ts rename to src/universal/pseudo-random-positive-int.ts index 742eda7..fa957c8 100644 --- a/src/universal/pseudo-random-int.ts +++ b/src/universal/pseudo-random-positive-int.ts @@ -4,7 +4,7 @@ * @param max - max number of the generated random number * @returns pseudo-random non-negative integer number */ -export const pseudoRandomInt = (max: number): number => { +export const pseudoRandomPositiveInt = (max: number): number => { if (!Number.isFinite(max) || max < 0) { throw new RangeError("max must be a finite, non-negative number"); } diff --git a/src/universal/pseudo-random-string.test.ts b/src/universal/pseudo-random-string.test.ts index 100b692..e1a4058 100644 --- a/src/universal/pseudo-random-string.test.ts +++ b/src/universal/pseudo-random-string.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "vitest"; -import { pseudoRandomInt } from "./pseudo-random-int.ts"; +import { pseudoRandomPositiveInt } from "./pseudo-random-positive-int.ts"; import { pseudoRandomString } from "./pseudo-random-string.ts"; describe("pseudoRandomString()", () => { @@ -34,7 +34,7 @@ describe("pseudoRandomString()", () => { }); test("works with different length values", () => { - for (const length of Array.from({ length: 5 }, () => pseudoRandomInt(500) + 1)) { + for (const length of Array.from({ length: 5 }, () => pseudoRandomPositiveInt(500) + 1)) { const generatedString = pseudoRandomString(length); expect(generatedString).toHaveLength(length); expect(typeof generatedString).toBe("string"); diff --git a/src/universal/pseudo-random-string.ts b/src/universal/pseudo-random-string.ts index 6b802a5..624fc8a 100644 --- a/src/universal/pseudo-random-string.ts +++ b/src/universal/pseudo-random-string.ts @@ -1,4 +1,4 @@ -import { pseudoRandomInt } from "./pseudo-random-int.ts"; +import { pseudoRandomPositiveInt } from "./pseudo-random-positive-int.ts"; import { chars } from "./pseudo-random-string-chars.ts"; /** @@ -13,7 +13,7 @@ export const pseudoRandomString = (length: number): string => { } return Array.from({ length }, () => { - const index = pseudoRandomInt(chars.length - 1); + const index = pseudoRandomPositiveInt(chars.length - 1); return chars[index]; }).join(""); }; From 0b8600f095c07670f8c25e92c541c3670f63b7b8 Mon Sep 17 00:00:00 2001 From: Jumpei Ogawa Date: Wed, 27 May 2026 14:27:25 +0900 Subject: [PATCH 3/9] test: move tests to different directory to apply tsconfig for Node.js --- src/{nodejs => universal}/tsconfig.json | 2 +- {src/universal => test}/deduplicate.test.ts | 2 +- {src/universal => test}/get-last-element-of.test.ts | 2 +- {src/nodejs => test}/load-json.test.ts | 4 ++-- {src/universal => test}/pseudo-random-positive-int.test.ts | 2 +- {src/universal => test}/pseudo-random-string.test.ts | 4 ++-- {src/universal => test}/sort-objects.test.ts | 2 +- {src/universal => test}/trim-lines.test.ts | 2 +- tsconfig.json | 6 ++++-- 9 files changed, 14 insertions(+), 12 deletions(-) rename src/{nodejs => universal}/tsconfig.json (76%) rename {src/universal => test}/deduplicate.test.ts (92%) rename {src/universal => test}/get-last-element-of.test.ts (96%) rename {src/nodejs => test}/load-json.test.ts (65%) rename {src/universal => test}/pseudo-random-positive-int.test.ts (95%) rename {src/universal => test}/pseudo-random-string.test.ts (91%) rename {src/universal => test}/sort-objects.test.ts (85%) rename {src/universal => test}/trim-lines.test.ts (84%) diff --git a/src/nodejs/tsconfig.json b/src/universal/tsconfig.json similarity index 76% rename from src/nodejs/tsconfig.json rename to src/universal/tsconfig.json index 1c53588..af12237 100644 --- a/src/nodejs/tsconfig.json +++ b/src/universal/tsconfig.json @@ -1,6 +1,6 @@ { "extends": [ - "@phanect/configs/ts/nodejs", + "@phanect/configs/ts", "@phanect/configs/ts/addons/npm" ], "include": [ diff --git a/src/universal/deduplicate.test.ts b/test/deduplicate.test.ts similarity index 92% rename from src/universal/deduplicate.test.ts rename to test/deduplicate.test.ts index 1acad8c..a1d15c8 100644 --- a/src/universal/deduplicate.test.ts +++ b/test/deduplicate.test.ts @@ -1,5 +1,5 @@ import { expect, test } from "vitest"; -import { deduplicate } from "../universal.ts"; +import { deduplicate } from "../src/universal.ts"; test("deduplicate", () => { const deduplicated = deduplicate([ diff --git a/src/universal/get-last-element-of.test.ts b/test/get-last-element-of.test.ts similarity index 96% rename from src/universal/get-last-element-of.test.ts rename to test/get-last-element-of.test.ts index be35f0d..d8a969f 100644 --- a/src/universal/get-last-element-of.test.ts +++ b/test/get-last-element-of.test.ts @@ -1,5 +1,5 @@ import { expect, test } from "vitest"; -import { getLastElementOf } from "../universal.ts"; +import { getLastElementOf } from "../src/universal.ts"; test("getLastElementOf (without index)", () => { const lastElement = getLastElementOf([ "a", "b", "c" ]); diff --git a/src/nodejs/load-json.test.ts b/test/load-json.test.ts similarity index 65% rename from src/nodejs/load-json.test.ts rename to test/load-json.test.ts index 94e9aa4..d7c4831 100644 --- a/src/nodejs/load-json.test.ts +++ b/test/load-json.test.ts @@ -1,10 +1,10 @@ import { join } from "node:path"; import { expect, test } from "vitest"; -import { loadJSON } from "../nodejs.ts"; +import { loadJSON } from "../src/nodejs.ts"; test("loadJSON", async () => { const obj = await loadJSON( - join(import.meta.dirname, "../../test/fixtures/load-json/fixture.json"), + join(import.meta.dirname, "fixtures/load-json/fixture.json"), ); expect(obj).toStrictEqual({ diff --git a/src/universal/pseudo-random-positive-int.test.ts b/test/pseudo-random-positive-int.test.ts similarity index 95% rename from src/universal/pseudo-random-positive-int.test.ts rename to test/pseudo-random-positive-int.test.ts index bf479d0..241724d 100644 --- a/src/universal/pseudo-random-positive-int.test.ts +++ b/test/pseudo-random-positive-int.test.ts @@ -1,6 +1,6 @@ import { ok } from "node:assert"; import { describe, expect, test } from "vitest"; -import { pseudoRandomPositiveInt } from "./pseudo-random-positive-int.ts"; +import { pseudoRandomPositiveInt } from "../src/universal/pseudo-random-positive-int.ts"; describe("pseudoRandomInt()", () => { test("returns a number within valid range", () => { diff --git a/src/universal/pseudo-random-string.test.ts b/test/pseudo-random-string.test.ts similarity index 91% rename from src/universal/pseudo-random-string.test.ts rename to test/pseudo-random-string.test.ts index e1a4058..63b7c5e 100644 --- a/src/universal/pseudo-random-string.test.ts +++ b/test/pseudo-random-string.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from "vitest"; -import { pseudoRandomPositiveInt } from "./pseudo-random-positive-int.ts"; -import { pseudoRandomString } from "./pseudo-random-string.ts"; +import { pseudoRandomPositiveInt } from "../src/universal/pseudo-random-positive-int.ts"; +import { pseudoRandomString } from "../src/universal/pseudo-random-string.ts"; describe("pseudoRandomString()", () => { test("returns a string with the correct length", () => { diff --git a/src/universal/sort-objects.test.ts b/test/sort-objects.test.ts similarity index 85% rename from src/universal/sort-objects.test.ts rename to test/sort-objects.test.ts index d40f12c..ad7b6fe 100644 --- a/src/universal/sort-objects.test.ts +++ b/test/sort-objects.test.ts @@ -1,5 +1,5 @@ import { expect, test } from "vitest"; -import { sortObjects } from "../universal.ts"; +import { sortObjects } from "../src/universal.ts"; test("sortObjects", () => { const result = sortObjects([ diff --git a/src/universal/trim-lines.test.ts b/test/trim-lines.test.ts similarity index 84% rename from src/universal/trim-lines.test.ts rename to test/trim-lines.test.ts index 86f448f..13bbac1 100644 --- a/src/universal/trim-lines.test.ts +++ b/test/trim-lines.test.ts @@ -1,5 +1,5 @@ import { expect, test } from "vitest"; -import { trimLines } from "../universal.ts"; +import { trimLines } from "../src/universal.ts"; test("deindent", () => { const before = ` diff --git a/tsconfig.json b/tsconfig.json index 4c0b5bd..da88f07 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "extends": [ - "@phanect/configs/ts", + "@phanect/configs/ts/nodejs", "@phanect/configs/ts/addons/npm" ], "include": [ @@ -12,6 +12,8 @@ ], "exclude": [ "dist", - "node_modules" + "node_modules", + // Use different tsconfig.json for universal code + "./src/universal/**" ] } From 4ad1121cbe04148f7f391e164ecdc7b343303cd9 Mon Sep 17 00:00:00 2001 From: Jumpei Ogawa Date: Wed, 27 May 2026 14:40:11 +0900 Subject: [PATCH 4/9] feat: move `npmPackageExists()` to Node.js functions --- src/nodejs.ts | 1 + src/{universal => nodejs}/npm-package-exists.ts | 2 +- src/universal.ts | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) rename src/{universal => nodejs}/npm-package-exists.ts (95%) diff --git a/src/nodejs.ts b/src/nodejs.ts index a97b7ab..c39ec8f 100644 --- a/src/nodejs.ts +++ b/src/nodejs.ts @@ -1 +1,2 @@ export { loadJSON } from "./nodejs/load-json.ts"; +export { npmPackageExists } from "./nodejs/npm-package-exists.ts"; diff --git a/src/universal/npm-package-exists.ts b/src/nodejs/npm-package-exists.ts similarity index 95% rename from src/universal/npm-package-exists.ts rename to src/nodejs/npm-package-exists.ts index 46934c1..975cece 100644 --- a/src/universal/npm-package-exists.ts +++ b/src/nodejs/npm-package-exists.ts @@ -1,4 +1,4 @@ -import { trimLines } from "./trim-lines.ts"; +import { trimLines } from "../universal/trim-lines.ts"; export const npmPackageExists = async (pkgName: string): Promise => { const res = await fetch(`https://registry.npmjs.com/${ pkgName }`); diff --git a/src/universal.ts b/src/universal.ts index e772704..e83027e 100644 --- a/src/universal.ts +++ b/src/universal.ts @@ -1,7 +1,6 @@ export { deduplicate } from "./universal/deduplicate.ts"; export { trimLines } from "./universal/trim-lines.ts"; export { getLastElementOf } from "./universal/get-last-element-of.ts"; -export { npmPackageExists } from "./universal/npm-package-exists.ts"; export { pseudoRandomPositiveInt } from "./universal/pseudo-random-positive-int.ts"; export { pseudoRandomString } from "./universal/pseudo-random-string.ts"; export { sortObjects } from "./universal/sort-objects.ts"; From c9e64df8551a95f30b3f302c27dc00b528c18d68 Mon Sep 17 00:00:00 2001 From: Jumpei Ogawa Date: Wed, 27 May 2026 13:48:09 +0900 Subject: [PATCH 5/9] feat: drop support for Node.js v20 and add v26 --- .github/workflows/actions.yml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index b02512c..f93ed55 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -43,9 +43,9 @@ jobs: strategy: matrix: node-version: - - 20 - 22 - 24 + - 26 env: # Override Node.js version over mise.toml MISE_NODE_VERSION: ${{ matrix.node-version }} diff --git a/package.json b/package.json index f40d6ef..854fff9 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "vitest": "^4.0.4" }, "engines": { - "node": "^20.11.0 || ^22.16.0 || >=24.0.0", + "node": "^22.16.0 || ^24.0.0 || ^26.0.0", "pnpm": ">=10.x" }, "packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402" From a56a257a51c863d0260bf39253dbbd05f2edbcd1 Mon Sep 17 00:00:00 2001 From: Jumpei Ogawa Date: Wed, 27 May 2026 13:53:23 +0900 Subject: [PATCH 6/9] chore: pin `@phanect/configs` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 854fff9..c516f63 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ } }, "devDependencies": { - "@phanect/configs": "latest", + "@phanect/configs": "2026.5.19", "@phanect/lint": "latest", "@types/node": "^24.7.1", "eslint": "^9.21.0", From da6e023b785e03c6c362b9b19798c5d812c59c6f Mon Sep 17 00:00:00 2001 From: Jumpei Ogawa Date: Wed, 27 May 2026 14:02:13 +0900 Subject: [PATCH 7/9] chore: update TypeScript, ESLint, & tsdown --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c516f63..75dab2d 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,10 @@ "@phanect/configs": "2026.5.19", "@phanect/lint": "latest", "@types/node": "^24.7.1", - "eslint": "^9.21.0", + "eslint": "^10.4.0", "jiti": "^2.4.2", - "tsdown": "0.21.7", - "typescript": "^5.3.3", + "tsdown": "0.22.0", + "typescript": "^6.0.3", "vitest": "^4.0.4" }, "engines": { From f50abb9df24599ad54a0fd7a6a4f4ee08dbd84e8 Mon Sep 17 00:00:00 2001 From: Jumpei Ogawa Date: Wed, 27 May 2026 13:51:32 +0900 Subject: [PATCH 8/9] chore: update pnpm --- package.json | 5 ++--- pnpm-workspace.yaml | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 75dab2d..c6b1a26 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,7 @@ "vitest": "^4.0.4" }, "engines": { - "node": "^22.16.0 || ^24.0.0 || ^26.0.0", - "pnpm": ">=10.x" + "node": "^22.16.0 || ^24.0.0 || ^26.0.0" }, - "packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402" + "packageManager": "pnpm@11.3.0+sha512.2c403d6594527287672b1f7056343a1f7c3634036a67ffabfcc2b3d7595d843768f8787148d1b57cf7956c90606bbd192857c363af19e96d2d0ec9ec5741d215" } diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index cb8238f..6c750ff 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,2 @@ -onlyBuiltDependencies: - - esbuild - - unrs-resolver +allowBuilds: + unrs-resolver: true From 1e27b97d00d64fd52650c0254d48952f16c7f65b Mon Sep 17 00:00:00 2001 From: Jumpei Ogawa Date: Wed, 27 May 2026 14:19:20 +0900 Subject: [PATCH 9/9] chore: v4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c6b1a26..8e43f8d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@phanect/utils", - "version": "3.0.0", + "version": "4.0.0", "description": "@phanect's personal utility library for JavaScript & TypeScript", "repository": { "type": "git",