diff --git a/package-lock.json b/package-lock.json index 120d317..c3b4cbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "style-loader": "^3.3.2", "ts-loader": "^9.5.1", "ts-node": "^10.9.2", - "typescript": "^5.3.3", + "typescript": "^5.4.2", "webpack": "^5.76.2", "webpack-cli": "^5.0.1", "webpack-dev-server": "^5.0.2", @@ -2527,9 +2527,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", - "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", + "version": "20.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", + "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -3343,9 +3343,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001594", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz", - "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==", + "version": "1.0.30001596", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz", + "integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==", "dev": true, "funding": [ { @@ -3985,9 +3985,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.693", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.693.tgz", - "integrity": "sha512-/if4Ueg0GUQlhCrW2ZlXwDAm40ipuKo+OgeHInlL8sbjt+hzISxZK949fZeJaVsheamrzANXvw1zQTvbxTvSHw==", + "version": "1.4.698", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.698.tgz", + "integrity": "sha512-f9iZD1t3CLy1AS6vzM5EKGa6p9pRcOeEFXRFbaG2Ta+Oe7MkfRQ3fsvPYidzHe1h4i0JvIvpcY55C+B6BZNGtQ==", "dev": true }, "node_modules/emoji-regex": { @@ -6668,12 +6668,12 @@ } }, "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", + "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", "dev": true, "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -7800,9 +7800,9 @@ } }, "node_modules/terser": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.0.tgz", - "integrity": "sha512-RXY80V6CBOVdZhyVwqsUHxOGcdFYSU1pCHTEF9UcQ2OWsacZiSyykd7CfAKfZFI6yfbRntv9EaoMW2TQNpyXjg==", + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz", + "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -8128,9 +8128,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 9175043..6380e66 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "style-loader": "^3.3.2", "ts-loader": "^9.5.1", "ts-node": "^10.9.2", - "typescript": "^5.3.3", + "typescript": "^5.4.2", "webpack": "^5.76.2", "webpack-cli": "^5.0.1", "webpack-dev-server": "^5.0.2", diff --git a/src/base.ts b/src/base.ts index 6446716..c9cbf59 100644 --- a/src/base.ts +++ b/src/base.ts @@ -256,19 +256,6 @@ export function renderLink(id: string, type: ItemType, names: I18nObject) { )}">${formatName(names)}</a>`; } -export function groupBy<W, T>(f: (w: W) => T, ws?: W[]): Map<T, W[]> { - const map = new Map<T, W[]>(); - return ( - ws?.reduce((m, w) => { - const key = f(w); - const arr = m.get(key) ?? []; - arr.push(w); - m.set(key, arr); - return m; - }, map) ?? map - ); -} - function renderQTableRow( materials: Material[], objects: (OfMaterial | [Domain, number])[], diff --git a/src/components/characters_table.ts b/src/components/characters_table.ts index 674700f..1453acc 100644 --- a/src/components/characters_table.ts +++ b/src/components/characters_table.ts @@ -1,4 +1,4 @@ -import { TYPE_CHARACTER, groupBy, renderLink } from "../base"; +import { TYPE_CHARACTER, renderLink } from "../base"; import { hasBookmarks } from "../bookmarks"; import { DELIMITER, I18nObject, formatName } from "../i18n"; import { Character, characters } from "../models/characters"; @@ -8,7 +8,7 @@ const title: I18nObject = { en: "Characters", "zh-CN": "角色" }; export class CharactersTable extends HTMLElement { constructor() { super(); - const byRarity = groupBy((o) => o.rarity, characters); + const byRarity = Map.groupBy(characters, ({ rarity }) => rarity); const rarities = Array.from(byRarity.keys()).sort().reverse(); this.innerHTML = `<details class="section" ${hasBookmarks() ? "" : "open"}> <summary>🦸 ${formatName(title)}</summary> diff --git a/src/components/enemies_table.ts b/src/components/enemies_table.ts index 7ff827f..3e4109a 100644 --- a/src/components/enemies_table.ts +++ b/src/components/enemies_table.ts @@ -7,7 +7,6 @@ import { TYPE_WEEKLY_BOSS, getTimezone, getWeekday, - groupBy, renderDomainLink, renderLink, } from "../base"; @@ -37,14 +36,14 @@ const regions: Record<Region, I18nObject> = { export class EnemiesTable extends HTMLElement { constructor() { super(); - const weeklyBosses: Map<Region, Enemies.Boss[]> = groupBy( - (b) => b.region, + const weeklyBosses: Map<Region, Enemies.Boss[]> = Map.groupBy( Enemies.bosses.filter((b) => b.type === TYPE_WEEKLY_BOSS), + (b) => b.region, ); const weeklyBossKeys = Array.from(weeklyBosses.keys()); - const bosses: Map<Region, Enemies.Boss[]> = groupBy( - (b) => b.region, + const bosses: Map<Region, Enemies.Boss[]> = Map.groupBy( Enemies.bosses.filter((b) => b.type === TYPE_BOSS), + ({ region }) => region, ); const bossKeys = Array.from(bosses.keys()); const talentDomains = Enemies.domains.filter( diff --git a/src/components/weapons_table.ts b/src/components/weapons_table.ts index 9626aca..bc0c4cd 100644 --- a/src/components/weapons_table.ts +++ b/src/components/weapons_table.ts @@ -1,4 +1,4 @@ -import { TYPE_WEAPON, groupBy, renderLink } from "../base"; +import { TYPE_WEAPON, renderLink } from "../base"; import { hasBookmarks } from "../bookmarks"; import { DELIMITER, I18nObject, formatName } from "../i18n"; import { Category, Weapon, weapons } from "../models/weapons"; @@ -7,15 +7,15 @@ const title: I18nObject = { en: "Weapons", "zh-CN": "武器" }; export class WeaponsTable extends HTMLElement { constructor() { super(); - const byRarity = groupBy((w) => w.rarity, weapons); + const byRarity = Map.groupBy(weapons, ({ rarity }) => rarity); const rarities = Array.from(byRarity.keys()).sort().reverse(); this.innerHTML = `<details class="section" ${hasBookmarks() ? "" : "open"}> <summary>🗡️ ${formatName(title)}</summary><table class="ctable"> ${rarities .map((rarity) => { - const ws2: Map<Category, Weapon[]> = groupBy( - (w) => w.category, - byRarity.get(rarity), + const ws2: Map<Category, Weapon[]> = Map.groupBy( + byRarity.get(rarity) || [], + ({ category }) => category, ); const categories = Array.from(ws2.keys()); return `<tr><th rowspan="${categories.length}">${"⭐".repeat(rarity)}</th> diff --git a/tsconfig.json b/tsconfig.json index 0c1cc59..52d5add 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "lib": [ "DOM", - "ES2023" + "ESNext" ], "module": "ES2020", "moduleResolution": "node",