diff --git a/.github/workflows/shared-component-storybook-publish.yaml b/.github/workflows/shared-component-storybook-publish.yaml new file mode 100644 index 0000000000..620f7a48e8 --- /dev/null +++ b/.github/workflows/shared-component-storybook-publish.yaml @@ -0,0 +1,41 @@ +name: Publish shared component storybook +on: + workflow_dispatch: {} + push: + branches: + - "develop" + paths: + - "packages/shared-components/**/*" + +permissions: {} + +jobs: + doc: + name: Publish storybook + runs-on: ubuntu-latest + environment: SharedComponents + steps: + - name: 🧮 Checkout code + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 + + - name: 🔧 Yarn cache + uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6 + with: + cache: "yarn" + node-version-file: package.json + + - name: 🔨 Install dependencies + working-directory: packages/shared-components + run: "yarn install --pure-lockfile" + + - name: 📖 Build Storybook + working-directory: packages/shared-components + run: yarn build:storybook + + - name: 🚀 Deploy to Cloudflare Pages + uses: cloudflare/wrangler-action@9681c2997648301493e78cacbfb790a9f19c833f # v3 + with: + apiToken: ${{ secrets.CF_PAGES_TOKEN }} + accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }} + workingDirectory: "packages/shared-components" + command: pages deploy storybook-static --project-name=shared-components-storybook diff --git a/packages/shared-components/.gitignore b/packages/shared-components/.gitignore index b1f29b1f0f..1ec1623885 100644 --- a/packages/shared-components/.gitignore +++ b/packages/shared-components/.gitignore @@ -8,3 +8,5 @@ # Ignore coverage report /coverage/ +# Ignore generated docs +typedoc diff --git a/packages/shared-components/README.md b/packages/shared-components/README.md index 113135f9ca..ccb287df09 100644 --- a/packages/shared-components/README.md +++ b/packages/shared-components/README.md @@ -255,6 +255,53 @@ export default { The Figma design will appear in the "Design" tab in Storybook. +#### Non-UI Utility Stories + +For utility functions, helpers, and other non-UI exports, create documentation stories using TSX format with TypeDoc-generated markdown. + +`src/utils/humanize.stories.tsx` + +```tsx +import React from "react"; +import { Markdown } from "@storybook/addon-docs/blocks"; + +import type { Meta } from "@storybook/react-vite"; +import humanizeTimeDoc from "../../typedoc/functions/humanizeTime.md?raw"; + +const meta = { + title: "utils/humanize", + parameters: { + docs: { + page: () => ( + <> +

humanize

