From 784a8cfa233c0bfd5ca4b42c634da273db5e684b Mon Sep 17 00:00:00 2001 From: Yann Prono Date: Mon, 1 Dec 2025 20:55:09 +0100 Subject: [PATCH] docs: documentation website --- .github/workflows/build.yml | 10 + .github/workflows/documentation.yml | 53 + .gitignore | 3 + README.md | 12 +- docs/.vitepress/config.mts | 62 + docs/.vitepress/theme/custom.css | 17 + docs/.vitepress/theme/index.ts | 4 + docs/configuration/README.md | 8 - docs/configuration/index.md | 50 + docs/getting-started/index.md | 96 ++ docs/index.md | 36 + docs/json-schemas/index.md | 12 + docs/keybindings/README.md | 78 -- docs/keybindings/index.md | 43 + docs/name/{README.md => index.md} | 0 docs/package-lock.json | 1294 +++++++++++++++++++ docs/package.json | 82 ++ docs/public/dd.svg | 236 ++++ docs/{assets => public}/demo-dark.gif | Bin docs/{assets => public}/demo-light.gif | Bin docs/{assets => public}/help.png | Bin docs/{assets => public}/logo.svg | 0 docs/public/maif.svg | 1 + docs/{assets => public}/record.png | Bin docs/{assets => public}/records.png | Bin docs/{assets => public}/topics.png | Bin docs/query-language/{README.md => index.md} | 2 +- docs/release/{README.md => index.md} | 0 docs/schema-registry/README.md | 78 -- docs/schema-registry/index.md | 56 + docs/search-filter/{README.md => index.md} | 13 +- docs/themes/{README.md => index.md} | 20 +- docs/tls/{README.md => index.md} | 16 +- docs/url-templates/{README.md => index.md} | 4 +- docs/what-is-yozefu/index.md | 46 + typos.toml | 2 + 36 files changed, 2134 insertions(+), 200 deletions(-) create mode 100644 .github/workflows/documentation.yml create mode 100644 docs/.vitepress/config.mts create mode 100644 docs/.vitepress/theme/custom.css create mode 100644 docs/.vitepress/theme/index.ts delete mode 100644 docs/configuration/README.md create mode 100644 docs/configuration/index.md create mode 100644 docs/getting-started/index.md create mode 100644 docs/index.md create mode 100644 docs/json-schemas/index.md delete mode 100644 docs/keybindings/README.md create mode 100644 docs/keybindings/index.md rename docs/name/{README.md => index.md} (100%) create mode 100644 docs/package-lock.json create mode 100644 docs/package.json create mode 100644 docs/public/dd.svg rename docs/{assets => public}/demo-dark.gif (100%) rename docs/{assets => public}/demo-light.gif (100%) rename docs/{assets => public}/help.png (100%) rename docs/{assets => public}/logo.svg (100%) create mode 100644 docs/public/maif.svg rename docs/{assets => public}/record.png (100%) rename docs/{assets => public}/records.png (100%) rename docs/{assets => public}/topics.png (100%) rename docs/query-language/{README.md => index.md} (92%) rename docs/release/{README.md => index.md} (100%) delete mode 100644 docs/schema-registry/README.md create mode 100644 docs/schema-registry/index.md rename docs/search-filter/{README.md => index.md} (88%) rename docs/themes/{README.md => index.md} (78%) rename docs/tls/{README.md => index.md} (84%) rename docs/url-templates/{README.md => index.md} (94%) create mode 100644 docs/what-is-yozefu/index.md diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7bdab370..439c3273 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -239,6 +239,16 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Build documentation run: cargo doc --no-deps --document-private-items --verbose + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: 24 + cache-dependency-path: docs/package-lock.json + cache: npm + - name: Install dependencies + run: npm install --prefix docs + - name: Build with VitePress + run: npm run build --prefix docs lychee: name: Lychee diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 00000000..cc2d1ad2 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,53 @@ +name: Deploy VitePress site to Pages + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: 24 + cache: npm + cache-dependency-path: docs/package-lock.json + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: npm ci --prefix docs + - name: Build with VitePress + run: npm run build --prefix docs + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: docs/docs/.vitepress/dist + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 4a22d13c..4d39a624 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ docs/schemas/kafka.properties .jj mutants.out mutants.out.old +docs/.vitepress/dist +docs/.vitepress/cache +docs/node_modules \ No newline at end of file diff --git a/README.md b/README.md index 7af54d30..b18e2df9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

- -  Pixel art portrait of a serious-faced person in grayscale above the text 'Yozefu' + +  Pixel art portrait of a serious-faced person in grayscale above the text 'Yozefu'

