From ac6181ccd0d9442ffc050d895df805221021cecf Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Wed, 25 Mar 2026 11:58:06 -0400 Subject: [PATCH 1/6] Add storybook for component development Signed-off-by: Nicholas Gates --- .github/workflows/web.yml | 78 ++ vortex-web/.storybook/main.ts | 13 + vortex-web/.storybook/preview.ts | 15 + vortex-web/README.md | 76 ++ vortex-web/eslint.config.ts | 40 +- vortex-web/package-lock.json | 1303 +++++++++++++++++++++++++++++- vortex-web/package.json | 8 +- 7 files changed, 1504 insertions(+), 29 deletions(-) create mode 100644 vortex-web/.storybook/main.ts create mode 100644 vortex-web/.storybook/preview.ts create mode 100644 vortex-web/README.md diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index 11b674b86c1..9b15e8a4137 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -63,6 +63,84 @@ jobs: path: vortex-web/dist retention-days: 7 + storybook: + name: Build Storybook + needs: [changes] + if: needs.changes.outputs.web == 'true' + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v4 + with: + node-version: "22" + cache: "npm" + cache-dependency-path: vortex-web/package-lock.json + - run: npm ci + - run: npm run build-storybook + - uses: actions/upload-artifact@v4 + with: + name: vortex-storybook-dist + path: vortex-web/storybook-static + retention-days: 7 + + storybook-preview: + name: Deploy Storybook Preview + needs: [storybook] + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + pull-requests: write + deployments: write + environment: + name: storybook-preview + url: ${{ steps.deploy.outputs.deployment-url }} + steps: + - uses: actions/download-artifact@v4 + with: + name: vortex-storybook-dist + path: storybook-static + - name: Deploy to Cloudflare Pages + id: deploy + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: >- + pages deploy storybook-static/ + --project-name=vortex-storybook + --branch=${{ github.head_ref || github.ref_name }} + - name: Comment Storybook preview URL on PR + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const body = `**Vortex Storybook Preview:** ${{ steps.deploy.outputs.deployment-url }}`; + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + const existing = comments.find(c => + c.body?.startsWith('**Vortex Storybook Preview:**') + ); + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + } + preview: name: Deploy Preview needs: [build, changes] diff --git a/vortex-web/.storybook/main.ts b/vortex-web/.storybook/main.ts new file mode 100644 index 00000000000..a9344785df8 --- /dev/null +++ b/vortex-web/.storybook/main.ts @@ -0,0 +1,13 @@ +import type { StorybookConfig } from '@storybook/react-vite'; + +const config: StorybookConfig = { + "stories": [ + "../src/**/*.mdx", + "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)" + ], + "addons": [ + "@storybook/addon-docs", + ], + "framework": "@storybook/react-vite" +}; +export default config; \ No newline at end of file diff --git a/vortex-web/.storybook/preview.ts b/vortex-web/.storybook/preview.ts new file mode 100644 index 00000000000..8b4b705f7ec --- /dev/null +++ b/vortex-web/.storybook/preview.ts @@ -0,0 +1,15 @@ +import type { Preview } from '@storybook/react-vite' +import '../src/index.css' + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + }, +}; + +export default preview; \ No newline at end of file diff --git a/vortex-web/README.md b/vortex-web/README.md new file mode 100644 index 00000000000..2ae9d73361d --- /dev/null +++ b/vortex-web/README.md @@ -0,0 +1,76 @@ +# Vortex Web + +A web UI for exploring Vortex data files, built with React, TypeScript, Tailwind CSS, and Rust/WASM. + +## Prerequisites + +- Node.js 22+ +- [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/) (for full app development) +- Rust toolchain (for full app development) + +## Getting Started + +```bash +npm install +``` + +### Full App (requires Rust + wasm-pack) + +```bash +# Start dev server (builds WASM in debug mode, then starts Vite) +npm run dev +``` + +### Storybook (no Rust/WASM required) + +Storybook lets you develop and preview UI components in isolation: + +```bash +npm run storybook +``` + +This starts a dev server at http://localhost:6006. + +## Scripts + +| Command | Description | +|---|---| +| `npm run dev` | Build WASM (debug) + start Vite dev server | +| `npm run build` | Production build (WASM release + Vite) | +| `npm run storybook` | Start Storybook dev server on port 6006 | +| `npm run build-storybook` | Build static Storybook site | +| `npm run lint` | Run ESLint | +| `npm run lint:fix` | Run ESLint with auto-fix | +| `npm run typecheck` | Run TypeScript type checking | +| `npm run check` | Build WASM + lint + typecheck | + +## Writing Stories + +Add story files alongside your components as `*.stories.tsx`: + +```tsx +import type { Meta, StoryObj } from '@storybook/react-vite'; +import { MyComponent } from './MyComponent'; + +const meta: Meta = { + component: MyComponent, +}; +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: {}, +}; +``` + +## Project Structure + +``` +vortex-web/ + crate/ # Rust WASM crate (vortex bindings) + src/ # React/TypeScript frontend + wasm/pkg/ # Generated WASM bindings (not checked in) + .storybook/ # Storybook configuration + public/ # Static assets +``` diff --git a/vortex-web/eslint.config.ts b/vortex-web/eslint.config.ts index cf1c40ae84e..72dde640163 100644 --- a/vortex-web/eslint.config.ts +++ b/vortex-web/eslint.config.ts @@ -5,27 +5,25 @@ import js from "@eslint/js"; import globals from "globals"; import reactHooks from "eslint-plugin-react-hooks"; import reactRefresh from "eslint-plugin-react-refresh"; +import storybook from "eslint-plugin-storybook"; import tseslint from "typescript-eslint"; -export default tseslint.config( - { ignores: ["dist"] }, - { - extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ["**/*.{ts,tsx}"], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - plugins: { - "react-hooks": reactHooks, - "react-refresh": reactRefresh, - }, - rules: { - ...reactHooks.configs.recommended.rules, - "react-refresh/only-export-components": [ - "warn", - { allowConstantExport: true }, - ], - }, +export default tseslint.config({ ignores: ["dist"] }, { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, }, -); + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + }, +}, storybook.configs["flat/recommended"]); diff --git a/vortex-web/package-lock.json b/vortex-web/package-lock.json index 56fcd69c1f4..3d8f3549bef 100644 --- a/vortex-web/package-lock.json +++ b/vortex-web/package-lock.json @@ -13,6 +13,8 @@ }, "devDependencies": { "@eslint/js": "^9.25.0", + "@storybook/addon-docs": "^10.3.3", + "@storybook/react-vite": "^10.3.3", "@tailwindcss/vite": "^4.1.4", "@types/react": "^19.1.2", "@types/react-dom": "^19.1.2", @@ -20,13 +22,22 @@ "eslint": "^9.25.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", + "eslint-plugin-storybook": "^10.3.3", "globals": "^16.0.0", + "storybook": "^10.3.3", "tailwindcss": "^4.1.4", "typescript": "~5.7.0", "typescript-eslint": "^8.30.1", "vite": "^6.3.2" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", @@ -262,6 +273,16 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", @@ -961,6 +982,26 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@joshwooding/vite-plugin-react-docgen-typescript": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.6.4.tgz", + "integrity": "sha512-6PyZBYKnnVNqOSB0YFly+62R7dmov8segT27A+RVTBVd4iAE6kbW9QBJGlyR2yG4D4ohzhZSTIu7BK1UTtmFFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^13.0.1", + "react-docgen-typescript": "^2.2.2" + }, + "peerDependencies": { + "typescript": ">= 4.3.x", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -1011,6 +1052,24 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", @@ -1018,6 +1077,29 @@ "dev": true, "license": "MIT" }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.60.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.0.tgz", @@ -1368,6 +1450,173 @@ "win32" ] }, + "node_modules/@storybook/addon-docs": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.3.3.tgz", + "integrity": "sha512-trJQTpOtuOEuNv1Rn8X2Sopp5hSPpb0u0soEJ71BZAbxe4d2Y1d/1MYcxBdRKwncum6sCTsnxTpqQ/qvSJKlTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mdx-js/react": "^3.0.0", + "@storybook/csf-plugin": "10.3.3", + "@storybook/icons": "^2.0.1", + "@storybook/react-dom-shim": "10.3.3", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.3.3" + } + }, + "node_modules/@storybook/builder-vite": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-10.3.3.tgz", + "integrity": "sha512-awspKCTZvXyeV3KabL0id62mFbxR5u/5yyGQultwCiSb2/yVgBfip2MAqLyS850pvTiB6QFVM9deOyd2/G/bEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/csf-plugin": "10.3.3", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.3.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@storybook/csf-plugin": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.3.3.tgz", + "integrity": "sha512-Utlh7zubm+4iOzBBfzLW4F4vD99UBtl2Do4edlzK2F7krQIcFvR2ontjAE8S1FQVLZAC3WHalCOS+Ch8zf3knA==", + "dev": true, + "license": "MIT", + "dependencies": { + "unplugin": "^2.3.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "esbuild": "*", + "rollup": "*", + "storybook": "^10.3.3", + "vite": "*", + "webpack": "*" + }, + "peerDependenciesMeta": { + "esbuild": { + "optional": true + }, + "rollup": { + "optional": true + }, + "vite": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/@storybook/global": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@storybook/icons": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-2.0.1.tgz", + "integrity": "sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@storybook/react": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-10.3.3.tgz", + "integrity": "sha512-cGG5TbR8Tdx9zwlpsWyBEfWrejm5iWdYF26EwIhwuKq9GFUTAVrQzo0Rs7Tqc3ZyVhRS/YfsRiWSEH+zmq2JiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/react-dom-shim": "10.3.3", + "react-docgen": "^8.0.2", + "react-docgen-typescript": "^2.2.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.3.3", + "typescript": ">= 4.9.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@storybook/react-dom-shim": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.3.3.tgz", + "integrity": "sha512-lkhuh4G3UTreU9M3Iz5Dt32c6U+l/4XuvqLtbe1sDHENZH6aPj7y0b5FwnfHyvuTvYRhtbo29xZrF5Bp9kCC0w==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.3.3" + } + }, + "node_modules/@storybook/react-vite": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.3.3.tgz", + "integrity": "sha512-qHdlBe1hjqFAGXa8JL7bWTLbP/gDqXbWDm+SYCB646NHh5yvVDkZLwigP5Y+UL7M2ASfqFtosnroUK9tcCM2dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@joshwooding/vite-plugin-react-docgen-typescript": "^0.6.4", + "@rollup/pluginutils": "^5.0.2", + "@storybook/builder-vite": "10.3.3", + "@storybook/react": "10.3.3", + "empathic": "^2.0.0", + "magic-string": "^0.30.0", + "react-docgen": "^8.0.0", + "resolve": "^1.22.8", + "tsconfig-paths": "^4.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.3.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/@tailwindcss/node": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz", @@ -1640,6 +1889,75 @@ "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1685,6 +2003,31 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/doctrine": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -1699,6 +2042,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.2.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", @@ -1720,6 +2070,13 @@ "@types/react": "^19.2.0" } }, + "node_modules/@types/resolve": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", + "integrity": "sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.57.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", @@ -2037,6 +2394,74 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/expect/node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/acorn": { "version": "8.16.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", @@ -2078,6 +2503,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2101,6 +2536,39 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2167,6 +2635,22 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2198,15 +2682,32 @@ ], "license": "CC-BY-4.0" }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=10" @@ -2215,6 +2716,16 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2264,6 +2775,13 @@ "node": ">= 8" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -2289,6 +2807,16 @@ } } }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2296,6 +2824,59 @@ "dev": true, "license": "MIT" }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -2306,6 +2887,26 @@ "node": ">=8" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, "node_modules/electron-to-chromium": { "version": "1.5.322", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.322.tgz", @@ -2313,6 +2914,16 @@ "dev": true, "license": "ISC" }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/enhanced-resolve": { "version": "5.20.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", @@ -2334,6 +2945,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -2476,6 +3088,20 @@ "eslint": ">=8.40" } }, + "node_modules/eslint-plugin-storybook": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.3.3.tgz", + "integrity": "sha512-jo8wZvKaJlxxrNvf4hCsROJP3CdlpaLiYewAs5Ww+PJxCrLelIi5XVHWOAgBvvr3H9WDKvUw8xuvqPYqAlpkFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.48.0" + }, + "peerDependencies": { + "eslint": ">=8", + "storybook": "^10.3.3" + } + }, "node_modules/eslint-scope": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", @@ -2524,6 +3150,20 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", @@ -2560,6 +3200,13 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -2675,6 +3322,16 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2685,6 +3342,24 @@ "node": ">=6.9.0" } }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2698,6 +3373,45 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", @@ -2728,6 +3442,19 @@ "node": ">=8" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -2765,6 +3492,48 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2788,6 +3557,41 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3180,6 +3984,13 @@ "dev": true, "license": "MIT" }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3190,6 +4001,16 @@ "yallist": "^3.0.2" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -3200,6 +4021,16 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", @@ -3213,6 +4044,26 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -3253,6 +4104,25 @@ "dev": true, "license": "MIT" }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -3336,6 +4206,50 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.7", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", + "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3349,7 +4263,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -3396,6 +4309,34 @@ "node": ">= 0.8.0" } }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3416,11 +4357,44 @@ "node": ">=0.10.0" } }, + "node_modules/react-docgen": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/react-docgen/-/react-docgen-8.0.3.tgz", + "integrity": "sha512-aEZ9qP+/M+58x2qgfSFEWH1BxLyHe5+qkLNJOZQb5iGS017jpbRnoKhNRrXPeA6RfBrZO5wZrT9DMC1UqE1f1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/traverse": "^7.28.0", + "@babel/types": "^7.28.2", + "@types/babel__core": "^7.20.5", + "@types/babel__traverse": "^7.20.7", + "@types/doctrine": "^0.0.9", + "@types/resolve": "^1.20.2", + "doctrine": "^3.0.0", + "resolve": "^1.22.1", + "strip-indent": "^4.0.0" + }, + "engines": { + "node": "^20.9.0 || >=22" + } + }, + "node_modules/react-docgen-typescript": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz", + "integrity": "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">= 4.3.x" + } + }, "node_modules/react-dom": { "version": "19.2.4", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -3428,6 +4402,13 @@ "react": "^19.2.4" } }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT" + }, "node_modules/react-refresh": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", @@ -3438,6 +4419,71 @@ "node": ">=0.10.0" } }, + "node_modules/recast": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redent/node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3454,6 +4500,7 @@ "integrity": "sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -3493,6 +4540,19 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -3532,6 +4592,16 @@ "node": ">=8" } }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -3542,6 +4612,92 @@ "node": ">=0.10.0" } }, + "node_modules/storybook": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.3.3.tgz", + "integrity": "sha512-tMoRAts9EVqf+mEMPLC6z1DPyHbcPe+CV1MhLN55IKsl0HxNjvVGK44rVPSePbltPE6vIsn4bdRj6CCUt8SJwQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/icons": "^2.0.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/user-event": "^14.6.1", + "@vitest/expect": "3.2.4", + "@vitest/spy": "3.2.4", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", + "open": "^10.2.0", + "recast": "^0.23.5", + "semver": "^7.7.3", + "use-sync-external-store": "^1.5.0", + "ws": "^8.18.0" + }, + "bin": { + "storybook": "dist/bin/dispatcher.js" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/storybook/node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/storybook/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-indent": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", + "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -3568,6 +4724,19 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/tailwindcss": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", @@ -3589,6 +4758,13 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -3606,6 +4782,16 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -3619,6 +4805,38 @@ "typescript": ">=4.8.4" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3671,6 +4889,22 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", @@ -3712,6 +4946,16 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/vite": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", @@ -3788,6 +5032,13 @@ } } }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3814,6 +5065,44 @@ "node": ">=0.10.0" } }, + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/vortex-web/package.json b/vortex-web/package.json index 0cd3212b2c6..b4db8620f73 100644 --- a/vortex-web/package.json +++ b/vortex-web/package.json @@ -12,7 +12,9 @@ "preview": "vite preview", "lint": "eslint .", "lint:fix": "eslint . --fix", - "typecheck": "tsc -b --noEmit" + "typecheck": "tsc -b --noEmit", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" }, "dependencies": { "react": "^19.1.0", @@ -20,6 +22,8 @@ }, "devDependencies": { "@eslint/js": "^9.25.0", + "@storybook/addon-docs": "^10.3.3", + "@storybook/react-vite": "^10.3.3", "@tailwindcss/vite": "^4.1.4", "@types/react": "^19.1.2", "@types/react-dom": "^19.1.2", @@ -27,7 +31,9 @@ "eslint": "^9.25.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", + "eslint-plugin-storybook": "^10.3.3", "globals": "^16.0.0", + "storybook": "^10.3.3", "tailwindcss": "^4.1.4", "typescript": "~5.7.0", "typescript-eslint": "^8.30.1", From 2acbce953c1cb912c809d6bb2329a2ae2a100e74 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Wed, 25 Mar 2026 11:58:40 -0400 Subject: [PATCH 2/6] Add storybook for component development Signed-off-by: Nicholas Gates --- vortex-web/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/vortex-web/README.md b/vortex-web/README.md index 2ae9d73361d..ac1a1a53201 100644 --- a/vortex-web/README.md +++ b/vortex-web/README.md @@ -33,34 +33,34 @@ This starts a dev server at http://localhost:6006. ## Scripts -| Command | Description | -|---|---| -| `npm run dev` | Build WASM (debug) + start Vite dev server | -| `npm run build` | Production build (WASM release + Vite) | -| `npm run storybook` | Start Storybook dev server on port 6006 | -| `npm run build-storybook` | Build static Storybook site | -| `npm run lint` | Run ESLint | -| `npm run lint:fix` | Run ESLint with auto-fix | -| `npm run typecheck` | Run TypeScript type checking | -| `npm run check` | Build WASM + lint + typecheck | +| Command | Description | +|---------------------------|--------------------------------------------| +| `npm run dev` | Build WASM (debug) + start Vite dev server | +| `npm run build` | Production build (WASM release + Vite) | +| `npm run storybook` | Start Storybook dev server on port 6006 | +| `npm run build-storybook` | Build static Storybook site | +| `npm run lint` | Run ESLint | +| `npm run lint:fix` | Run ESLint with auto-fix | +| `npm run typecheck` | Run TypeScript type checking | +| `npm run check` | Build WASM + lint + typecheck | ## Writing Stories Add story files alongside your components as `*.stories.tsx`: ```tsx -import type { Meta, StoryObj } from '@storybook/react-vite'; -import { MyComponent } from './MyComponent'; +import type {Meta, StoryObj} from '@storybook/react-vite'; +import {MyComponent} from './MyComponent'; const meta: Meta = { - component: MyComponent, + component: MyComponent, }; export default meta; type Story = StoryObj; export const Default: Story = { - args: {}, + args: {}, }; ``` From bdb0c6bb142403bc10604ea75bc9121a5d070bb5 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Wed, 25 Mar 2026 13:07:39 -0400 Subject: [PATCH 3/6] A bunch of AI slop to generate scan graphs, as well as fixing lots of split problems Signed-off-by: Nicholas Gates --- .github/workflows/web.yml | 29 ++++++- vortex-web/.gitignore | 4 +- vortex-web/src/wasm/pkg/package.json | 17 +++++ vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts | 75 +++++++++++++++++++ .../src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts | 19 +++++ 5 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 vortex-web/src/wasm/pkg/package.json create mode 100644 vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts create mode 100644 vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index 9b15e8a4137..5f97ac33214 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -36,8 +36,27 @@ jobs: - "vortex-web/**" - ".github/workflows/web.yml" + check: + name: Lint & Typecheck + needs: [changes] + if: needs.changes.outputs.web == 'true' + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v4 + with: + node-version: "22" + cache: "npm" + cache-dependency-path: vortex-web/package-lock.json + - run: npm ci + - run: npm run lint + - run: npm run typecheck + build: name: Build + needs: [changes] + if: needs.changes.outputs.web == 'true' runs-on: ubuntu-latest timeout-minutes: 30 steps: @@ -55,8 +74,11 @@ jobs: cache: "npm" cache-dependency-path: vortex-web/package-lock.json - run: npm ci + - name: Verify committed WASM types are up-to-date + run: | + npm run wasm + git diff --exit-code src/wasm/pkg/*.d.ts src/wasm/pkg/package.json - run: npm run build - - run: npm run lint - uses: actions/upload-artifact@v4 with: name: vortex-web-dist @@ -94,7 +116,7 @@ jobs: pull-requests: write deployments: write environment: - name: storybook-preview + name: preview url: ${{ steps.deploy.outputs.deployment-url }} steps: - uses: actions/download-artifact@v4 @@ -143,8 +165,7 @@ jobs: preview: name: Deploy Preview - needs: [build, changes] - if: needs.changes.outputs.web == 'true' + needs: [build] runs-on: ubuntu-latest timeout-minutes: 10 permissions: diff --git a/vortex-web/.gitignore b/vortex-web/.gitignore index 5b8d31bbb7f..9cc815e482e 100644 --- a/vortex-web/.gitignore +++ b/vortex-web/.gitignore @@ -1,4 +1,6 @@ node_modules dist -src/wasm/pkg +storybook-static +src/wasm/pkg/*.js +src/wasm/pkg/*.wasm *.local diff --git a/vortex-web/src/wasm/pkg/package.json b/vortex-web/src/wasm/pkg/package.json new file mode 100644 index 00000000000..6cf192c28a4 --- /dev/null +++ b/vortex-web/src/wasm/pkg/package.json @@ -0,0 +1,17 @@ +{ + "name": "vortex-web-wasm", + "type": "module", + "description": "WASM bindings for the Vortex web explorer", + "version": "0.1.0", + "license": "Apache-2.0", + "files": [ + "vortex_web_wasm_bg.wasm", + "vortex_web_wasm.js", + "vortex_web_wasm.d.ts" + ], + "main": "vortex_web_wasm.js", + "types": "vortex_web_wasm.d.ts", + "sideEffects": [ + "./snippets/*" + ] +} \ No newline at end of file diff --git a/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts b/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts new file mode 100644 index 00000000000..a0737cb5d1a --- /dev/null +++ b/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts @@ -0,0 +1,75 @@ +/* tslint:disable */ +/* eslint-disable */ + +/** + * A handle to an opened Vortex file, exposing metadata to JavaScript. + */ +export class VortexFileHandle { + private constructor(); + free(): void; + [Symbol.dispose](): void; + /** + * The top-level DType of the file as a string. + */ + readonly dtype: string; + /** + * The total number of rows in the file. + */ + readonly row_count: bigint; +} + +/** + * Initialize the WASM module (sets up panic hook for better error messages). + */ +export function init(): void; + +/** + * Open a Vortex file from raw bytes and return a handle for exploration. + * + * Call this from JavaScript after reading a `.vortex` file via drag-and-drop. + */ +export function open_vortex_file(data: Uint8Array): VortexFileHandle; + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly init: () => void; + readonly open_vortex_file: (a: number, b: number) => [number, number, number]; + readonly __wbg_vortexfilehandle_free: (a: number, b: number) => void; + readonly vortexfilehandle_row_count: (a: number) => bigint; + readonly vortexfilehandle_dtype: (a: number) => [number, number]; + readonly wasm_bindgen__closure__destroy__h315b7af3ad8e2911: (a: number, b: number) => void; + readonly wasm_bindgen__convert__closures_____invoke__hd9aaad206556e4f9: (a: number, b: number, c: any) => [number, number]; + readonly wasm_bindgen__convert__closures_____invoke__hbcb1741f2446bbd2: (a: number, b: number) => number; + readonly __wbindgen_exn_store: (a: number) => void; + readonly __externref_table_alloc: () => number; + readonly __wbindgen_externrefs: WebAssembly.Table; + readonly __wbindgen_free: (a: number, b: number, c: number) => void; + readonly __wbindgen_malloc: (a: number, b: number) => number; + readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __externref_table_dealloc: (a: number) => void; + readonly __wbindgen_start: () => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; + +/** + * Instantiates the given `module`, which can either be bytes or + * a precompiled `WebAssembly.Module`. + * + * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. + * + * @returns {InitOutput} + */ +export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; + +/** + * If `module_or_path` is {RequestInfo} or {URL}, makes a request and + * for everything else, calls `WebAssembly.instantiate` directly. + * + * @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. + * + * @returns {Promise} + */ +export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; diff --git a/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts b/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts new file mode 100644 index 00000000000..4ed7d60610e --- /dev/null +++ b/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts @@ -0,0 +1,19 @@ +/* tslint:disable */ +/* eslint-disable */ +export const memory: WebAssembly.Memory; +export const init: () => void; +export const open_vortex_file: (a: number, b: number) => [number, number, number]; +export const __wbg_vortexfilehandle_free: (a: number, b: number) => void; +export const vortexfilehandle_row_count: (a: number) => bigint; +export const vortexfilehandle_dtype: (a: number) => [number, number]; +export const wasm_bindgen__closure__destroy__h315b7af3ad8e2911: (a: number, b: number) => void; +export const wasm_bindgen__convert__closures_____invoke__hd9aaad206556e4f9: (a: number, b: number, c: any) => [number, number]; +export const wasm_bindgen__convert__closures_____invoke__hbcb1741f2446bbd2: (a: number, b: number) => number; +export const __wbindgen_exn_store: (a: number) => void; +export const __externref_table_alloc: () => number; +export const __wbindgen_externrefs: WebAssembly.Table; +export const __wbindgen_free: (a: number, b: number, c: number) => void; +export const __wbindgen_malloc: (a: number, b: number) => number; +export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; +export const __externref_table_dealloc: (a: number) => void; +export const __wbindgen_start: () => void; From a51950d7002c9669f47df0b400f09e13a2ec1c0d Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Wed, 25 Mar 2026 13:15:20 -0400 Subject: [PATCH 4/6] Copyright Signed-off-by: Nicholas Gates --- .idea/copyright/profiles_settings.xml | 14 ++++++++++++++ .idea/scopes/web_files.xml | 3 +++ vortex-web/.storybook/main.ts | 3 +++ vortex-web/.storybook/preview.ts | 3 +++ vortex-web/src/wasm/pkg/package.json.license | 2 ++ .../src/wasm/pkg/vortex_web_wasm.d.ts.license | 2 ++ .../wasm/pkg/vortex_web_wasm_bg.wasm.d.ts.license | 2 ++ 7 files changed, 29 insertions(+) create mode 100644 .idea/scopes/web_files.xml create mode 100644 vortex-web/src/wasm/pkg/package.json.license create mode 100644 vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts.license create mode 100644 vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts.license diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml index 61532053af8..fddee87269b 100644 --- a/.idea/copyright/profiles_settings.xml +++ b/.idea/copyright/profiles_settings.xml @@ -2,10 +2,24 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/scopes/web_files.xml b/.idea/scopes/web_files.xml new file mode 100644 index 00000000000..7f11007f7f9 --- /dev/null +++ b/.idea/scopes/web_files.xml @@ -0,0 +1,3 @@ + + + diff --git a/vortex-web/.storybook/main.ts b/vortex-web/.storybook/main.ts index a9344785df8..93a5ba691cd 100644 --- a/vortex-web/.storybook/main.ts +++ b/vortex-web/.storybook/main.ts @@ -1,3 +1,6 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors + import type { StorybookConfig } from '@storybook/react-vite'; const config: StorybookConfig = { diff --git a/vortex-web/.storybook/preview.ts b/vortex-web/.storybook/preview.ts index 8b4b705f7ec..85daeef5177 100644 --- a/vortex-web/.storybook/preview.ts +++ b/vortex-web/.storybook/preview.ts @@ -1,3 +1,6 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors + import type { Preview } from '@storybook/react-vite' import '../src/index.css' diff --git a/vortex-web/src/wasm/pkg/package.json.license b/vortex-web/src/wasm/pkg/package.json.license new file mode 100644 index 00000000000..8e5a7614c30 --- /dev/null +++ b/vortex-web/src/wasm/pkg/package.json.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: Apache-2.0 +SPDX-FileCopyrightText: Copyright the Vortex contributors diff --git a/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts.license b/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts.license new file mode 100644 index 00000000000..8e5a7614c30 --- /dev/null +++ b/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: Apache-2.0 +SPDX-FileCopyrightText: Copyright the Vortex contributors diff --git a/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts.license b/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts.license new file mode 100644 index 00000000000..8e5a7614c30 --- /dev/null +++ b/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: Apache-2.0 +SPDX-FileCopyrightText: Copyright the Vortex contributors From ebe7d9fb3008b46b938fde85f943fe0b3f870f3c Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Wed, 25 Mar 2026 13:26:18 -0400 Subject: [PATCH 5/6] Copyright Signed-off-by: Nicholas Gates --- .github/workflows/web.yml | 166 +----------------- vortex-web/.gitignore | 3 +- vortex-web/src/wasm/pkg/package.json.license | 2 - vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts | 84 ++++----- .../src/wasm/pkg/vortex_web_wasm.d.ts.license | 2 - .../pkg/vortex_web_wasm_bg.wasm.d.ts.license | 2 - 6 files changed, 36 insertions(+), 223 deletions(-) delete mode 100644 vortex-web/src/wasm/pkg/package.json.license delete mode 100644 vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts.license delete mode 100644 vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts.license diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index 5f97ac33214..871382d1ca7 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -36,25 +36,8 @@ jobs: - "vortex-web/**" - ".github/workflows/web.yml" - check: - name: Lint & Typecheck - needs: [changes] - if: needs.changes.outputs.web == 'true' - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - cache-dependency-path: vortex-web/package-lock.json - - run: npm ci - - run: npm run lint - - run: npm run typecheck - build: - name: Build + name: Build & Check needs: [changes] if: needs.changes.outputs.web == 'true' runs-on: ubuntu-latest @@ -74,148 +57,7 @@ jobs: cache: "npm" cache-dependency-path: vortex-web/package-lock.json - run: npm ci - - name: Verify committed WASM types are up-to-date - run: | - npm run wasm - git diff --exit-code src/wasm/pkg/*.d.ts src/wasm/pkg/package.json - - run: npm run build - - uses: actions/upload-artifact@v4 - with: - name: vortex-web-dist - path: vortex-web/dist - retention-days: 7 - - storybook: - name: Build Storybook - needs: [changes] - if: needs.changes.outputs.web == 'true' - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - cache-dependency-path: vortex-web/package-lock.json - - run: npm ci + - run: npm run wasm + - run: npm run lint + - run: npm run typecheck - run: npm run build-storybook - - uses: actions/upload-artifact@v4 - with: - name: vortex-storybook-dist - path: vortex-web/storybook-static - retention-days: 7 - - storybook-preview: - name: Deploy Storybook Preview - needs: [storybook] - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - contents: read - pull-requests: write - deployments: write - environment: - name: preview - url: ${{ steps.deploy.outputs.deployment-url }} - steps: - - uses: actions/download-artifact@v4 - with: - name: vortex-storybook-dist - path: storybook-static - - name: Deploy to Cloudflare Pages - id: deploy - uses: cloudflare/wrangler-action@v3 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: >- - pages deploy storybook-static/ - --project-name=vortex-storybook - --branch=${{ github.head_ref || github.ref_name }} - - name: Comment Storybook preview URL on PR - if: github.event_name == 'pull_request' - uses: actions/github-script@v7 - with: - script: | - const body = `**Vortex Storybook Preview:** ${{ steps.deploy.outputs.deployment-url }}`; - const { data: comments } = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - }); - const existing = comments.find(c => - c.body?.startsWith('**Vortex Storybook Preview:**') - ); - if (existing) { - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: existing.id, - body, - }); - } else { - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body, - }); - } - - preview: - name: Deploy Preview - needs: [build] - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - contents: read - pull-requests: write - deployments: write - environment: - name: preview - url: ${{ steps.deploy.outputs.deployment-url }} - steps: - - uses: actions/download-artifact@v4 - with: - name: vortex-web-dist - path: dist - - name: Deploy to Cloudflare Pages - id: deploy - uses: cloudflare/wrangler-action@v3 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: >- - pages deploy dist/ - --project-name=vortex-web - --branch=${{ github.head_ref || github.ref_name }} - - name: Comment preview URL on PR - if: github.event_name == 'pull_request' - uses: actions/github-script@v7 - with: - script: | - const body = `**Vortex Web Preview:** ${{ steps.deploy.outputs.deployment-url }}`; - const { data: comments } = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - }); - const existing = comments.find(c => - c.body?.startsWith('**Vortex Web Preview:**') - ); - if (existing) { - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: existing.id, - body, - }); - } else { - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body, - }); - } diff --git a/vortex-web/.gitignore b/vortex-web/.gitignore index 9cc815e482e..0fc1c516892 100644 --- a/vortex-web/.gitignore +++ b/vortex-web/.gitignore @@ -1,6 +1,5 @@ node_modules dist storybook-static -src/wasm/pkg/*.js -src/wasm/pkg/*.wasm +src/wasm/pkg *.local diff --git a/vortex-web/src/wasm/pkg/package.json.license b/vortex-web/src/wasm/pkg/package.json.license deleted file mode 100644 index 8e5a7614c30..00000000000 --- a/vortex-web/src/wasm/pkg/package.json.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-License-Identifier: Apache-2.0 -SPDX-FileCopyrightText: Copyright the Vortex contributors diff --git a/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts b/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts index a0737cb5d1a..d6c73598f47 100644 --- a/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts +++ b/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts @@ -1,75 +1,53 @@ -/* tslint:disable */ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors +// +// Hand-maintained type declarations for the WASM bindings. +// Update this file when the public API in crate/src/wasm.rs changes. + /* eslint-disable */ -/** - * A handle to an opened Vortex file, exposing metadata to JavaScript. - */ +/// A handle to an opened Vortex file, exposing metadata to JavaScript. export class VortexFileHandle { private constructor(); + free(): void; + [Symbol.dispose](): void; - /** - * The top-level DType of the file as a string. - */ + + /// The top-level DType of the file as a string. readonly dtype: string; - /** - * The total number of rows in the file. - */ + /// The total number of rows in the file. readonly row_count: bigint; } -/** - * Initialize the WASM module (sets up panic hook for better error messages). - */ +/// Initialize the WASM module (sets up panic hook for better error messages). export function init(): void; -/** - * Open a Vortex file from raw bytes and return a handle for exploration. - * - * Call this from JavaScript after reading a `.vortex` file via drag-and-drop. - */ +/// Open a Vortex file from raw bytes and return a handle for exploration. export function open_vortex_file(data: Uint8Array): VortexFileHandle; -export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; +export type InitInput = + | RequestInfo + | URL + | Response + | BufferSource + | WebAssembly.Module; export interface InitOutput { readonly memory: WebAssembly.Memory; - readonly init: () => void; - readonly open_vortex_file: (a: number, b: number) => [number, number, number]; - readonly __wbg_vortexfilehandle_free: (a: number, b: number) => void; - readonly vortexfilehandle_row_count: (a: number) => bigint; - readonly vortexfilehandle_dtype: (a: number) => [number, number]; - readonly wasm_bindgen__closure__destroy__h315b7af3ad8e2911: (a: number, b: number) => void; - readonly wasm_bindgen__convert__closures_____invoke__hd9aaad206556e4f9: (a: number, b: number, c: any) => [number, number]; - readonly wasm_bindgen__convert__closures_____invoke__hbcb1741f2446bbd2: (a: number, b: number) => number; - readonly __wbindgen_exn_store: (a: number) => void; - readonly __externref_table_alloc: () => number; - readonly __wbindgen_externrefs: WebAssembly.Table; - readonly __wbindgen_free: (a: number, b: number, c: number) => void; - readonly __wbindgen_malloc: (a: number, b: number) => number; - readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; - readonly __externref_table_dealloc: (a: number) => void; - readonly __wbindgen_start: () => void; + + [key: string]: unknown; } export type SyncInitInput = BufferSource | WebAssembly.Module; -/** - * Instantiates the given `module`, which can either be bytes or - * a precompiled `WebAssembly.Module`. - * - * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. - * - * @returns {InitOutput} - */ -export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; +export function initSync( + module: { module: SyncInitInput } | SyncInitInput, +): InitOutput; -/** - * If `module_or_path` is {RequestInfo} or {URL}, makes a request and - * for everything else, calls `WebAssembly.instantiate` directly. - * - * @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. - * - * @returns {Promise} - */ -export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; +export default function __wbg_init( + module_or_path?: + | { module_or_path: InitInput | Promise } + | InitInput + | Promise, +): Promise; diff --git a/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts.license b/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts.license deleted file mode 100644 index 8e5a7614c30..00000000000 --- a/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-License-Identifier: Apache-2.0 -SPDX-FileCopyrightText: Copyright the Vortex contributors diff --git a/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts.license b/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts.license deleted file mode 100644 index 8e5a7614c30..00000000000 --- a/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-License-Identifier: Apache-2.0 -SPDX-FileCopyrightText: Copyright the Vortex contributors From 4975ab242e0b005998d4de818dde8ba1496266bd Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Wed, 25 Mar 2026 13:29:04 -0400 Subject: [PATCH 6/6] Copyright Signed-off-by: Nicholas Gates --- vortex-web/src/wasm/pkg/package.json | 17 ------ vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts | 53 ------------------- .../src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts | 19 ------- 3 files changed, 89 deletions(-) delete mode 100644 vortex-web/src/wasm/pkg/package.json delete mode 100644 vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts delete mode 100644 vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts diff --git a/vortex-web/src/wasm/pkg/package.json b/vortex-web/src/wasm/pkg/package.json deleted file mode 100644 index 6cf192c28a4..00000000000 --- a/vortex-web/src/wasm/pkg/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "vortex-web-wasm", - "type": "module", - "description": "WASM bindings for the Vortex web explorer", - "version": "0.1.0", - "license": "Apache-2.0", - "files": [ - "vortex_web_wasm_bg.wasm", - "vortex_web_wasm.js", - "vortex_web_wasm.d.ts" - ], - "main": "vortex_web_wasm.js", - "types": "vortex_web_wasm.d.ts", - "sideEffects": [ - "./snippets/*" - ] -} \ No newline at end of file diff --git a/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts b/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts deleted file mode 100644 index d6c73598f47..00000000000 --- a/vortex-web/src/wasm/pkg/vortex_web_wasm.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: Copyright the Vortex contributors -// -// Hand-maintained type declarations for the WASM bindings. -// Update this file when the public API in crate/src/wasm.rs changes. - -/* eslint-disable */ - -/// A handle to an opened Vortex file, exposing metadata to JavaScript. -export class VortexFileHandle { - private constructor(); - - free(): void; - - [Symbol.dispose](): void; - - /// The top-level DType of the file as a string. - readonly dtype: string; - /// The total number of rows in the file. - readonly row_count: bigint; -} - -/// Initialize the WASM module (sets up panic hook for better error messages). -export function init(): void; - -/// Open a Vortex file from raw bytes and return a handle for exploration. -export function open_vortex_file(data: Uint8Array): VortexFileHandle; - -export type InitInput = - | RequestInfo - | URL - | Response - | BufferSource - | WebAssembly.Module; - -export interface InitOutput { - readonly memory: WebAssembly.Memory; - - [key: string]: unknown; -} - -export type SyncInitInput = BufferSource | WebAssembly.Module; - -export function initSync( - module: { module: SyncInitInput } | SyncInitInput, -): InitOutput; - -export default function __wbg_init( - module_or_path?: - | { module_or_path: InitInput | Promise } - | InitInput - | Promise, -): Promise; diff --git a/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts b/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts deleted file mode 100644 index 4ed7d60610e..00000000000 --- a/vortex-web/src/wasm/pkg/vortex_web_wasm_bg.wasm.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -export const memory: WebAssembly.Memory; -export const init: () => void; -export const open_vortex_file: (a: number, b: number) => [number, number, number]; -export const __wbg_vortexfilehandle_free: (a: number, b: number) => void; -export const vortexfilehandle_row_count: (a: number) => bigint; -export const vortexfilehandle_dtype: (a: number) => [number, number]; -export const wasm_bindgen__closure__destroy__h315b7af3ad8e2911: (a: number, b: number) => void; -export const wasm_bindgen__convert__closures_____invoke__hd9aaad206556e4f9: (a: number, b: number, c: any) => [number, number]; -export const wasm_bindgen__convert__closures_____invoke__hbcb1741f2446bbd2: (a: number, b: number) => number; -export const __wbindgen_exn_store: (a: number) => void; -export const __externref_table_alloc: () => number; -export const __wbindgen_externrefs: WebAssembly.Table; -export const __wbindgen_free: (a: number, b: number, c: number) => void; -export const __wbindgen_malloc: (a: number, b: number) => number; -export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; -export const __externref_table_dealloc: (a: number) => void; -export const __wbindgen_start: () => void;