+ {humanizeTimeDoc} + + ), + }, + }, + tags: ["autodocs", "skip-test"], +} satisfies Meta; + +export default meta; + +// Docs-only story - renders nothing but triggers autodocs +export const Docs = { + render: () => null, +}; +``` + +> [!NOTE] +> Be sure to include the `skip-test` tag in your utility stories to prevent them from running as visual tests. + +**Workflow:** + +1. Write TsDoc in your utility function +2. Export the function from `src/index.ts` +3. Run `yarn build:doc` to generate TypeDoc markdown +4. Create a `.stories.tsx` file importing the generated markdown +5. The documentation appears automatically in Storybook + ### Tests Two types of tests are available: unit tests and visual regression tests. @@ -288,7 +335,7 @@ Screenshots are located in `packages/shared-components/__vis__/`. ### Translations -First see our [translation guide](../../docs/translation.md) and [translation dev guide](../../docs/translation-dev.md). +First see our [translation guide](../../docs/translating.md) and [translation dev guide](../../docs/translating-dev.md). To generate translation strings for this package, run: ```bash diff --git a/packages/shared-components/package.json b/packages/shared-components/package.json index 5746ad270f..e214bd63ff 100644 --- a/packages/shared-components/package.json +++ b/packages/shared-components/package.json @@ -1,6 +1,6 @@ { "name": "@element-hq/web-shared-components", - "version": "0.0.1", + "version": "0.0.2", "description": "Shared components for Element", "author": "New Vector Ltd.", "repository": { @@ -39,11 +39,12 @@ "i18n:sort": "matrix-sort-i18n src/i18n/strings/en_EN.json", "i18n:lint": "matrix-i18n-lint && prettier --log-level=silent --write src/i18n/strings/ --ignore-path /dev/null", "test:unit": "vitest --project=unit", - "test:storybook": "vitest --project=storybook", + "test:storybook": "yarn build:doc && vitest --project=storybook", "test:storybook:update": "playwright-screenshots --entrypoint /work/scripts/storybook-screenshot-update.sh --with-node-modules", "prepare": "vite build", "storybook": "storybook dev -p 6007", - "build-storybook": "storybook build", + "build:storybook": "pnpm build:doc && storybook build && node scripts/storybook-build-i18n.ts", + "build:doc": "typedoc", "lint": "pnpm lint:types && pnpm lint:js", "lint:js": "eslint --max-warnings 0 src && prettier --check .", "lint:types": "tsc --noEmit && tsc --noEmit -p tsconfig.node.json" @@ -103,6 +104,9 @@ "prettier": "^3.6.2", "storybook": "^10.0.7", "storybook-addon-vis": "^3.1.2", + "typedoc": "^0.28.16", + "typedoc-plugin-markdown": "^4.9.0", + "typedoc-plugin-missing-exports": "^4.1.2", "typescript": "^5.9.3", "vite": "^7.3.1", "vite-plugin-dts": "^4.5.4", diff --git a/packages/shared-components/scripts/storybook-build-i18n.ts b/packages/shared-components/scripts/storybook-build-i18n.ts new file mode 100644 index 0000000000..e0f6dbfb38 --- /dev/null +++ b/packages/shared-components/scripts/storybook-build-i18n.ts @@ -0,0 +1,85 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +/** + * Script to generate i18n files for Storybook build. + */ + +import * as fs from "node:fs"; +import { createHash } from "node:crypto"; + +// Base path for i18n strings +const I18N_BASE_PATH = "./src/i18n/strings/"; +// Destination path for generated i18n files +const I18N_DEST = "storybook-static/i18n/"; + +// List of languages to include +const INCLUDE_LANGS = [...new Set([...fs.readdirSync(I18N_BASE_PATH)])] + .filter((fn) => fn.endsWith(".json")) + .map((f) => f.slice(0, -5)); + +// Check if dist exists +if (!fs.existsSync("dist")) { + fs.mkdirSync("dist"); +} +// Check if i18n exists +if (!fs.existsSync(I18N_DEST)) { + fs.mkdirSync(I18N_DEST); +} + +// Type mapping language codes to filenames +type LangFileMap = Record; + +/** + * Prepare language files by creating hashed filenames and writing them to the destination. + * @returns Mapping of language codes to filenames + */ +function prepareLangFiles(): LangFileMap { + return INCLUDE_LANGS.reduce>((fileMap, lang) => { + const [filename, json] = createHashFromFile(lang); + fs.writeFileSync(`${I18N_DEST}${filename}`, json); + fileMap[lang] = filename; + return fileMap; + }, {}); +} + +/** + * Create a hash from the contents of the language file. + * @param lang - Language code + * @returns Tuple of filename and JSON content + */ +function createHashFromFile(lang: string): [filename: string, json: string] { + const translationsPath = `${I18N_BASE_PATH}${lang}.json`; + + const json = JSON.stringify(fs.readFileSync(translationsPath).toString(), null, 4); + const jsonBuffer = Buffer.from(json); + const digest = createHash("sha256").update(jsonBuffer).digest("hex").slice(0, 7); + const filename = `${lang}.${digest}.json`; + + return [filename, json]; +} + +/** + * Generate the languages.json file mapping language codes to filenames. + * @param langFileMap + */ +function genLangList(langFileMap: LangFileMap): void { + const languages: Record = {}; + INCLUDE_LANGS.forEach(function (lang) { + const normalizedLanguage = lang.toLowerCase().replace("_", "-"); + const languageParts = normalizedLanguage.split("-"); + if (languageParts.length == 2 && languageParts[0] == languageParts[1]) { + languages[languageParts[0]] = langFileMap[lang]; + } else { + languages[normalizedLanguage] = langFileMap[lang]; + } + }); + fs.writeFileSync(`${I18N_DEST}/languages.json`, JSON.stringify(languages, null, 4)); +} + +const langFileMap = prepareLangFiles(); +genLangList(langFileMap); diff --git a/packages/shared-components/src/@types/global.d.ts b/packages/shared-components/src/@types/global.d.ts index 1334c41737..5e8049628c 100644 --- a/packages/shared-components/src/@types/global.d.ts +++ b/packages/shared-components/src/@types/global.d.ts @@ -6,3 +6,9 @@ Please see LICENSE files in the repository root for full details. */ declare module "*.css"; + +// For importing markdown files into storybook stories +declare module "*.md?raw" { + const content: string; + export default content; +} diff --git a/packages/shared-components/src/utils/FormattingUtils.stories.tsx b/packages/shared-components/src/utils/FormattingUtils.stories.tsx new file mode 100644 index 0000000000..e3bd0040e3 --- /dev/null +++ b/packages/shared-components/src/utils/FormattingUtils.stories.tsx @@ -0,0 +1,43 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import React from "react"; +import { Markdown } from "@storybook/addon-docs/blocks"; + +import type { Meta } from "@storybook/react-vite"; +import formatBytesDoc from "../../typedoc/functions/formatBytes.md?raw"; +import formatSecondsDoc from "../../typedoc/functions/formatSeconds.md?raw"; + +const meta = { + title: "utils/FormattingUtils", + parameters: { + docs: { + page: () => ( + <> +