@@ -123,18 +123,18 @@ yozf -c localhost
-  A TUI displays a list of topics on the left, a search bar below, and records with timestamps and values in a table on the right. +  A TUI displays a list of topics on the left, a search bar below, and records with timestamps and values in a table on the right. - A TUI listing the consumed kafka records with their timestamps, their partition, their offset and an excerpt of the key and the value. + A TUI listing the consumed kafka records with their timestamps, their partition, their offset and an excerpt of the key and the value.
- View of a selected kafka records + View of a selected kafka records - View of the help page + View of the help page
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts new file mode 100644 index 00000000..88b5eb91 --- /dev/null +++ b/docs/.vitepress/config.mts @@ -0,0 +1,62 @@ +import { defineConfig } from 'vitepress' + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + + title: "Yōzefu", + description: "Interactive TUI to explore Kafka clusters and data", + + themeConfig: { + search: { + provider: 'local' + }, + nav: [ + { text: 'Documentation', link: '/getting-started/' }, + { text: 'docs.rs', link: 'https://docs.rs/crate/yozefu/latest' }, + { text: 'crates.io', link: 'https://crates.io/crates/yozefu' } + ], + footer: { + message: ` +
OSS by MAIF, released under Apache License, Version 2.0

`, + }, + sidebar: [ + { + text: 'Introduction', + items: [ + { text: 'What is Yōzefu?', link: '/what-is-yozefu/' }, + { text: 'Getting Started', link: '/getting-started/' }, + { text: 'Keybindings', link: '/keybindings/' }, + + ] + }, + { + text: 'Configuration', + items: [ + { text: 'General', link: '/configuration/' }, + { text: 'TLS', link: '/tls/' }, + { text: 'Schema Registry', link: '/schema-registry/' }, + { text: 'Themes', link: '/themes/' }, + { text: 'URL Templates', link: '/url-templates/' }, + ] + }, + { + text: 'Search', + items: [ + + { text: 'Creating a search filter', link: '/search-filter/' }, + { text: 'Examples', link: '/query-language/' }, + ] + }, + { + text: 'Internals', + items: [ + { text: 'JSON schemas', link: '/json-schemas/' }, + ] + }, + ], + + socialLinks: [ + { icon: 'github', link: 'https://github.com/MAIF/yozefu' } + ] + } +}) diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css new file mode 100644 index 00000000..744f8a11 --- /dev/null +++ b/docs/.vitepress/theme/custom.css @@ -0,0 +1,17 @@ +html.dark .light-only { + display: none !important; +} + +html:not(.dark) .dark-only { + display: none !important; +} + +.gif { + border-radius: 12px; +} + + +.footer-maif { + height: 2rem; + margin: 0 auto; +} \ No newline at end of file diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 00000000..508d8b4a --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,4 @@ +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default DefaultTheme \ No newline at end of file diff --git a/docs/configuration/README.md b/docs/configuration/README.md deleted file mode 100644 index 74947722..00000000 --- a/docs/configuration/README.md +++ /dev/null @@ -1,8 +0,0 @@ -Work in progress - -| | Default behavior | CLI option | Environment variable | Configuration file | -| ------------------------- | --------------------------------- | --------------: | -------------------: | ---------------------------: | -| Workspace (or config dir) | `~/.config/io.maif.yozefu/` | `--config-dir` | `YOZEFU_CONFIG_DIR` | No | -| Configuration file | `${workspace}/config.json` | `--config-file` | N/A | No | -| Log file | `${workspace}/application.log` | `--log-file` | `YOZEFU_LOG_FILE` | jsonpath `/log_file` | -| Export directory | `$PWD/export-{datetime-now}.json` | `--output` | No | jsonpath `/export_directory` | diff --git a/docs/configuration/index.md b/docs/configuration/index.md new file mode 100644 index 00000000..3fd6f396 --- /dev/null +++ b/docs/configuration/index.md @@ -0,0 +1,50 @@ +# Configuration + +Yōzefu uses a workspace directory to store its configuration file, logs, and other data. By default, this directory is located at `yozf config get dir`. You can change the workspace directory using the `--config-dir` command-line option or the `YOZEFU_CONFIG_DIR` environment variable. + + + +| | Default | CLI option | Env variable | Configuration file | +| ------------- | --------------------------------- | --------------: | ------------------: | ------------------: | +| Workspace | `~/.config/io.maif.yozefu/` | `--config-dir` | `YOZEFU_CONFIG_DIR` | No | +| Configuration | `${workspace}/config.json` | `--config-file` | N/A | No | +| Logs | `${workspace}/application.log` | `--log-file` | `YOZEFU_LOG_FILE` | `/log_file` | +| Export folder | `$PWD/export-{datetime-now}.json` | `--output` | No | `/export_directory` | + + + + +## `config.json` file + + +Yōzefu uses a JSON configuration file to set various options. By default, it looks for a file named `config.json` in the workspace directory. + + +| Key | Type | Examples | +| ---------------------------------------------------------------------------------------- | --------------------- | ------------------------------------------------------- | +| `default_url_template`
Placeholder URL to open a Kafka record in the browser. | String | `http://localhost/cluster/{topic}/{partition}/{offset}` | +| `initial_query`
Initial search query when starting the UI. | String | `from end - 10` | +| `theme`
TUI theme. | String | `light` | +| `highlighter_theme`
Theme for syntax highlighting. | String | `InspiredGitHub` | +| `clusters`
Kafka properties per cluster. | Object | — | +| `consumer`
Default configuration for the Kafka consumer. | Object | `{ buffer_capacity: 1000, timeout_in_ms: 10 }` | +| `default_kafka_config`
Default Kafka properties inherited by every cluster. | Map\ | `{"fetch.min.bytes": "10000"}` | +| `history`
Past search queries. | Array\ | `["from end - 10"]` | +| `show_shortcuts`
Whether to show shortcuts. | Boolean | `true` | +| `export_directory`
Directory for exports. | String | `./yozefu-exports` | +| `log_file`
File path to write logs. | String | `/path/to/log/file.log` | +| `timestamp_format`
Display timestamps as date-time or relative. | `DateTime` or `Ago` | `DateTime` | + + +## Kafka cluster + + +| Key | Type | Examples | +| ------------------------------------------------------------------------------- | --------------------- | ------------------------------------------------- | +| `url_template`
Placeholder URL to open a Kafka record in the browser. | String | `http://dev/cluster/{topic}/{partition}/{offset}` | +| `schema_registry`
Schema registry settings for this cluster. | Object | `{}` | +| `kafka`
Kafka consumer properties for this cluster | Map\ | `{}` | +| `consumer`
configuration for the Yozefu consumer. | Object | `{ buffer_capacity: 10, timeout_in_ms: 1 }` | + + +For more details, see the [configuration json schema](../json-schemas/). \ No newline at end of file diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md new file mode 100644 index 00000000..3f32798f --- /dev/null +++ b/docs/getting-started/index.md @@ -0,0 +1,96 @@ +# Getting started + + +Give Yōzefu a try in your terminal with the following command: + +```shell +# It clones this repository, starts a docker kafka node and produces json records +curl -L "https://raw.githubusercontent.com/MAIF/yozefu/refs/heads/main/docs/try-it.sh" | bash +yozf -c localhost +``` + + +## Install + + +### Prerequisites + + + +::: code-group + +```sh [cargo] +RUSTFLAGS="--cfg tokio_unstable" cargo install --locked yozefu +``` + +```sh [git] +git clone git@github.com:MAIF/yozefu.git +cargo run -- --localhost +``` + +```sh [brew] +brew install yozefu + +``` + +```sh [yay] +yay -S yozefu +``` + +```sh [nix] +nix run github:MAIF/yozefu +``` +::: + + +### Configuration + +Once installed, you can configure Yōzefu to connect to your Kafka clusters. + + +::: tip NOTE + +Yōzefu has a default cluster named `localhost` pointing to `localhost:9092`. You can use it to quickly try Yōzefu with a local Kafka instance. + +::: + +```shell +# Path of the configuration file +yozf config get path + +# Open the configuration file with your favorite editor +yozf configure --editor 'vim' +``` + +And then add your cluster configuration. Here is an example for a Aiven cluster: +```json{8-18} +{ + "default_url_template": "...", + "initial_query": "from end - 10", + "clusters": { + "localhost": { + ... + }, + "production": { + "url_template": "https://console.aiven.io//topics/{topic}/messages?offset={offset}&partition={partition}&format=json", + "kafka": { + "bootstrap.servers": "kafka.aivencloud.com:24624", + "security.protocol": "sasl_ssl", + "sasl.mechanism": "SCRAM-SHA-256", + "sasl.username": "user", + "sasl.password": "password", + "ssl.ca.location": "~/path/to/ca.pem" + } + } + } +} +``` + +## Run it + +Once configured, you can start using Yōzefu to query your Kafka topics. + +```shell +# Connect to the 'production' cluster +yozf --cluster production +``` \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..35495102 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,36 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "Yōzefu," + text: "A TUI to explore Kafka clusters" + image: + src: /dd.svg + alt: Yozefu + + actions: + - theme: brand + text: Getting started + link: /getting-started/ + +features: + - icon: 🔌 + title: Real-time + Multi-topic + details: Live access to records and search across multiple topics. + - icon: 🔎 + title: Powerful Querying + details: SQL-inspired query language with fine-grained filters, extensible via WebAssembly. + link: /query-language/ + - icon: 🖥️ + title: Dual Modes + details: Use as interactive TUI or CLI with the `--headless` flag. + link: /what-is-yozefu/#a-tui-and-cli + - icon: 📤 + title: One-key Export + details: Quickly export Kafka records for deeper analysis. +--- + + +![The user selects a topic and sees and real time new records published to Kafka.](https://vhs.charm.sh/vhs-UpIJD2h92vKkj01XSS0r0.gif){.dark-only .gif} +![The user selects a topic and sees and real time new records published to Kafka.](https://vhs.charm.sh/vhs-1oh0ovd0DaUfvKLTx4iZTo.gif){.light-only .gif} \ No newline at end of file diff --git a/docs/json-schemas/index.md b/docs/json-schemas/index.md new file mode 100644 index 00000000..9490af31 --- /dev/null +++ b/docs/json-schemas/index.md @@ -0,0 +1,12 @@ +# JSON schemas + + +these json schemas are for documentation purpose and give an overview of the data structures used by Yozefu. + +| Name | Rust definition | Schema definition | +| --------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | +| Kafka record | [kafka_record.rs](https://github.com/MAIF/yozefu/blob/main/crates/lib/src/kafka/kafka_record.rs) | [kafka-record.json](https://github.com/MAIF/yozefu/blob/main/docs/json-schemas/kafka-record.json) | +| Exported kafka record | [exported_kafka_record.rs](https://github.com/MAIF/yozefu/blob/main/crates/lib/src/kafka/exported_kafka_record.rs) | [exported-kafka-record.json](https://github.com/MAIF/yozefu/blob/main/docs/json-schemas/exported-kafka-record.json) | +| Input filter | [mod.rs](https://github.com/MAIF/yozefu/blob/main/crates/lib/src/search/mod.rs) | [filter-input.json](https://github.com/MAIF/yozefu/blob/main/docs/json-schemas/filter-input.json) | +| Result filter | [mod.rs](https://github.com/MAIF/yozefu/blob/main/crates//lib/src/search/mod.rs) | [filter-result.json](https://github.com/MAIF/yozefu/blob/main/docs/json-schemas/filter-result.json) | +| Configuration | [global_config.rs](https://github.com/MAIF/yozefu/blob/main/crates/app/src/configuration/global_config.rs) | [global-config.json](https://github.com/MAIF/yozefu/blob/main/docs/json-schemas/global-config.json) | \ No newline at end of file diff --git a/docs/keybindings/README.md b/docs/keybindings/README.md deleted file mode 100644 index 9709ff3a..00000000 --- a/docs/keybindings/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Keybindings. - - -So far, keybindings are hardcoded. -The choices I made are completely personal. I use a qwerty Apple keyboard for your information. - -**General** -| Keybinding | Description | -| --------------------------------- | :------------------------------------- | -| Tab | Next panel | -| Shift + Tab | previous panel | -| / | Go to search bar | -| Escape | Close the last visible dialog | -| Ctrl + H | Show/Hide help | -| Ctrl + O | Show/Hide topics | -| [ | Scroll to top | -| ] | Scroll to bottom | -| K | Move to upward direction by one line | -| J | Move to downward direction by one line | - - -
- -**Topics** -| Keybinding | Description | -| ------------------------------ | :------------------ | -| Ctrl + P | Show topic details | -| Ctrl + U | Unselect all topics | -| Enter | Select the topic | - - -
- -**Records list** -| Keybinding | Description | -| ------------------------------ | :--------------------------------------------------------- | -| C | Copy kafka record to clipboard | -| O | Open the kafka record in the web browser | -| E | Export kafka record to the file | -| Ctrl + E | Export all records to the file | -| F | Keep selecting the last consumed kafka record | -| Enter | Open the selected record | -| T | Switch the timestamp format: `Datetime` or `X seconds ago` | -| or | Previous/next record | -| or | Resize the topic and key columns | - - -
- -**Record** - -| Keybinding | Description | -| ---------------------------- | :--------------------------------------- | -| C | Copy to clipboard | -| O | Open the kafka record in the web browser | -| S | Show schemas | -| E | Export kafka record to the file | -| or | Previous/next record | - -
- -**Schemas** - -| Keybinding | Description | -| ---------------------------- | :------------------------ | -| C | Copy schemas to clipboard | -| or | Scroll | - -
- - - -**Search** -| Keybinding | Description | -| ---------------------------- | :------------------- | -| or | Browse history | -| | Accept autocomplete | -| Enter | Search kafka records | diff --git a/docs/keybindings/index.md b/docs/keybindings/index.md new file mode 100644 index 00000000..da00e742 --- /dev/null +++ b/docs/keybindings/index.md @@ -0,0 +1,43 @@ +# Keybindings. + + +So far, keybindings are hardcoded. The choices I made are completely personal. + +| Focused panel | Keybinding | Description | +| :------------ | --------------------------------- | :-------------------------------------------- | +| General | Tab | Next panel | +| | Shift + Tab | previous panel | +| | / | Go to search bar | +| | Escape | Close the last visible dialog | +| | Ctrl + H | Show/Hide help | +| | Ctrl + O | Show/Hide topics | +| | [ | Scroll to top | +| | ] | Scroll to bottom | +| | K | Move to upward direction by one line | +| | J | Move to downward direction by one line | +| | | | +| Topics | Ctrl + P | Show topic details | +| | Ctrl + U | Unselect all topics | +| | Enter | Select the topic | +| | | | +| Records | C | Copy kafka record to clipboard | +| | O | Open the kafka record in the web browser | +| | E | Export kafka record to the file | +| | Ctrl + E | Export all records to the file | +| | F | Keep selecting the last consumed kafka record | +| | Enter | Open the selected record | +| | or | Previous/next record | +| | or | Resize the topic and key columns | +| | | | +| Records | C | Copy to clipboard | +| | O | Open the kafka record in the web browser | +| | S | Show schemas | +| | E | Export kafka record to the file | +| | or | Previous/next record | +| | | | +| Search | or | Browse history | +| | | Accept autocomplete | +| | Enter | Search kafka records | +| | | | +| Schemas | C | Copy schemas to clipboard | +| | or | Scroll | \ No newline at end of file diff --git a/docs/name/README.md b/docs/name/index.md similarity index 100% rename from docs/name/README.md rename to docs/name/index.md diff --git a/docs/package-lock.json b/docs/package-lock.json new file mode 100644 index 00000000..18c39b1a --- /dev/null +++ b/docs/package-lock.json @@ -0,0 +1,1294 @@ +{ + "name": "docs", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "docs", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "birpc": "^2.8.0", + "ccount": "^2.0.1", + "character-entities-html4": "^2.1.0", + "character-entities-legacy": "^3.0.0", + "comma-separated-tokens": "^2.0.3", + "copy-anything": "^4.0.5", + "csstype": "^3.2.3", + "dequal": "^2.0.3", + "devlop": "^1.1.0", + "entities": "^4.5.0", + "esbuild": "^0.25.12", + "estree-walker": "^2.0.2", + "fdir": "^6.5.0", + "focus-trap": "^7.6.6", + "hast-util-to-html": "^9.0.5", + "hast-util-whitespace": "^3.0.0", + "hookable": "^5.5.3", + "htm": "^3.1.1", + "html-void-elements": "^3.0.0", + "is-what": "^5.5.0", + "magic-string": "^0.30.21", + "mark.js": "^8.11.1", + "mdast-util-to-hast": "^13.2.1", + "micromark-util-character": "^2.1.1", + "micromark-util-encode": "^2.0.1", + "micromark-util-sanitize-uri": "^2.0.1", + "micromark-util-symbol": "^2.0.1", + "micromark-util-types": "^2.0.2", + "minisearch": "^7.2.0", + "mitt": "^3.0.1", + "nanoid": "^3.3.11", + "oniguruma-parser": "^0.12.1", + "oniguruma-to-es": "^4.3.4", + "perfect-debounce": "^2.0.0", + "picocolors": "^1.1.1", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "property-information": "^7.1.0", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2", + "regex-utilities": "^2.3.0", + "rfdc": "^1.4.1", + "rollup": "^4.53.3", + "shiki": "^3.17.1", + "source-map-js": "^1.2.1", + "space-separated-tokens": "^2.0.2", + "speakingurl": "^14.0.1", + "stringify-entities": "^4.0.4", + "superjson": "^2.2.6", + "tabbable": "^6.3.0", + "tinyglobby": "^0.2.15", + "trim-lines": "^3.0.1", + "unist-util-is": "^6.0.1", + "unist-util-position": "^5.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3", + "vfile-message": "^4.0.3", + "vite": "^7.2.6", + "vue": "^3.5.25", + "zwitch": "^2.0.4" + }, + "devDependencies": { + "vitepress": "^2.0.0-alpha.15" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@docsearch/css": { + "version": "4.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@docsearch/js": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "htm": "3.1.1" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@iconify-json/simple-icons": { + "version": "1.2.61", + "dev": true, + "license": "CC0-1.0", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "license": "MIT" + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.50", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.3", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@shikijs/core": { + "version": "3.17.1", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.17.1", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "3.17.1", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.17.1", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.4" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.17.1", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.17.1", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.17.1", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.17.1" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.17.1", + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.17.1" + } + }, + "node_modules/@shikijs/transformers": { + "version": "3.17.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.17.1", + "@shikijs/types": "3.17.1" + } + }, + "node_modules/@shikijs/types": { + "version": "3.17.1", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "license": "MIT" + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.21", + "dev": true, + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "license": "ISC" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-beta.50" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.25", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.25", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.25", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.25", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.25", + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.25", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/devtools-api": { + "version": "8.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^8.0.5" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "8.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^8.0.5", + "birpc": "^2.6.1", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^2.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "8.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.25", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.25", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.25", + "@vue/shared": "3.5.25" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.25", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.25", + "@vue/runtime-core": "3.5.25", + "@vue/shared": "3.5.25", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.25", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.25", + "@vue/shared": "3.5.25" + }, + "peerDependencies": { + "vue": "3.5.25" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.25", + "license": "MIT" + }, + "node_modules/@vueuse/core": { + "version": "14.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.21", + "@vueuse/metadata": "14.1.0", + "@vueuse/shared": "14.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/@vueuse/integrations": { + "version": "14.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@vueuse/core": "14.1.0", + "@vueuse/shared": "14.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "async-validator": "^4", + "axios": "^1", + "change-case": "^5", + "drauu": "^0.4", + "focus-trap": "^7", + "fuse.js": "^7", + "idb-keyval": "^6", + "jwt-decode": "^4", + "nprogress": "^0.2", + "qrcode": "^1.5", + "sortablejs": "^1", + "universal-cookie": "^7 || ^8", + "vue": "^3.5.0" + }, + "peerDependenciesMeta": { + "async-validator": { + "optional": true + }, + "axios": { + "optional": true + }, + "change-case": { + "optional": true + }, + "drauu": { + "optional": true + }, + "focus-trap": { + "optional": true + }, + "fuse.js": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "jwt-decode": { + "optional": true + }, + "nprogress": { + "optional": true + }, + "qrcode": { + "optional": true + }, + "sortablejs": { + "optional": true + }, + "universal-cookie": { + "optional": true + } + } + }, + "node_modules/@vueuse/metadata": { + "version": "14.1.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "14.1.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vue": "^3.5.0" + } + }, + "node_modules/birpc": { + "version": "2.8.0", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/copy-anything": { + "version": "4.0.5", + "license": "MIT", + "dependencies": { + "is-what": "^5.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/focus-trap": { + "version": "7.6.6", + "license": "MIT", + "dependencies": { + "tabbable": "^6.3.0" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "license": "MIT" + }, + "node_modules/htm": { + "version": "3.1.1", + "license": "Apache-2.0" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-what": { + "version": "5.5.0", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mark.js": { + "version": "8.11.1", + "license": "MIT" + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/minisearch": { + "version": "7.2.0", + "license": "MIT" + }, + "node_modules/mitt": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/oniguruma-parser": { + "version": "0.12.1", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.4", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.1", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/perfect-debounce": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/regex": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-utilities": { + "version": "2.3.0", + "license": "MIT" + }, + "node_modules/rfdc": { + "version": "1.4.1", + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.53.3", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/shiki": { + "version": "3.17.1", + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.17.1", + "@shikijs/engine-javascript": "3.17.1", + "@shikijs/engine-oniguruma": "3.17.1", + "@shikijs/langs": "3.17.1", + "@shikijs/themes": "3.17.1", + "@shikijs/types": "3.17.1", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/superjson": { + "version": "2.2.6", + "license": "MIT", + "dependencies": { + "copy-anything": "^4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tabbable": { + "version": "6.3.0", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "7.2.6", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitepress": { + "version": "2.0.0-alpha.15", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-2.0.0-alpha.15.tgz", + "integrity": "sha512-jhjSYd10Z6RZiKOa7jy0xMVf5NB5oSc/lS3bD/QoUc6V8PrvQR5JhC9104NEt6+oTGY/ftieVWxY9v7YI+1IjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@docsearch/css": "^4.3.2", + "@docsearch/js": "^4.3.2", + "@iconify-json/simple-icons": "^1.2.59", + "@shikijs/core": "^3.15.0", + "@shikijs/transformers": "^3.15.0", + "@shikijs/types": "^3.15.0", + "@types/markdown-it": "^14.1.2", + "@vitejs/plugin-vue": "^6.0.1", + "@vue/devtools-api": "^8.0.5", + "@vue/shared": "^3.5.24", + "@vueuse/core": "^14.0.0", + "@vueuse/integrations": "^14.0.0", + "focus-trap": "^7.6.6", + "mark.js": "8.11.1", + "minisearch": "^7.2.0", + "shiki": "^3.15.0", + "vite": "^7.2.2", + "vue": "^3.5.24" + }, + "bin": { + "vitepress": "bin/vitepress.js" + }, + "peerDependencies": { + "markdown-it-mathjax3": "^4", + "oxc-minify": "*", + "postcss": "^8" + }, + "peerDependenciesMeta": { + "markdown-it-mathjax3": { + "optional": true + }, + "oxc-minify": { + "optional": true + }, + "postcss": { + "optional": true + } + } + }, + "node_modules/vue": { + "version": "3.5.25", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.25", + "@vue/compiler-sfc": "3.5.25", + "@vue/runtime-dom": "3.5.25", + "@vue/server-renderer": "3.5.25", + "@vue/shared": "3.5.25" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000..4083ba2a --- /dev/null +++ b/docs/package.json @@ -0,0 +1,82 @@ +{ + "name": "docs", + "version": "1.0.0", + "description": "", + "license": "ISC", + "author": "", + "type": "commonjs", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "dev": "vitepress dev", + "build": "vitepress build", + "preview": "vitepress preview" + }, + "dependencies": { + "birpc": "^2.8.0", + "ccount": "^2.0.1", + "character-entities-html4": "^2.1.0", + "character-entities-legacy": "^3.0.0", + "comma-separated-tokens": "^2.0.3", + "copy-anything": "^4.0.5", + "csstype": "^3.2.3", + "dequal": "^2.0.3", + "devlop": "^1.1.0", + "entities": "^4.5.0", + "esbuild": "^0.25.12", + "estree-walker": "^2.0.2", + "fdir": "^6.5.0", + "focus-trap": "^7.6.6", + "hast-util-to-html": "^9.0.5", + "hast-util-whitespace": "^3.0.0", + "hookable": "^5.5.3", + "htm": "^3.1.1", + "html-void-elements": "^3.0.0", + "is-what": "^5.5.0", + "magic-string": "^0.30.21", + "mark.js": "^8.11.1", + "mdast-util-to-hast": "^13.2.1", + "micromark-util-character": "^2.1.1", + "micromark-util-encode": "^2.0.1", + "micromark-util-sanitize-uri": "^2.0.1", + "micromark-util-symbol": "^2.0.1", + "micromark-util-types": "^2.0.2", + "minisearch": "^7.2.0", + "mitt": "^3.0.1", + "nanoid": "^3.3.11", + "oniguruma-parser": "^0.12.1", + "oniguruma-to-es": "^4.3.4", + "perfect-debounce": "^2.0.0", + "picocolors": "^1.1.1", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "property-information": "^7.1.0", + "regex": "^6.0.1", + "regex-recursion": "^6.0.2", + "regex-utilities": "^2.3.0", + "rfdc": "^1.4.1", + "rollup": "^4.53.3", + "shiki": "^3.17.1", + "source-map-js": "^1.2.1", + "space-separated-tokens": "^2.0.2", + "speakingurl": "^14.0.1", + "stringify-entities": "^4.0.4", + "superjson": "^2.2.6", + "tabbable": "^6.3.0", + "tinyglobby": "^0.2.15", + "trim-lines": "^3.0.1", + "unist-util-is": "^6.0.1", + "unist-util-position": "^5.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.2", + "vfile": "^6.0.3", + "vfile-message": "^4.0.3", + "vite": "^7.2.6", + "vue": "^3.5.25", + "zwitch": "^2.0.4" + }, + "devDependencies": { + "vitepress": "^2.0.0-alpha.15" + } +} \ No newline at end of file diff --git a/docs/public/dd.svg b/docs/public/dd.svg new file mode 100644 index 00000000..407b6d77 --- /dev/null +++ b/docs/public/dd.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/assets/demo-dark.gif b/docs/public/demo-dark.gif similarity index 100% rename from docs/assets/demo-dark.gif rename to docs/public/demo-dark.gif diff --git a/docs/assets/demo-light.gif b/docs/public/demo-light.gif similarity index 100% rename from docs/assets/demo-light.gif rename to docs/public/demo-light.gif diff --git a/docs/assets/help.png b/docs/public/help.png similarity index 100% rename from docs/assets/help.png rename to docs/public/help.png diff --git a/docs/assets/logo.svg b/docs/public/logo.svg similarity index 100% rename from docs/assets/logo.svg rename to docs/public/logo.svg diff --git a/docs/public/maif.svg b/docs/public/maif.svg new file mode 100644 index 00000000..a3d39d30 --- /dev/null +++ b/docs/public/maif.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/assets/record.png b/docs/public/record.png similarity index 100% rename from docs/assets/record.png rename to docs/public/record.png diff --git a/docs/assets/records.png b/docs/public/records.png similarity index 100% rename from docs/assets/records.png rename to docs/public/records.png diff --git a/docs/assets/topics.png b/docs/public/topics.png similarity index 100% rename from docs/assets/topics.png rename to docs/public/topics.png diff --git a/docs/query-language/README.md b/docs/query-language/index.md similarity index 92% rename from docs/query-language/README.md rename to docs/query-language/index.md index 68a15703..4cafe068 100644 --- a/docs/query-language/README.md +++ b/docs/query-language/index.md @@ -36,7 +36,7 @@ value contains "release" ``` -5. Records where the `md5(key)` is equals to the user-provided parameter. A [search filter](../search-filter/README.md) must be implemented for this example. +5. Records where the `md5(key)` is equals to the user-provided parameter. A [search filter](../search-filter/index.md) must be implemented for this example. ```sql from begin md5-key-equals-to("d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f89") ``` \ No newline at end of file diff --git a/docs/release/README.md b/docs/release/index.md similarity index 100% rename from docs/release/README.md rename to docs/release/index.md diff --git a/docs/schema-registry/README.md b/docs/schema-registry/README.md deleted file mode 100644 index 23ca65cc..00000000 --- a/docs/schema-registry/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Schema registry - -⚠️ The support of the schema registry in Yozefu is **highly experimental**. Contributions and feedback are welcome: - -| Types | Support | -| ----------- | :-------------------- | -| Json schema | Experimental | -| Avro | Experimental | -| Protobuf | Not supported for now | - - - -You can configure the tool to use a schema registry. Open the configuration file `yozf configure`, and add a `schema_registry` entry to your cluster: -```json -{ - "clusters": { - "localhost": { - "url_template": "http://localhost:9000/ui/kafka-localhost-server/topic/{topic}/data?single=true&partition={partition}&offset={offset}", - "schema_registry": { - "url": "http://localhost:8081" - }, - "kafka": { - "bootstrap.servers": "localhost:9092", - "security.protocol": "plaintext", - "broker.address.family": "v4" - } - } - } -} -``` - - - - - -## Basic auth - -If the schema registry is protected by a basic authentication, you can add the `Authorization` header: - -```json -{ - "schema_registry": { - "url": "https://acme-schema-registry:8081", - "headers": { - "Authorization": "Basic am9obkBleGFtcGxlLmNvbTphYmMxMjM=" - } - } -} -``` - - -## Bearer token - -```json -{ - "schema_registry": { - "url": "https://acme-schema-registry:8081", - "headers": { - "Authorization": "Bearer " - } - } -} - -``` - - - - -## Authentication methods per provider - - -| Nom | Authentication methods | -| ----------------------------------------------------------------------------------- | ------------------------------- | -| [Confluent](https://confluent.cloud) | Basic authentication
OAuth | -| [Redpanda Cloud](https://docs.redpanda.com/current/manage/security/authentication/) | Basic authentication
OAuth | - - - diff --git a/docs/schema-registry/index.md b/docs/schema-registry/index.md new file mode 100644 index 00000000..cd9825d6 --- /dev/null +++ b/docs/schema-registry/index.md @@ -0,0 +1,56 @@ +# Schema registry + +> [!WARNING] +> The support of the schema registry is **highly experimental**. Contributions and feedback are welcome. + + + +| Types | Support | +| ----------- | :------------------------ | +| Json schema | Experimental | +| Avro | Experimental | +| Protobuf | Looking for contributions | + + + +You can configure the tool to use a schema registry. Open the configuration file and add a `schema_registry` entry to your cluster: + +```shell +EDITOR=nano yozf configure +``` +```json{4} +{ + "clusters": { + "localhost": { + "url_template": "http://localhost:9000/ui/kafka-localhost-server/topic/{topic}/data?single=true&partition={partition}&offset={offset}", + "schema_registry": { + "url": "http://localhost:8081" + }, + "kafka": { + "bootstrap.servers": "localhost:9092", + "security.protocol": "plaintext", + "broker.address.family": "v4" + } + } + } +} +``` + + + + + +## Authentication + +If the schema registry is protected by an authentication, you can specify the `Authorization` header for the schema registry client: + +```json{4-6} +{ + "schema_registry": { + "url": "https://acme-schema-registry:8081", + "headers": { + "Authorization": "Basic am9obkBleGFtcGxlLmNvbTphYmMxMjM=" + } + } +} +``` \ No newline at end of file diff --git a/docs/search-filter/README.md b/docs/search-filter/index.md similarity index 88% rename from docs/search-filter/README.md rename to docs/search-filter/index.md index 5613a052..11c3902d 100644 --- a/docs/search-filter/README.md +++ b/docs/search-filter/index.md @@ -1,7 +1,4 @@ -
-logo of WebAssembly -

Creating a search filter.

-
+# Creating a search filter Let's say you want to list all kafka records where the key ends with `1234`. Currently, the query syntax doesn't offer such feature. Fortunately, you have the ability to extend the search engine and create your own search logic. @@ -26,7 +23,7 @@ The name of the function corresponds to the name of the wasm file. In the exampl Yōzefu relies on [Extism](https://extism.org/) to develop and execute search filters. The WebAssembly module we're going to implement must export 2 functions, `parse_parameters` and `matches`. -The first step is to choose your preferred programming language. Extism supports different programming languages. You can read more at [Extism Quickstart Guide](https://extism.org/docs/quickstart/plugin-quickstart). I'll choose [golang](../../crates/wasm-blueprints/golang) for this example. A [Rust example](../../crates/wasm-blueprints/rust) is also available. +The first step is to choose your preferred programming language. Extism supports different programming languages. You can read more at [Extism Quickstart Guide](https://extism.org/docs/quickstart/plugin-quickstart). I'll choose [golang](https://github.com/MAIF/yozefu/blob/main/crates/wasm-blueprints/golang) for this example. A [Rust example](https://github.com/MAIF/yozefu/blob/main/crates/wasm-blueprints/rust) is also available. ```bash yozf create-filter --language golang key-ends-with --directory /tmp/my-filter @@ -34,14 +31,14 @@ yozf create-filter --language golang key-ends-with --directory /tmp/my-filter $EDITOR /tmp/my-filter ``` -If you need more context about how WebAssembly is called from the Rust codebase, feel free to explore [filter.rs](../../crates/app/src/search/filter.rs). +If you need more context about how WebAssembly is called from the Rust codebase, feel free to explore [filter.rs](https://github.com/MAIF/yozefu/blob/main/crates/app/src/search/filter.rs). ### Function `parse_parameters` This function ensures that user-provided parameters are valid. This function is called once at parsing time. The function must return a status code `0` when it's valid. Another status code means the parameters are invalid. -```golang +```go // golang example // https://github.com/MAIF/yozefu/blob/main/crates/wasm-blueprints/golang/main.go @@ -69,7 +66,7 @@ This function receives a [JSON object](./filter-input.json) containing both the -```golang +```go // golang example // https://github.com/MAIF/yozefu/blob/main/crates/wasm-blueprints/golang/main.go diff --git a/docs/themes/README.md b/docs/themes/index.md similarity index 78% rename from docs/themes/README.md rename to docs/themes/index.md index b1742fe5..f30060c0 100644 --- a/docs/themes/README.md +++ b/docs/themes/index.md @@ -1,6 +1,6 @@ -# Themes. +# Themes -A theme is a [set of colors](https://github.com/MAIF/yozefu/blob/main/crates/command/themes.json) defining the appearance of UI. By default, Yozefu comes with 3 built-in themes: +A theme is a [set of colors](https://github.com/MAIF/yozefu/blob/main/crates/command/themes.json) defining the appearance of UI. By default, Yōzefu comes with 3 built-in themes: - `light` - `dark` - `solarized-dark-higher-contrast` @@ -12,10 +12,10 @@ yozf config get themes_file ``` -## How to select a theme +### How to select a theme You have 2 options: - 1. Use the `--theme ` flag when launching yozefu. + 1. Use the `--theme ` flag when launching yōzefu. 2. Or update your configuration: `yozf config set /theme solarized-dark-higher-contrast` 🖌️ You can also create, update and share your own themes by editing `themes.json`. @@ -23,7 +23,7 @@ You have 2 options: ## Highlighter -For syntax highlighting, Yozefu uses [Syntect](https://github.com/trishume/syntect) +For syntax highlighting, Yōzefu uses [Syntect](https://github.com/trishume/syntect) Syntect includes [7 built-in themes](https://github.com/trishume/syntect/blob/2a3a09d54710a2d6a9b7724784e2a412d22a2375/src/dumps.rs#L208-L217): - `base16-ocean.dark` - `base16-eighties.dark` @@ -34,7 +34,7 @@ Syntect includes [7 built-in themes](https://github.com/trishume/syntect/blob/2a - `Solarized (light)` -## How to select a highlighter theme +### How to select a highlighter theme? You can configure it in two ways: 1. In `config.json`, under the `/highlighter_theme` property. @@ -42,12 +42,12 @@ You can configure it in two ways: -## Using a custom highlighter theme +### Using a custom highlighter theme `syntect` supports [Sublime Text `.tmTheme` format](https://www.sublimetext.com/docs/color_schemes_tmtheme.html). For example, to use [`Srcery TextMate`](https://github.com/srcery-colors/srcery-textmate): - 1. Go to your Yozefu configuration directory: `cd $(yozf config get dir)` + 1. Go to your Yōzefu configuration directory: `cd $(yozf config get dir)` 2. Download the theme: `git clone https://github.com/srcery-colors/srcery-textmate.git`. 3. Edit your configuration to point to the theme file: ```bash @@ -64,8 +64,8 @@ yozf configure } ``` - 1. Save the file and restart Yozefu for the changes to take effect. + 1. Save the file and restart Yōzefu for the changes to take effect. > [!NOTE] -> You can disable Syntect by setting the `highlighter_theme` property to `null` in your configuration and `themes.json`. +> You can disable Syntect by setting the `highlighter_theme` property to `null` in your configuration and `themes.json`. \ No newline at end of file diff --git a/docs/tls/README.md b/docs/tls/index.md similarity index 84% rename from docs/tls/README.md rename to docs/tls/index.md index ca0460fe..414e56e8 100644 --- a/docs/tls/README.md +++ b/docs/tls/index.md @@ -1,10 +1,4 @@ -# TLS encryption and authentication -

- - Link to librdkakfa configuration - - How to configure the librdkakfa client -

+# TLS This page helps you configure TLS settings for different providers. @@ -108,8 +102,12 @@ For more details, refer to the documentation: https://docs.aws.amazon.com/msk/la ## Mutual TLS -For more details about Mutual TLS, refer to the documentation: https://docs.confluent.io/platform/current/kafka/configure-mds/mutual-tls-auth-rbac.html.Certificates. -Please note that, according to [the documentation](https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md), certificates must be in PEM format. +For more details about Mutual TLS, refer to the documentation: [Configure mTLS Authentication and RBAC for Kafka Brokers](https://docs.confluent.io/platform/current/kafka/configure-mds/mutual-tls-auth-rbac.html). + + +> [!INFO] +> Please note that, according to [the documentation](https://github.com/confluentinc/librdkafka/blob/master/CONFIGURATION.md), certificates must be in PEM format. + ```json { "clusters": { diff --git a/docs/url-templates/README.md b/docs/url-templates/index.md similarity index 94% rename from docs/url-templates/README.md rename to docs/url-templates/index.md index 0d21fd09..98808b0b 100644 --- a/docs/url-templates/README.md +++ b/docs/url-templates/index.md @@ -1,6 +1,6 @@ -# URL templates to switch to web applications +# URL templates -In certain situations, you may need to view a Kafka record in a web browser. `yozefu` allows you to do so: select the Kafka record and press the o key (for **o**pen). This will open the corresponding URL in a new browser tab. +In certain situations, you may need to view a Kafka record in a web browser. Yōzefu allows you to do so: select the Kafka record and press the o key (for **o**pen). This will open the corresponding URL in a new browser tab. The tool uses a URL template from the configuration file. this template is defined in the `.clusters..url_template` property, where `` is the specific cluster name you're using. diff --git a/docs/what-is-yozefu/index.md b/docs/what-is-yozefu/index.md new file mode 100644 index 00000000..86f9d83b --- /dev/null +++ b/docs/what-is-yozefu/index.md @@ -0,0 +1,46 @@ +# What is Yōzefu? + + +Yōzefu is designed to be a fast and efficient tool to explore Kafka clusters from the terminal. It aims to provide a user-friendly interface while leveraging the power of the terminal for quick navigation and operations. More details on this [blog post](https://mcdostone.github.io/articles/why-yozefu/). + + +Yōzefu is a reference to the main character of **The Trial**, the novel of Franz Kafka. + + + +## A TUI and a CLI + +Yōzefu can be used as an interactive terminal user interface (TUI) or as a command-line interface in headless mode. + +**TUI mode** +```shell +yozf --cluster preproduction \ +-t my.topic.of.books \ +"from begin where key == '978-2070315932' limit 1" \ +--format transpose +``` + +**Headless mode** +```shell +yozf --headless \ +-c preproduction \ +-t my.topic.of.books \ +"from begin where key == '978-2070315932' limit 1" \ +--format simple +``` + +## Limitations + + - The tool is designed only to consume kafka records. There is no feature to produce records or manage a cluster. + - Serialization formats such as json, xml or plain text are supported. Avro support is experimental for now. Protobuf is not supported. + - ōzefu gives you the feeling that every kafka records stays in memory but in reality, it uses a ring buffer to store only the last 500 kafka records. + - There is probably room for improvement regarding the throughput (lot of clone() and deserialization). + - Yōzefu has been tested on macOS Silicon but not on Windows or Linux. Feedback or contributions are welcome. + + +## Screenshots + +![Records panel](../public/records.png) +![record panel](../public/record.png) +![topic panel](../public/topics.png) +![help panel](../public/help.png) \ No newline at end of file diff --git a/typos.toml b/typos.toml index 372dc952..017e9205 100644 --- a/typos.toml +++ b/typos.toml @@ -1,2 +1,4 @@ [default.extend-words] ratatui = "ratatui" +devlop = "devlop" +