itsi 0.2.16 → 0.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Cargo.lock +4 -2
- data/crates/itsi_acme/Cargo.toml +1 -1
- data/crates/itsi_scheduler/Cargo.toml +1 -1
- data/crates/itsi_server/Cargo.toml +3 -1
- data/crates/itsi_server/src/lib.rs +6 -1
- data/crates/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +2 -0
- data/crates/itsi_server/src/ruby_types/itsi_grpc_call.rs +4 -4
- data/crates/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +14 -13
- data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +64 -33
- data/crates/itsi_server/src/ruby_types/itsi_http_response.rs +151 -152
- data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +6 -15
- data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +26 -5
- data/crates/itsi_server/src/ruby_types/itsi_server.rs +1 -1
- data/crates/itsi_server/src/server/binds/listener.rs +45 -7
- data/crates/itsi_server/src/server/frame_stream.rs +142 -0
- data/crates/itsi_server/src/server/http_message_types.rs +142 -9
- data/crates/itsi_server/src/server/io_stream.rs +28 -5
- data/crates/itsi_server/src/server/lifecycle_event.rs +1 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +2 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +8 -10
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +2 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +3 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +54 -56
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +5 -7
- data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +5 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +7 -10
- data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +2 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +1 -2
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +4 -6
- data/crates/itsi_server/src/server/mod.rs +1 -0
- data/crates/itsi_server/src/server/process_worker.rs +3 -4
- data/crates/itsi_server/src/server/serve_strategy/acceptor.rs +16 -12
- data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +87 -31
- data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +158 -142
- data/crates/itsi_server/src/server/signal.rs +37 -9
- data/crates/itsi_server/src/server/thread_worker.rs +84 -69
- data/crates/itsi_server/src/services/itsi_http_service.rs +43 -43
- data/crates/itsi_server/src/services/static_file_server.rs +28 -47
- data/docs/benchmark-dashboard/.gitignore +27 -0
- data/docs/benchmark-dashboard/app/api/benchmarks/route.ts +22 -0
- data/docs/benchmark-dashboard/app/globals.css +94 -0
- data/docs/benchmark-dashboard/app/layout.tsx +20 -0
- data/docs/benchmark-dashboard/app/page.tsx +252 -0
- data/docs/benchmark-dashboard/components/benchmark-dashboard.tsx +1663 -0
- data/docs/benchmark-dashboard/components/theme-provider.tsx +11 -0
- data/docs/benchmark-dashboard/components/ui/accordion.tsx +58 -0
- data/docs/benchmark-dashboard/components/ui/alert-dialog.tsx +141 -0
- data/docs/benchmark-dashboard/components/ui/alert.tsx +59 -0
- data/docs/benchmark-dashboard/components/ui/aspect-ratio.tsx +7 -0
- data/docs/benchmark-dashboard/components/ui/avatar.tsx +50 -0
- data/docs/benchmark-dashboard/components/ui/badge.tsx +36 -0
- data/docs/benchmark-dashboard/components/ui/breadcrumb.tsx +115 -0
- data/docs/benchmark-dashboard/components/ui/button.tsx +56 -0
- data/docs/benchmark-dashboard/components/ui/calendar.tsx +66 -0
- data/docs/benchmark-dashboard/components/ui/card.tsx +79 -0
- data/docs/benchmark-dashboard/components/ui/carousel.tsx +262 -0
- data/docs/benchmark-dashboard/components/ui/chart.tsx +365 -0
- data/docs/benchmark-dashboard/components/ui/checkbox.tsx +30 -0
- data/docs/benchmark-dashboard/components/ui/collapsible.tsx +11 -0
- data/docs/benchmark-dashboard/components/ui/command.tsx +153 -0
- data/docs/benchmark-dashboard/components/ui/context-menu.tsx +200 -0
- data/docs/benchmark-dashboard/components/ui/dialog.tsx +122 -0
- data/docs/benchmark-dashboard/components/ui/drawer.tsx +118 -0
- data/docs/benchmark-dashboard/components/ui/dropdown-menu.tsx +200 -0
- data/docs/benchmark-dashboard/components/ui/form.tsx +178 -0
- data/docs/benchmark-dashboard/components/ui/hover-card.tsx +29 -0
- data/docs/benchmark-dashboard/components/ui/input-otp.tsx +71 -0
- data/docs/benchmark-dashboard/components/ui/input.tsx +22 -0
- data/docs/benchmark-dashboard/components/ui/label.tsx +26 -0
- data/docs/benchmark-dashboard/components/ui/loading-spinner.tsx +12 -0
- data/docs/benchmark-dashboard/components/ui/menubar.tsx +236 -0
- data/docs/benchmark-dashboard/components/ui/navigation-menu.tsx +128 -0
- data/docs/benchmark-dashboard/components/ui/pagination.tsx +117 -0
- data/docs/benchmark-dashboard/components/ui/popover.tsx +31 -0
- data/docs/benchmark-dashboard/components/ui/progress.tsx +28 -0
- data/docs/benchmark-dashboard/components/ui/radio-group.tsx +44 -0
- data/docs/benchmark-dashboard/components/ui/resizable.tsx +45 -0
- data/docs/benchmark-dashboard/components/ui/scroll-area.tsx +48 -0
- data/docs/benchmark-dashboard/components/ui/select.tsx +160 -0
- data/docs/benchmark-dashboard/components/ui/separator.tsx +31 -0
- data/docs/benchmark-dashboard/components/ui/sheet.tsx +140 -0
- data/docs/benchmark-dashboard/components/ui/sidebar.tsx +763 -0
- data/docs/benchmark-dashboard/components/ui/skeleton.tsx +15 -0
- data/docs/benchmark-dashboard/components/ui/slider.tsx +28 -0
- data/docs/benchmark-dashboard/components/ui/sonner.tsx +31 -0
- data/docs/benchmark-dashboard/components/ui/switch.tsx +29 -0
- data/docs/benchmark-dashboard/components/ui/table.tsx +117 -0
- data/docs/benchmark-dashboard/components/ui/tabs.tsx +55 -0
- data/docs/benchmark-dashboard/components/ui/textarea.tsx +22 -0
- data/docs/benchmark-dashboard/components/ui/toast.tsx +129 -0
- data/docs/benchmark-dashboard/components/ui/toaster.tsx +35 -0
- data/docs/benchmark-dashboard/components/ui/toggle-group.tsx +61 -0
- data/docs/benchmark-dashboard/components/ui/toggle.tsx +45 -0
- data/docs/benchmark-dashboard/components/ui/tooltip.tsx +30 -0
- data/docs/benchmark-dashboard/components/ui/use-mobile.tsx +19 -0
- data/docs/benchmark-dashboard/components/ui/use-toast.ts +194 -0
- data/docs/benchmark-dashboard/components.json +21 -0
- data/docs/benchmark-dashboard/dist/benchmark-dashboard.css +1 -0
- data/docs/benchmark-dashboard/dist/benchmark-dashboard.iife.js +211 -0
- data/docs/benchmark-dashboard/dist/placeholder-logo.png +0 -0
- data/docs/benchmark-dashboard/dist/placeholder-logo.svg +1 -0
- data/docs/benchmark-dashboard/dist/placeholder-user.jpg +0 -0
- data/docs/benchmark-dashboard/dist/placeholder.jpg +0 -0
- data/docs/benchmark-dashboard/dist/placeholder.svg +1 -0
- data/docs/benchmark-dashboard/embed.tsx +13 -0
- data/docs/benchmark-dashboard/hooks/use-mobile.tsx +19 -0
- data/docs/benchmark-dashboard/hooks/use-toast.ts +194 -0
- data/docs/benchmark-dashboard/lib/benchmark-utils.ts +54 -0
- data/docs/benchmark-dashboard/lib/utils.ts +6 -0
- data/docs/benchmark-dashboard/next.config.mjs +14 -0
- data/docs/benchmark-dashboard/package-lock.json +5859 -0
- data/docs/benchmark-dashboard/package.json +72 -0
- data/docs/benchmark-dashboard/pnpm-lock.yaml +5 -0
- data/docs/benchmark-dashboard/postcss.config.mjs +8 -0
- data/docs/benchmark-dashboard/styles/globals.css +94 -0
- data/docs/benchmark-dashboard/tailwind.config.ts +96 -0
- data/docs/benchmark-dashboard/tsconfig.json +27 -0
- data/docs/benchmark-dashboard/vite.config.ts +24 -0
- data/docs/build.rb +52 -0
- data/docs/content/benchmarks/index.md +96 -0
- data/docs/content/getting_started/_index.md +76 -46
- data/docs/hugo.yaml +3 -0
- data/docs/static/results.json +1 -0
- data/docs/static/scripts/benchmark-dashboard.iife.js +211 -0
- data/docs/static/styles/benchmark-dashboard.css +1 -0
- data/gems/scheduler/Cargo.lock +1 -1
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/server/Cargo.lock +3 -1
- data/gems/server/exe/itsi +6 -1
- data/gems/server/lib/itsi/http_request.rb +31 -39
- data/gems/server/lib/itsi/http_response.rb +5 -0
- data/gems/server/lib/itsi/rack_env_pool.rb +59 -0
- data/gems/server/lib/itsi/server/config/dsl.rb +5 -4
- data/gems/server/lib/itsi/server/config/middleware/proxy.rb +1 -1
- data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +2 -2
- data/gems/server/lib/itsi/server/config/options/auto_reload_config.rb +6 -2
- data/gems/server/lib/itsi/server/config/options/include.rb +5 -2
- data/gems/server/lib/itsi/server/config/options/pipeline_flush.md +16 -0
- data/gems/server/lib/itsi/server/config/options/pipeline_flush.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/writev.md +25 -0
- data/gems/server/lib/itsi/server/config/options/writev.rb +19 -0
- data/gems/server/lib/itsi/server/config.rb +21 -8
- data/gems/server/lib/itsi/server/default_config/Itsi.rb +1 -4
- data/gems/server/lib/itsi/server/grpc/grpc_call.rb +2 -0
- data/gems/server/lib/itsi/server/grpc/grpc_interface.rb +2 -2
- data/gems/server/lib/itsi/server/rack/handler/itsi.rb +3 -1
- data/gems/server/lib/itsi/server/rack_interface.rb +17 -12
- data/gems/server/lib/itsi/server/scheduler_interface.rb +2 -0
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/lib/itsi/server.rb +1 -0
- data/gems/server/lib/ruby_lsp/itsi/addon.rb +12 -13
- data/gems/server/test/helpers/test_helper.rb +12 -13
- data/gems/server/test/middleware/grpc/grpc.rb +13 -14
- data/gems/server/test/middleware/grpc/test_service_impl.rb +3 -3
- data/gems/server/test/middleware/proxy.rb +262 -268
- data/lib/itsi/version.rb +1 -1
- metadata +96 -6
- data/tasks.txt +0 -28
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="215" height="48" fill="none"><path fill="#000" d="M57.588 9.6h6L73.828 38h-5.2l-2.36-6.88h-11.36L52.548 38h-5.2l10.24-28.4Zm7.16 17.16-4.16-12.16-4.16 12.16h8.32Zm23.694-2.24c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.486-7.72.12 3.4c.534-1.227 1.307-2.173 2.32-2.84 1.04-.693 2.267-1.04 3.68-1.04 1.494 0 2.76.387 3.8 1.16 1.067.747 1.827 1.813 2.28 3.2.507-1.44 1.294-2.52 2.36-3.24 1.094-.747 2.414-1.12 3.96-1.12 1.414 0 2.64.307 3.68.92s1.84 1.52 2.4 2.72c.56 1.2.84 2.667.84 4.4V38h-4.96V25.92c0-1.813-.293-3.187-.88-4.12-.56-.96-1.413-1.44-2.56-1.44-.906 0-1.68.213-2.32.64-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.84-.48 3.04V38h-4.56V25.92c0-1.2-.133-2.213-.4-3.04-.24-.827-.626-1.453-1.16-1.88-.506-.427-1.133-.64-1.88-.64-.906 0-1.68.227-2.32.68-.64.427-1.133 1.053-1.48 1.88-.32.827-.48 1.827-.48 3V38h-4.96V16.8h4.48Zm26.723 10.6c0-2.24.427-4.187 1.28-5.84.854-1.68 2.067-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.84 0 3.494.413 4.96 1.24 1.467.827 2.64 2.08 3.52 3.76.88 1.653 1.347 3.693 1.4 6.12v1.32h-15.08c.107 1.813.614 3.227 1.52 4.24.907.987 2.134 1.48 3.68 1.48.987 0 1.88-.253 2.68-.76a4.803 4.803 0 0 0 1.84-2.2l5.08.36c-.64 2.027-1.84 3.64-3.6 4.84-1.733 1.173-3.733 1.76-6 1.76-2.08 0-3.906-.453-5.48-1.36-1.573-.907-2.786-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84Zm15.16-2.04c-.213-1.733-.76-3.013-1.64-3.84-.853-.827-1.893-1.24-3.12-1.24-1.44 0-2.6.453-3.48 1.36-.88.88-1.44 2.12-1.68 3.72h9.92ZM163.139 9.6V38h-5.04V9.6h5.04Zm8.322 7.2.24 5.88-.64-.36c.32-2.053 1.094-3.56 2.32-4.52 1.254-.987 2.787-1.48 4.6-1.48 2.32 0 4.107.733 5.36 2.2 1.254 1.44 1.88 3.387 1.88 5.84V38h-4.96V25.92c0-1.253-.12-2.28-.36-3.08-.24-.8-.64-1.413-1.2-1.84-.533-.427-1.253-.64-2.16-.64-1.44 0-2.573.48-3.4 1.44-.8.933-1.2 2.307-1.2 4.12V38h-4.96V16.8h4.48Zm30.003 7.72c-.186-1.307-.706-2.32-1.56-3.04-.853-.72-1.866-1.08-3.04-1.08-1.68 0-2.986.613-3.92 1.84-.906 1.227-1.36 2.947-1.36 5.16s.454 3.933 1.36 5.16c.934 1.227 2.24 1.84 3.92 1.84 1.254 0 2.307-.373 3.16-1.12.854-.773 1.387-1.867 1.6-3.28l5.12.24c-.186 1.68-.733 3.147-1.64 4.4-.906 1.227-2.08 2.173-3.52 2.84-1.413.667-2.986 1-4.72 1-2.08 0-3.906-.453-5.48-1.36-1.546-.907-2.76-2.2-3.64-3.88-.853-1.68-1.28-3.627-1.28-5.84 0-2.24.427-4.187 1.28-5.84.88-1.68 2.094-2.973 3.64-3.88 1.574-.907 3.4-1.36 5.48-1.36 1.68 0 3.227.32 4.64.96 1.414.64 2.56 1.56 3.44 2.76.907 1.2 1.454 2.6 1.64 4.2l-5.12.28Zm11.443 8.16V38h-5.6v-5.32h5.6Z"/><path fill="#171717" fill-rule="evenodd" d="m7.839 40.783 16.03-28.054L20 6 0 40.783h7.839Zm8.214 0H40L27.99 19.894l-4.02 7.032 3.976 6.914H20.02l-3.967 6.943Z" clip-rule="evenodd"/></svg>
|
Binary file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1200" fill="none"><rect width="1200" height="1200" fill="#EAEAEA" rx="3"/><g opacity=".5"><g opacity=".5"><path fill="#FAFAFA" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 736.5c-75.454 0-136.621-61.167-136.621-136.62 0-75.454 61.167-136.621 136.621-136.621 75.453 0 136.62 61.167 136.62 136.621 0 75.453-61.167 136.62-136.62 136.62Z"/></g><path stroke="url(#a)" stroke-width="2.418" d="M0-1.209h553.581" transform="scale(1 -1) rotate(45 1163.11 91.165)"/><path stroke="url(#b)" stroke-width="2.418" d="M404.846 598.671h391.726"/><path stroke="url(#c)" stroke-width="2.418" d="M599.5 795.742V404.017"/><path stroke="url(#d)" stroke-width="2.418" d="m795.717 796.597-391.441-391.44"/><path fill="#fff" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/><g clip-path="url(#e)"><path fill="#666" fill-rule="evenodd" d="M616.426 586.58h-31.434v16.176l3.553-3.554.531-.531h9.068l.074-.074 8.463-8.463h2.565l7.18 7.181V586.58Zm-15.715 14.654 3.698 3.699 1.283 1.282-2.565 2.565-1.282-1.283-5.2-5.199h-6.066l-5.514 5.514-.073.073v2.876a2.418 2.418 0 0 0 2.418 2.418h26.598a2.418 2.418 0 0 0 2.418-2.418v-8.317l-8.463-8.463-7.181 7.181-.071.072Zm-19.347 5.442v4.085a6.045 6.045 0 0 0 6.046 6.045h26.598a6.044 6.044 0 0 0 6.045-6.045v-7.108l1.356-1.355-1.282-1.283-.074-.073v-17.989h-38.689v23.43l-.146.146.146.147Z" clip-rule="evenodd"/></g><path stroke="#C9C9C9" stroke-width="2.418" d="M600.709 656.704c-31.384 0-56.825-25.441-56.825-56.824 0-31.384 25.441-56.825 56.825-56.825 31.383 0 56.824 25.441 56.824 56.825 0 31.383-25.441 56.824-56.824 56.824Z"/></g><defs><linearGradient id="a" x1="554.061" x2="-.48" y1=".083" y2=".087" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="b" x1="796.912" x2="404.507" y1="599.963" y2="599.965" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="c" x1="600.792" x2="600.794" y1="403.677" y2="796.082" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><linearGradient id="d" x1="404.85" x2="796.972" y1="403.903" y2="796.02" gradientUnits="userSpaceOnUse"><stop stop-color="#C9C9C9" stop-opacity="0"/><stop offset=".208" stop-color="#C9C9C9"/><stop offset=".792" stop-color="#C9C9C9"/><stop offset="1" stop-color="#C9C9C9" stop-opacity="0"/></linearGradient><clipPath id="e"><path fill="#fff" d="M581.364 580.535h38.689v38.689h-38.689z"/></clipPath></defs></svg>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import ReactDOM from "react-dom/client";
|
3
|
+
import { BenchmarkDashboard } from "@/components/benchmark-dashboard";
|
4
|
+
import "@/styles/globals.css";
|
5
|
+
|
6
|
+
const root = document.getElementById("root");
|
7
|
+
if (root) {
|
8
|
+
fetch("/results.json")
|
9
|
+
.then((res) => res.json())
|
10
|
+
.then((data) => {
|
11
|
+
ReactDOM.createRoot(root).render(<BenchmarkDashboard data={data} />);
|
12
|
+
});
|
13
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import * as React from "react"
|
2
|
+
|
3
|
+
const MOBILE_BREAKPOINT = 768
|
4
|
+
|
5
|
+
export function useIsMobile() {
|
6
|
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
|
7
|
+
|
8
|
+
React.useEffect(() => {
|
9
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
|
10
|
+
const onChange = () => {
|
11
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
12
|
+
}
|
13
|
+
mql.addEventListener("change", onChange)
|
14
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
15
|
+
return () => mql.removeEventListener("change", onChange)
|
16
|
+
}, [])
|
17
|
+
|
18
|
+
return !!isMobile
|
19
|
+
}
|
@@ -0,0 +1,194 @@
|
|
1
|
+
"use client"
|
2
|
+
|
3
|
+
// Inspired by react-hot-toast library
|
4
|
+
import * as React from "react"
|
5
|
+
|
6
|
+
import type {
|
7
|
+
ToastActionElement,
|
8
|
+
ToastProps,
|
9
|
+
} from "@/components/ui/toast"
|
10
|
+
|
11
|
+
const TOAST_LIMIT = 1
|
12
|
+
const TOAST_REMOVE_DELAY = 1000000
|
13
|
+
|
14
|
+
type ToasterToast = ToastProps & {
|
15
|
+
id: string
|
16
|
+
title?: React.ReactNode
|
17
|
+
description?: React.ReactNode
|
18
|
+
action?: ToastActionElement
|
19
|
+
}
|
20
|
+
|
21
|
+
const actionTypes = {
|
22
|
+
ADD_TOAST: "ADD_TOAST",
|
23
|
+
UPDATE_TOAST: "UPDATE_TOAST",
|
24
|
+
DISMISS_TOAST: "DISMISS_TOAST",
|
25
|
+
REMOVE_TOAST: "REMOVE_TOAST",
|
26
|
+
} as const
|
27
|
+
|
28
|
+
let count = 0
|
29
|
+
|
30
|
+
function genId() {
|
31
|
+
count = (count + 1) % Number.MAX_SAFE_INTEGER
|
32
|
+
return count.toString()
|
33
|
+
}
|
34
|
+
|
35
|
+
type ActionType = typeof actionTypes
|
36
|
+
|
37
|
+
type Action =
|
38
|
+
| {
|
39
|
+
type: ActionType["ADD_TOAST"]
|
40
|
+
toast: ToasterToast
|
41
|
+
}
|
42
|
+
| {
|
43
|
+
type: ActionType["UPDATE_TOAST"]
|
44
|
+
toast: Partial<ToasterToast>
|
45
|
+
}
|
46
|
+
| {
|
47
|
+
type: ActionType["DISMISS_TOAST"]
|
48
|
+
toastId?: ToasterToast["id"]
|
49
|
+
}
|
50
|
+
| {
|
51
|
+
type: ActionType["REMOVE_TOAST"]
|
52
|
+
toastId?: ToasterToast["id"]
|
53
|
+
}
|
54
|
+
|
55
|
+
interface State {
|
56
|
+
toasts: ToasterToast[]
|
57
|
+
}
|
58
|
+
|
59
|
+
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
|
60
|
+
|
61
|
+
const addToRemoveQueue = (toastId: string) => {
|
62
|
+
if (toastTimeouts.has(toastId)) {
|
63
|
+
return
|
64
|
+
}
|
65
|
+
|
66
|
+
const timeout = setTimeout(() => {
|
67
|
+
toastTimeouts.delete(toastId)
|
68
|
+
dispatch({
|
69
|
+
type: "REMOVE_TOAST",
|
70
|
+
toastId: toastId,
|
71
|
+
})
|
72
|
+
}, TOAST_REMOVE_DELAY)
|
73
|
+
|
74
|
+
toastTimeouts.set(toastId, timeout)
|
75
|
+
}
|
76
|
+
|
77
|
+
export const reducer = (state: State, action: Action): State => {
|
78
|
+
switch (action.type) {
|
79
|
+
case "ADD_TOAST":
|
80
|
+
return {
|
81
|
+
...state,
|
82
|
+
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
|
83
|
+
}
|
84
|
+
|
85
|
+
case "UPDATE_TOAST":
|
86
|
+
return {
|
87
|
+
...state,
|
88
|
+
toasts: state.toasts.map((t) =>
|
89
|
+
t.id === action.toast.id ? { ...t, ...action.toast } : t
|
90
|
+
),
|
91
|
+
}
|
92
|
+
|
93
|
+
case "DISMISS_TOAST": {
|
94
|
+
const { toastId } = action
|
95
|
+
|
96
|
+
// ! Side effects ! - This could be extracted into a dismissToast() action,
|
97
|
+
// but I'll keep it here for simplicity
|
98
|
+
if (toastId) {
|
99
|
+
addToRemoveQueue(toastId)
|
100
|
+
} else {
|
101
|
+
state.toasts.forEach((toast) => {
|
102
|
+
addToRemoveQueue(toast.id)
|
103
|
+
})
|
104
|
+
}
|
105
|
+
|
106
|
+
return {
|
107
|
+
...state,
|
108
|
+
toasts: state.toasts.map((t) =>
|
109
|
+
t.id === toastId || toastId === undefined
|
110
|
+
? {
|
111
|
+
...t,
|
112
|
+
open: false,
|
113
|
+
}
|
114
|
+
: t
|
115
|
+
),
|
116
|
+
}
|
117
|
+
}
|
118
|
+
case "REMOVE_TOAST":
|
119
|
+
if (action.toastId === undefined) {
|
120
|
+
return {
|
121
|
+
...state,
|
122
|
+
toasts: [],
|
123
|
+
}
|
124
|
+
}
|
125
|
+
return {
|
126
|
+
...state,
|
127
|
+
toasts: state.toasts.filter((t) => t.id !== action.toastId),
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
const listeners: Array<(state: State) => void> = []
|
133
|
+
|
134
|
+
let memoryState: State = { toasts: [] }
|
135
|
+
|
136
|
+
function dispatch(action: Action) {
|
137
|
+
memoryState = reducer(memoryState, action)
|
138
|
+
listeners.forEach((listener) => {
|
139
|
+
listener(memoryState)
|
140
|
+
})
|
141
|
+
}
|
142
|
+
|
143
|
+
type Toast = Omit<ToasterToast, "id">
|
144
|
+
|
145
|
+
function toast({ ...props }: Toast) {
|
146
|
+
const id = genId()
|
147
|
+
|
148
|
+
const update = (props: ToasterToast) =>
|
149
|
+
dispatch({
|
150
|
+
type: "UPDATE_TOAST",
|
151
|
+
toast: { ...props, id },
|
152
|
+
})
|
153
|
+
const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
|
154
|
+
|
155
|
+
dispatch({
|
156
|
+
type: "ADD_TOAST",
|
157
|
+
toast: {
|
158
|
+
...props,
|
159
|
+
id,
|
160
|
+
open: true,
|
161
|
+
onOpenChange: (open) => {
|
162
|
+
if (!open) dismiss()
|
163
|
+
},
|
164
|
+
},
|
165
|
+
})
|
166
|
+
|
167
|
+
return {
|
168
|
+
id: id,
|
169
|
+
dismiss,
|
170
|
+
update,
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
function useToast() {
|
175
|
+
const [state, setState] = React.useState<State>(memoryState)
|
176
|
+
|
177
|
+
React.useEffect(() => {
|
178
|
+
listeners.push(setState)
|
179
|
+
return () => {
|
180
|
+
const index = listeners.indexOf(setState)
|
181
|
+
if (index > -1) {
|
182
|
+
listeners.splice(index, 1)
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}, [state])
|
186
|
+
|
187
|
+
return {
|
188
|
+
...state,
|
189
|
+
toast,
|
190
|
+
dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
export { useToast, toast }
|
@@ -0,0 +1,54 @@
|
|
1
|
+
// This file would contain utility functions for processing benchmark data
|
2
|
+
// For example, parsing JSON files, aggregating results, etc.
|
3
|
+
|
4
|
+
export type BenchmarkResult = {
|
5
|
+
server: string
|
6
|
+
test_case: string
|
7
|
+
threads: number
|
8
|
+
workers: number
|
9
|
+
http2: boolean
|
10
|
+
concurrency: number
|
11
|
+
rss_mb?: number
|
12
|
+
results: {
|
13
|
+
successRate: number
|
14
|
+
total: number
|
15
|
+
slowest: number
|
16
|
+
fastest: number
|
17
|
+
average: number
|
18
|
+
requestsPerSec: number
|
19
|
+
totalData: number
|
20
|
+
sizePerRequest: number
|
21
|
+
sizePerSec: number
|
22
|
+
errorDistribution: Record<string, number>
|
23
|
+
p95_latency: number
|
24
|
+
}
|
25
|
+
timestamp?: string
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
* In a real implementation, this function would:
|
30
|
+
* 1. Scan the directory structure
|
31
|
+
* 2. Read and parse the JSON files
|
32
|
+
* 3. Return the aggregated data
|
33
|
+
*/
|
34
|
+
export async function loadBenchmarkData(): Promise<BenchmarkResult[]> {
|
35
|
+
// This is a placeholder for the actual implementation
|
36
|
+
return []
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Calculate summary statistics for benchmark results
|
41
|
+
*/
|
42
|
+
export function calculateStats(data: BenchmarkResult[], metric: keyof BenchmarkResult["results"]) {
|
43
|
+
if (data.length === 0) return null
|
44
|
+
|
45
|
+
const values = data.map((item) => item.results[metric] as number)
|
46
|
+
|
47
|
+
return {
|
48
|
+
count: values.length,
|
49
|
+
min: Math.min(...values),
|
50
|
+
max: Math.max(...values),
|
51
|
+
avg: values.reduce((sum, val) => sum + val, 0) / values.length,
|
52
|
+
median: values.sort((a, b) => a - b)[Math.floor(values.length / 2)],
|
53
|
+
}
|
54
|
+
}
|