Formatting Utilities

+

A collection of utility functions for formatting data into human-readable strings.

+ +
+

formatBytes

+ {formatBytesDoc} + +
+

formatSeconds

+ {formatSecondsDoc} + + ), + }, + }, + tags: ["autodocs", "skip-test"], +} satisfies Meta; + +export default meta; + +// Docs-only story - renders nothing but triggers autodocs +export const Docs = { + render: () => null, +}; diff --git a/packages/shared-components/src/utils/humanize.stories.tsx b/packages/shared-components/src/utils/humanize.stories.tsx new file mode 100644 index 0000000000..6d5ba65440 --- /dev/null +++ b/packages/shared-components/src/utils/humanize.stories.tsx @@ -0,0 +1,34 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import React from "react"; +import { Markdown } from "@storybook/addon-docs/blocks"; + +import type { Meta } from "@storybook/react-vite"; +import humanizeTimeDoc from "../../typedoc/functions/humanizeTime.md?raw"; + +const meta = { + title: "utils/humanize", + parameters: { + docs: { + page: () => ( + <> +

humanize

+ {humanizeTimeDoc} + + ), + }, + }, + tags: ["autodocs", "skip-test"], +} satisfies Meta; + +export default meta; + +// Docs-only story - renders nothing but triggers autodocs +export const Docs = { + render: () => null, +}; diff --git a/packages/shared-components/src/utils/numbers.stories.tsx b/packages/shared-components/src/utils/numbers.stories.tsx new file mode 100644 index 0000000000..638f8fe4ed --- /dev/null +++ b/packages/shared-components/src/utils/numbers.stories.tsx @@ -0,0 +1,61 @@ +/* + * Copyright 2026 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import React from "react"; +import { Markdown } from "@storybook/addon-docs/blocks"; + +import type { Meta } from "@storybook/react-vite"; +import clampDoc from "../../typedoc/functions/clamp.md?raw"; +import defaultNumberDoc from "../../typedoc/functions/defaultNumber.md?raw"; +import percentageOfDoc from "../../typedoc/functions/percentageOf.md?raw"; +import percentageWithinDoc from "../../typedoc/functions/percentageWithin.md?raw"; +import sumDoc from "../../typedoc/functions/sum.md?raw"; + +const meta = { + title: "utils/numbers", + parameters: { + docs: { + page: () => ( + <> +

Number Utilities

+

+ A collection of utility functions for working with numbers, including validation, clamping, and + percentage calculations. +

+ +
+

defaultNumber

+ {defaultNumberDoc} + +
+

clamp

+ {clampDoc} + +
+

sum

+ {sumDoc} + +
+

percentageWithin

+ {percentageWithinDoc} + +
+

percentageOf

+ {percentageOfDoc} + + ), + }, + }, + tags: ["autodocs", "skip-test"], +} satisfies Meta; + +export default meta; + +// Docs-only story - renders nothing but triggers autodocs +export const Docs = { + render: () => null, +}; diff --git a/packages/shared-components/typedoc.json b/packages/shared-components/typedoc.json new file mode 100644 index 0000000000..2f4402584a --- /dev/null +++ b/packages/shared-components/typedoc.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": ["src/index.ts"], + "plugin": ["typedoc-plugin-markdown", "typedoc-plugin-missing-exports"], + "out": "typedoc", + "hidePageHeader": true, + "hidePageTitle": true, + "hideBreadcrumbs": true, + "useCodeBlocks": true, + "parametersFormat": "table", + "propertiesFormat": "table", + "enumMembersFormat": "table", + "typeDeclarationFormat": "table", + "indexFormat": "table", + "publicPath": "https://github.com/element-hq/element-web/blob/develop/packages/shared-components/", + "sourceLinkTemplate": "https://github.com/element-hq/element-web/blob/develop/{path}#L{line}", + "name": "@element-hq/web-shared-components", + "categorizeByGroup": true, + "externalSymbolLinkMappings": { + "@types/react": { + "*": "https://react.dev/" + }, + "react-virtuoso": { + "*": "https://virtuoso.dev/" + } + } +} diff --git a/packages/shared-components/vitest.config.ts b/packages/shared-components/vitest.config.ts index 975ced5ae3..23cc026304 100644 --- a/packages/shared-components/vitest.config.ts +++ b/packages/shared-components/vitest.config.ts @@ -94,6 +94,9 @@ export default defineConfig({ storybookTest({ configDir: path.join(dirname, ".storybook"), storybookScript: "storybook --ci", + tags: { + exclude: ["skip-test"], + }, }), storybookVis({ // 3px of difference allowed before marking as failed diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 37b02fe0bd..cd4c3723c2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -837,6 +837,15 @@ importers: storybook-addon-vis: specifier: ^3.1.2 version: 3.1.2(@storybook/addon-vitest@10.2.5(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.0.18(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(yaml@2.8.2))(vitest@4.0.18))(@vitest/runner@4.0.18)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.5(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vitest@4.0.18))(@vitest/browser-playwright@4.0.18)(@vitest/browser@4.0.18(vite@7.3.1(@types/node@22.19.8)(jiti@2.6.1)(sugarss@5.0.1(postcss@8.5.6))(terser@5.46.0)(yaml@2.8.2))(vitest@4.0.18))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.5(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(vitest@4.0.18) + typedoc: + specifier: ^0.28.16 + version: 0.28.16(typescript@5.9.3) + typedoc-plugin-markdown: + specifier: ^4.9.0 + version: 4.9.0(typedoc@0.28.16(typescript@5.9.3)) + typedoc-plugin-missing-exports: + specifier: ^4.1.2 + version: 4.1.2(typedoc@0.28.16(typescript@5.9.3)) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -2209,6 +2218,9 @@ packages: '@formatjs/intl-segmenter@12.1.1': resolution: {integrity: sha512-/ufC6NrGKDHrjWXLhkSu852K/ZHgMXm4H37xOqiB5qWrjOSu0gXyiyUSJkc5HExmNW/28qDTvh4gUb79ZQ3fbA==} + '@gerrit0/mini-shiki@3.22.0': + resolution: {integrity: sha512-jMpciqEVUBKE1QwU64S4saNMzpsSza6diNCk4MWAeCxO2+LFi2FIFmL2S0VDLzEJCxuvCbU783xi8Hp/gkM5CQ==} + '@grpc/grpc-js@1.14.3': resolution: {integrity: sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==} engines: {node: '>=12.10.0'} @@ -3556,6 +3568,21 @@ packages: peerDependencies: webpack: '>=4.40.0' + '@shikijs/engine-oniguruma@3.22.0': + resolution: {integrity: sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA==} + + '@shikijs/langs@3.22.0': + resolution: {integrity: sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA==} + + '@shikijs/themes@3.22.0': + resolution: {integrity: sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g==} + + '@shikijs/types@3.22.0': + resolution: {integrity: sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@sinclair/typebox@0.34.48': resolution: {integrity: sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==} @@ -3893,6 +3920,9 @@ packages: '@types/glob-to-regexp@0.4.4': resolution: {integrity: sha512-nDKoaKJYbnn1MZxUY0cA1bPmmgZbg0cTq7Rh13d0KWYNOiKbqoR+2d89SnRPszGh7ROzSwZ/GOjZ4jPbmmZ6Eg==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/hoist-non-react-statics@3.3.7': resolution: {integrity: sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==} peerDependencies: @@ -4055,6 +4085,9 @@ packages: '@types/ua-parser-js@0.7.39': resolution: {integrity: sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} @@ -7241,6 +7274,9 @@ packages: linkify-it@4.0.1: resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + linkify-react@4.3.2: resolution: {integrity: sha512-mi744h1hf+WDsr+paJgSBBgYNLMWNSHyM9V9LVUo03RidNGdw1VpI7Twnt+K3pEh3nIzB4xiiAgZxpd61ItKpQ==} peerDependencies: @@ -7343,6 +7379,9 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -7376,6 +7415,10 @@ packages: resolution: {integrity: sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==} hasBin: true + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -7420,6 +7463,9 @@ packages: mdurl@1.0.1: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -8455,6 +8501,10 @@ packages: pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} @@ -9601,6 +9651,24 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} + typedoc-plugin-markdown@4.9.0: + resolution: {integrity: sha512-9Uu4WR9L7ZBgAl60N/h+jqmPxxvnC9nQAlnnO/OujtG2ubjnKTVUFY1XDhcMY+pCqlX3N2HsQM2QTYZIU9tJuw==} + engines: {node: '>= 18'} + peerDependencies: + typedoc: 0.28.x + + typedoc-plugin-missing-exports@4.1.2: + resolution: {integrity: sha512-WNoeWX9+8X3E3riuYPduilUTFefl1K+Z+5bmYqNeH5qcWjtnTRMbRzGdEQ4XXn1WEO4WCIlU0vf46Ca2y/mspg==} + peerDependencies: + typedoc: ^0.28.1 + + typedoc@0.28.16: + resolution: {integrity: sha512-x4xW77QC3i5DUFMBp0qjukOTnr/sSg+oEs86nB3LjDslvAmwe/PUGDWbe3GrIqt59oTqoXK5GRK9tAa0sYMiog==} + engines: {node: '>= 18', pnpm: '>= 10'} + hasBin: true + peerDependencies: + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x + typescript@5.8.2: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} @@ -9618,6 +9686,9 @@ packages: uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} @@ -11673,6 +11744,14 @@ snapshots: '@formatjs/intl-localematcher': 0.8.1 tslib: 2.8.1 + '@gerrit0/mini-shiki@3.22.0': + dependencies: + '@shikijs/engine-oniguruma': 3.22.0 + '@shikijs/langs': 3.22.0 + '@shikijs/themes': 3.22.0 + '@shikijs/types': 3.22.0 + '@shikijs/vscode-textmate': 10.0.2 + '@grpc/grpc-js@1.14.3': dependencies: '@grpc/proto-loader': 0.8.0 @@ -13094,6 +13173,26 @@ snapshots: - encoding - supports-color + '@shikijs/engine-oniguruma@3.22.0': + dependencies: + '@shikijs/types': 3.22.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.22.0': + dependencies: + '@shikijs/types': 3.22.0 + + '@shikijs/themes@3.22.0': + dependencies: + '@shikijs/types': 3.22.0 + + '@shikijs/types@3.22.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + '@sinclair/typebox@0.34.48': {} '@sindresorhus/merge-streams@4.0.0': {} @@ -13500,6 +13599,10 @@ snapshots: '@types/glob-to-regexp@0.4.4': {} + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/hoist-non-react-statics@3.3.7(@types/react@19.2.10)': dependencies: '@types/react': 19.2.10 @@ -13667,6 +13770,8 @@ snapshots: '@types/ua-parser-js@0.7.39': {} + '@types/unist@3.0.3': {} + '@types/ws@8.18.1': dependencies: '@types/node': 22.19.8 @@ -17478,6 +17583,10 @@ snapshots: dependencies: uc.micro: 1.0.6 + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + linkify-react@4.3.2(linkifyjs@4.3.2)(react@19.2.4): dependencies: linkifyjs: 4.3.2 @@ -17580,6 +17689,8 @@ snapshots: dependencies: yallist: 4.0.0 + lunr@2.3.9: {} + lz-string@1.5.0: {} magic-string@0.30.21: @@ -17647,6 +17758,15 @@ snapshots: mdurl: 1.0.1 uc.micro: 1.0.6 + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + math-intrinsics@1.1.0: {} mathml-tag-names@4.0.0: {} @@ -17703,6 +17823,8 @@ snapshots: mdurl@1.0.1: {} + mdurl@2.0.0: {} + media-typer@0.3.0: {} media-typer@1.1.0: {} @@ -18815,6 +18937,8 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 + punycode.js@2.3.1: {} + punycode@1.4.1: {} punycode@2.3.1: {} @@ -20240,6 +20364,23 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 + typedoc-plugin-markdown@4.9.0(typedoc@0.28.16(typescript@5.9.3)): + dependencies: + typedoc: 0.28.16(typescript@5.9.3) + + typedoc-plugin-missing-exports@4.1.2(typedoc@0.28.16(typescript@5.9.3)): + dependencies: + typedoc: 0.28.16(typescript@5.9.3) + + typedoc@0.28.16(typescript@5.9.3): + dependencies: + '@gerrit0/mini-shiki': 3.22.0 + lunr: 2.3.9 + markdown-it: 14.1.0 + minimatch: 9.0.5 + typescript: 5.9.3 + yaml: 2.8.2 + typescript@5.8.2: {} typescript@5.9.3: {} @@ -20248,6 +20389,8 @@ snapshots: uc.micro@1.0.6: {} + uc.micro@2.1.0: {} + ufo@1.6.3: {} unbox-primitive@1.1.0: