From 40b8aeccea6e5ae7f3da75d20da17d9311bcd663 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 12 Aug 2024 12:15:37 +0100 Subject: [PATCH 01/33] WIP on using react-window-splitter --- .../app/components/primitives/Resizable.tsx | 19 +- .../route.tsx | 16 +- apps/webapp/package.json | 1 + pnpm-lock.yaml | 1419 +++++++++++++++++ 4 files changed, 1432 insertions(+), 23 deletions(-) diff --git a/apps/webapp/app/components/primitives/Resizable.tsx b/apps/webapp/app/components/primitives/Resizable.tsx index 776b210f3..f06e3bd6e 100644 --- a/apps/webapp/app/components/primitives/Resizable.tsx +++ b/apps/webapp/app/components/primitives/Resizable.tsx @@ -1,28 +1,25 @@ "use client"; -import * as ResizablePrimitive from "react-resizable-panels"; +import { PanelGroup, Panel, PanelResizer } from "react-window-splitter"; import { cn } from "~/utils/cn"; -const ResizablePanelGroup = ({ - className, - ...props -}: React.ComponentProps) => ( - ) => ( + ); -const ResizablePanel = ResizablePrimitive.Panel; +const ResizablePanel = Panel; const ResizableHandle = ({ - withHandle, + withHandle = true, className, ...props -}: React.ComponentProps & { +}: React.ComponentProps & { withHandle?: boolean; }) => ( - div]:rotate-90", className @@ -37,7 +34,7 @@ const ResizableHandle = ({ ))} )} - + ); export { ResizableHandle, ResizablePanel, ResizablePanelGroup }; diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx index 5c1641764..09f6cf525 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx @@ -254,16 +254,8 @@ function TraceView({ run, trace, maximumLiveReloadingSetting, resizeSettings }: return (
- { - if (layout.length !== 2) return; - if (!selectedSpanId) return; - setResizableRunSettings(document, layout); - }} - > - + + - + {selectedSpanId && ( - + = 12'} @@ -12590,6 +13146,16 @@ packages: react: 18.2.0 dev: false + /@react-aria/ssr@3.9.5(react@18.2.0): + resolution: {integrity: sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==} + engines: {node: '>= 12'} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/switch@3.6.0(react@18.2.0): resolution: {integrity: sha512-YNWc5fGLNXE4XlmDAKyqAdllRiClGR7ki4KGFY7nL+xR5jxzjCGU3S3ToMK5Op3QSMGZLxY/aYmC4O+MvcoADQ==} peerDependencies: @@ -12602,6 +13168,19 @@ packages: react: 18.2.0 dev: false + /@react-aria/switch@3.6.6(react@18.2.0): + resolution: {integrity: sha512-+dZOX1utODlx5dC90DtwnXd9nvln9HxMffBj/gmMT1/cD/RmXfjvymfjTsTMwvHhqCew9yfpvod0ZWwj3BkLGw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/toggle': 3.10.6(react@18.2.0) + '@react-stately/toggle': 3.7.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/switch': 3.5.5(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/table@3.13.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-AzmETpyxwNqISTzwHJPs85x9gujG40IIsSOBUdp49oKhB85RbPLvMwhadp4wCVAoHw3erOC/TJxHtVc7o2K1LA==} peerDependencies: @@ -12628,6 +13207,31 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/table@3.15.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-jVDLxp6Y/9M6y45c1I6u6msJ9dBg2I7Cu/FlSaK6HthTpN23UXuGw1oWuAjbfqi31nVXHWBwjCZkGKTdMjLf5A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.1(react@18.2.0) + '@react-aria/grid': 3.10.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/i18n': 3.12.1(react@18.2.0) + '@react-aria/interactions': 3.22.1(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/utils': 3.25.1(react@18.2.0) + '@react-aria/visually-hidden': 3.8.14(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/flags': 3.0.3 + '@react-stately/table': 3.12.1(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/table': 3.10.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/tabs@3.8.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Plw0K/5Qv35vYq7pHZFfQB2BF5OClFx4Abzo9hLVx4oMy3qb7i5lxmLBVbt81yPX/MdjYeP4zO1EHGBl4zMRhA==} peerDependencies: @@ -12646,6 +13250,24 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/tabs@3.9.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-J1KOCdx4eSyMMeNCvO8BIz8E8xez12B+cYbM4BbJzWlcfMboGYUnM0lvI8QSpFPa/H9LkAhp7BJnl9IZeIBzoA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.1(react@18.2.0) + '@react-aria/i18n': 3.12.1(react@18.2.0) + '@react-aria/selection': 3.19.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.1(react@18.2.0) + '@react-stately/tabs': 3.6.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/tabs': 3.3.9(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/tag@3.3.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-w7d8sVZqxTo8VFfeg2ixLp5kawtrcguGznVY4mt5aE6K8LMJOeNVDqNNfolfyia80VjOWjeX+RpVdVJRdrv/GQ==} peerDependencies: @@ -12666,6 +13288,26 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/tag@3.4.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-BqXKazX9YHvt6+qzGTu770V0FqGVefzz03hmnV2IVb+zYchXBv3WYbWVy46s/D5zTePOAXdpitQHxqy5rh+hgw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/gridlist': 3.9.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/i18n': 3.12.1(react@18.2.0) + '@react-aria/interactions': 3.22.1(react@18.2.0) + '@react-aria/label': 3.7.10(react@18.2.0) + '@react-aria/selection': 3.19.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.1(react@18.2.0) + '@react-stately/list': 3.10.7(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/textfield@3.14.1(react@18.2.0): resolution: {integrity: sha512-UMepuYtDdCgrUF4dMphNxrUm23xOmR54aZD1pbp9cJyfioVkJN35BTXZVkD0D07gHLn4RhxKIZxBortQQrLB9g==} peerDependencies: @@ -12683,6 +13325,23 @@ packages: react: 18.2.0 dev: false + /@react-aria/textfield@3.14.7(react@18.2.0): + resolution: {integrity: sha512-1cWCG6vkjlwJuRTXKbKl9P0Q/0Li5pnMafZqDDWfDOlkS5dFGxYG6QFfoaYp7N6XMoNkXiculnCssfrQ+8hWgA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.1(react@18.2.0) + '@react-aria/form': 3.0.7(react@18.2.0) + '@react-aria/label': 3.7.10(react@18.2.0) + '@react-aria/utils': 3.25.1(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/textfield': 3.9.5(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/toggle@3.10.0(react@18.2.0): resolution: {integrity: sha512-6cUf4V9TuG2J7AvXUdU/GspEPFCubUOID3mrselSe563RViy+mMZk0vUEOdyoNanDcEXl58W4dE3SGWxFn71vg==} peerDependencies: @@ -12697,6 +13356,21 @@ packages: react: 18.2.0 dev: false + /@react-aria/toggle@3.10.6(react@18.2.0): + resolution: {integrity: sha512-AGlbtB1b8grrtjbiW5Au0LKYzxR83RHbHhaUkFwajyYRGyuEzr3Y03OiveoPB+DayA8Gz3H1ZVmW++8JZQOWHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.1(react@18.2.0) + '@react-aria/interactions': 3.22.1(react@18.2.0) + '@react-aria/utils': 3.25.1(react@18.2.0) + '@react-stately/toggle': 3.7.6(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/tooltip@3.7.0(react@18.2.0): resolution: {integrity: sha512-+u9Sftkfe09IDyPEnbbreFKS50vh9X/WTa7n1u2y3PenI9VreLpUR6czyzda4BlvQ95e9jQz1cVxUjxTNaZmBw==} peerDependencies: @@ -12712,6 +13386,21 @@ packages: react: 18.2.0 dev: false + /@react-aria/tooltip@3.7.6(react@18.2.0): + resolution: {integrity: sha512-JvRAMTcMju/KBOtISjVKKtIDzG3J1r6xK+mZTvu6ArM7DdeMBM5A8Lwk0bJ8dhr+YybiM9rR3hoZv3/E7IIYVw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.1(react@18.2.0) + '@react-aria/interactions': 3.22.1(react@18.2.0) + '@react-aria/utils': 3.25.1(react@18.2.0) + '@react-stately/tooltip': 3.4.11(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/tooltip': 3.4.11(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/utils@3.23.0(react@18.2.0): resolution: {integrity: sha512-fJA63/VU4iQNT8WUvrmll3kvToqMurD69CcgVmbQ56V7ZbvlzFi44E7BpnoaofScYLLtFWRjVdaHsohT6O/big==} peerDependencies: @@ -12725,6 +13414,31 @@ packages: react: 18.2.0 dev: false + /@react-aria/utils@3.25.1(react@18.2.0): + resolution: {integrity: sha512-5Uj864e7T5+yj78ZfLnfHqmypLiqW2mN+nsdslog2z5ssunTqjolVeM15ootXskjISlZ7MojLpq97kIC4nlnAw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + clsx: 2.1.0 + react: 18.2.0 + dev: false + + /@react-aria/visually-hidden@3.8.14(react@18.2.0): + resolution: {integrity: sha512-DV3yagbAgO4ywQTq6D/AxcIaTC8c77r/SxlIMhQBMQ6vScJWTCh6zFG55wmLe3NKqvRrowv1OstlmYfZQ4v/XA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/interactions': 3.22.1(react@18.2.0) + '@react-aria/utils': 3.25.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/visually-hidden@3.8.8(react@18.2.0): resolution: {integrity: sha512-Cn2PYKD4ijGDtF0+dvsh8qa4y7KTNAlkTG6h20r8Q+6UTyRNmtE2/26QEaApRF8CBiNy9/BZC/ZC4FK2OjvCoA==} peerDependencies: @@ -13198,6 +13912,10 @@ packages: react: 18.2.0 dev: false + /@react-spring/rafz@9.7.4: + resolution: {integrity: sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==} + dev: false + /@react-stately/calendar@3.4.3(react@18.2.0): resolution: {integrity: sha512-OrEcdskszDjnjVnFuSiDC2PVBJ6lWMCJROD5s6W1LUehUtBp8LX9wPavAGHV43LbhN9ldj560sxaQ4WCddrRCA==} peerDependencies: @@ -13211,6 +13929,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/calendar@3.5.3(react@18.2.0): + resolution: {integrity: sha512-SRwsgszyc9FNcvkjqBe81e/tnjKpRqH+yTYpG0uI9NR1HfyddmhR3Y7QilWPcqQkq4SQb7pL68SkTPH2dX2dng==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/calendar': 3.4.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/checkbox@3.6.1(react@18.2.0): resolution: {integrity: sha512-rOjFeVBy32edYwhKiHj3ZLdLeO+xZ2fnBwxnOBjcygnw4Neygm8FJH/dB1J0hdYYR349yby86ED2x0wRc84zPw==} peerDependencies: @@ -13224,6 +13955,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/checkbox@3.6.7(react@18.2.0): + resolution: {integrity: sha512-ZOaBNXXazpwkuKj5hk6FtGbXO7HoKEGXvf3p7FcHcIHyiEJ65GBvC7e7HwMc3jYxlBwtbebSpEcf3oFqI5dl3A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/collections@3.10.4(react@18.2.0): resolution: {integrity: sha512-OHhCrItGt4zB2bSrgObRo0H2SC7QlkH8ReGxo+NVIWchXRLRoiWBP7S+IwleewEo5gOqDVPY3hqA9n4iiI8twg==} peerDependencies: @@ -13234,6 +13978,16 @@ packages: react: 18.2.0 dev: false + /@react-stately/collections@3.10.9(react@18.2.0): + resolution: {integrity: sha512-plyrng6hOQMG8LrjArMA6ts/DgWyXln3g90/hFNbqe/hdVYF53sDVsj8Jb+5LtoYTpiAlV6eOvy1XR0vPZUf8w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/combobox@3.8.1(react@18.2.0): resolution: {integrity: sha512-FaWkqTXQdWg7ptaeU4iPcqF/kxbRg2ZNUcvW/hiL/enciV5tRCsddvfNqvDvy1L30z9AUwlp9MWqzm/DhBITCw==} peerDependencies: @@ -13251,6 +14005,23 @@ packages: react: 18.2.0 dev: false + /@react-stately/combobox@3.9.1(react@18.2.0): + resolution: {integrity: sha512-jmeKUKs0jK18NwDAlpu79ATufgxrc6Sn3ZMmI8KPVQ5sdPTjNlnDx6gTFyOOIa87axf/c6WYU7v3jxmcp+RDdg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/list': 3.10.7(react@18.2.0) + '@react-stately/overlays': 3.6.9(react@18.2.0) + '@react-stately/select': 3.6.6(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/combobox': 3.12.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/data@3.11.0(react@18.2.0): resolution: {integrity: sha512-0BlPT58WrAtUvpiEfUuyvIsGFTzp/9vA5y+pk53kGJhOdc5tqBGHi9cg40pYE/i1vdHJGMpyHGRD9nkQb8wN3Q==} peerDependencies: @@ -13261,6 +14032,22 @@ packages: react: 18.2.0 dev: false + /@react-stately/datepicker@3.10.1(react@18.2.0): + resolution: {integrity: sha512-KXr5cxLOLUYBf3wlDSKhvshsKOWpdV2flhS075V6dgC/EPBh7igBZGUXJ9AZzndT7Hx1w8v/ul6CIffxEJz1Nw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@internationalized/string': 3.2.3 + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/overlays': 3.6.9(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/datepicker': 3.8.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/datepicker@3.9.1(react@18.2.0): resolution: {integrity: sha512-o5xLvlZGJyAbTev2yruGlV2fzQyIDuYTgL19TTt0W0WCfjGGr/AAA9GjGXXmyoRA7sZMxqIPnnv7lNrdA38ofA==} peerDependencies: @@ -13288,12 +14075,29 @@ packages: react: 18.2.0 dev: false + /@react-stately/dnd@3.4.1(react@18.2.0): + resolution: {integrity: sha512-EXPW1vKx3vNpMaXOpPKTOU1T4S+jqjllGFDyWD659Ql0lL9SQ5Y4IU/KmIK3T3yKkjps9xrMmCjLAkb75PH5zg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/selection': 3.16.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/flags@3.0.0: resolution: {integrity: sha512-e3i2ItHbIa0eEwmSXAnPdD7K8syW76JjGe8ENxwFJPW/H1Pu9RJfjkCb/Mq0WSPN/TpxBb54+I9TgrGhbCoZ9w==} dependencies: '@swc/helpers': 0.4.14 dev: false + /@react-stately/flags@3.0.3: + resolution: {integrity: sha512-/ha7XFA0RZTQsbzSPwu3KkbNMgbvuM0GuMTYLTBWpgBrovBNTM+QqI/PfZTdHg8PwCYF4H5Y8gjdSpdulCvJFw==} + dependencies: + '@swc/helpers': 0.5.2 + dev: false + /@react-stately/form@3.0.0(react@18.2.0): resolution: {integrity: sha512-C8wkfFmtx1escizibhdka5JvTy9/Vp173CS9cakjvWTmnjYYC1nOlzwp7BsYWTgerCFbRY/BU/Cf/bJDxPiUKQ==} peerDependencies: @@ -13304,6 +14108,16 @@ packages: react: 18.2.0 dev: false + /@react-stately/form@3.0.5(react@18.2.0): + resolution: {integrity: sha512-J3plwJ63HQz109OdmaTqTA8Qhvl3gcYYK7DtgKyNP6mc/Me2Q4tl2avkWoA+22NRuv5m+J8TpBk4AVHUEOwqeQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/grid@3.8.4(react@18.2.0): resolution: {integrity: sha512-rwqV1K4lVhaiaqJkt4TfYqdJoVIyqvSm98rKAYfCNzrKcivVpoiCMJ2EMt6WlYCjDVBdEOQ7fMV1I60IV0pntA==} peerDependencies: @@ -13317,6 +14131,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/grid@3.9.1(react@18.2.0): + resolution: {integrity: sha512-LSVIcXO/cqwG0IgDSk2juDbpARBS1IzGnsTp/8vSOejMxq5MXrwxL5hUcqNczL8Ss6aLpELm42tCS0kPm3cMKw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/selection': 3.16.1(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/list@3.10.2(react@18.2.0): resolution: {integrity: sha512-INt+zofkIg2KN8B95xPi9pJG7ZFWAm30oIm/lCPBqM3K1Nm03/QaAbiQj2QeJcOsG3lb7oqI6D6iwTolwJkjIQ==} peerDependencies: @@ -13330,6 +14157,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/list@3.10.7(react@18.2.0): + resolution: {integrity: sha512-W5PG7uG5GQV2Q59vXJE7QLKHZIoUNEx+JmHrBUCMKUgyngSpKIIEDR/R/C1b6ZJ9jMqqZA68Zlnd5iK1/mBi1A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/selection': 3.16.1(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/menu@3.6.0(react@18.2.0): resolution: {integrity: sha512-OB6CjNyfOkAuirqx1oTL8z8epS9WDzLyrXjmRnxdiCU9EgRXLGAQNECuO7VIpl58oDry8tgRJiJ8fn8FivWSQA==} peerDependencies: @@ -13342,6 +14182,18 @@ packages: react: 18.2.0 dev: false + /@react-stately/menu@3.8.1(react@18.2.0): + resolution: {integrity: sha512-HzAANHg+QUpyRok0CBIL/5qb+4TARteP0q9av2tKnQWPG91iJw84phJDJrmmY55uFFax4fxBgDM9dy1t12iKgQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/overlays': 3.6.9(react@18.2.0) + '@react-types/menu': 3.9.11(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/numberfield@3.8.0(react@18.2.0): resolution: {integrity: sha512-1XvB8tDOvZKcFnMM6qNLEaTVJcIc0jRFS/9jtS8MzalZvh8DbKi0Ucm1bGU7S5rkCx2QWqZ0rGOIm2h/RlcpkA==} peerDependencies: @@ -13355,6 +14207,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/numberfield@3.9.5(react@18.2.0): + resolution: {integrity: sha512-aWilyzrZOvkgntcXd6Kl+t1QiCbnajUCN8yll6/saByKpfuOf1k6AGYNQBJ0CO/5HyffPPdbFs+45sj4e3cdjA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/number': 3.5.3 + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/numberfield': 3.8.5(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/overlays@3.6.4(react@18.2.0): resolution: {integrity: sha512-tHEaoAGpE9dSnsskqLPVKum59yGteoSqsniTopodM+miQozbpPlSjdiQnzGLroy5Afx5OZYClE616muNHUILXA==} peerDependencies: @@ -13366,6 +14231,17 @@ packages: react: 18.2.0 dev: false + /@react-stately/overlays@3.6.9(react@18.2.0): + resolution: {integrity: sha512-4chfyzKw7P2UEainm0yzjUgYwG1ovBejN88eTrn+O62x5huuMCwe0cbMxmYh4y7IhRFSee3jIJd0SP0u/+i39w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/radio@3.10.1(react@18.2.0): resolution: {integrity: sha512-MsBYbcLCvjKsqTAKe43T681F2XwKMsS7PLG0eplZgWP9210AMY78GeY1XPYZKHPAau8XkbYiuJqbqTerIJ3DBw==} peerDependencies: @@ -13379,6 +14255,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/radio@3.10.6(react@18.2.0): + resolution: {integrity: sha512-wiJuUUQ6LuEv0J1DQtkC0+Sed7tO6y3sIPeB+5uIxIIsUpxvNlDcqr+JOkrQm7gZmkmvcfotb5Gv5PqaIl1zKA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/radio': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/searchfield@3.5.0(react@18.2.0): resolution: {integrity: sha512-SStjChkn/33pEn40slKQPnBnmQYyxVazVwPjiBkdeVejC42lUVairUTrGJgF0PNoZTbxn0so2/XzjqTC9T8iCw==} peerDependencies: @@ -13390,6 +14279,17 @@ packages: react: 18.2.0 dev: false + /@react-stately/searchfield@3.5.5(react@18.2.0): + resolution: {integrity: sha512-rKWIVNbxft5eGGxQ4CtcTKGXm2B1AuYSg6kLRQLq+VYspPNq3wfeMtVBeIdy4LNjWXsTmzs2b3o+zkFYdPqPPw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/searchfield': 3.5.7(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/select@3.6.1(react@18.2.0): resolution: {integrity: sha512-e5ixtLiYLlFWM8z1msDqXWhflF9esIRfroptZsltMn1lt2iImUlDRlOTZlMtPQzUrDWoiHXRX88sSKUM/jXjQQ==} peerDependencies: @@ -13404,6 +14304,20 @@ packages: react: 18.2.0 dev: false + /@react-stately/select@3.6.6(react@18.2.0): + resolution: {integrity: sha512-JEpBosWNSXRexE/iReATei1EiVdTIwOWlLcCGw6K7oC/5/f+OHMsh2Kkt/c/RzM/to3vgR+Wbbqwrb712AWgYQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/list': 3.10.7(react@18.2.0) + '@react-stately/overlays': 3.6.9(react@18.2.0) + '@react-types/select': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/selection@3.14.2(react@18.2.0): resolution: {integrity: sha512-mL7OoiUgVWaaF7ks5XSxgbXeShijYmD4G3bkBHhqkpugU600QH6BM2hloCq8KOUupk1y8oTljPtF9EmCv375DA==} peerDependencies: @@ -13416,6 +14330,18 @@ packages: react: 18.2.0 dev: false + /@react-stately/selection@3.16.1(react@18.2.0): + resolution: {integrity: sha512-qmnmYaXY7IhhzmIiInec1a/yPxlPSBHka6vrWddvt0S6zN7FU5cv6sm69ONUwYwLKSoaNHgOGvZhmsTzyV0O2A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/slider@3.5.0(react@18.2.0): resolution: {integrity: sha512-dOVpIxb7XKuiRxgpHt1bUSlsklciFki100tKIyBPR+Okar9iC/CwLYROYgVfLkGe77jEBNkor9tDLjDGEWcc1w==} peerDependencies: @@ -13428,6 +14354,18 @@ packages: react: 18.2.0 dev: false + /@react-stately/slider@3.5.6(react@18.2.0): + resolution: {integrity: sha512-a7DZgpOVjQyGzMLPiVRCVHISPJX8E3bT+qbZpcRQN+F7T7wReOwUt2I8gQMosnnCGWgU6kdYk8snn0obXe70Fg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/slider': 3.7.5(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/table@3.11.4(react@18.2.0): resolution: {integrity: sha512-dWINJIEOKQl4qq3moq+S8xCD3m+yJqBj0dahr+rOkS+t2uqORwzsusTM35D2T/ZHZi49S2GpE7QuDa+edCynPw==} peerDependencies: @@ -13445,6 +14383,23 @@ packages: react: 18.2.0 dev: false + /@react-stately/table@3.12.1(react@18.2.0): + resolution: {integrity: sha512-Cg3lXrWJNrYkD1gqRclMxq0GGiR+ygxdeAqk2jbbsmHU8RSQuzoO/RtUCw6WAKfQjAq4gE0E60TlAsGgCUdJGA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/flags': 3.0.3 + '@react-stately/grid': 3.9.1(react@18.2.0) + '@react-stately/selection': 3.16.1(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/table': 3.10.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/tabs@3.6.3(react@18.2.0): resolution: {integrity: sha512-Nj+Gacwa2SIzYIvHW40GsyX4Q6c8kF7GOuXESeQswbCjnwqhrSbDBp+ngPcUPUJxqFh6JhDCVwAS3wMhUoyUwA==} peerDependencies: @@ -13457,6 +14412,18 @@ packages: react: 18.2.0 dev: false + /@react-stately/tabs@3.6.8(react@18.2.0): + resolution: {integrity: sha512-pLRwnMmXk/IWvbIJYSO5hm3/PiJ/VzrQlwKr6dlOcrDOSVIZpTjnGWHd6mJSDoPiDyBThlN/k3+2pUFMEOAcfw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/list': 3.10.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/tabs': 3.3.9(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/toggle@3.7.0(react@18.2.0): resolution: {integrity: sha512-TRksHkCJk/Xogq4181g3CYgJf+EfsJCqX5UZDSw1Z1Kgpvonjmdf6FAfQfCh9QR2OuXUL6hOLUDVLte5OPI+5g==} peerDependencies: @@ -13468,6 +14435,28 @@ packages: react: 18.2.0 dev: false + /@react-stately/toggle@3.7.6(react@18.2.0): + resolution: {integrity: sha512-xRZyrjNVu1VCd1xpg5RwmNYs9fXb+JHChoUaRcBmGCCjsPD0R5uR3iNuE17RXJtWS3/8o9IJVn90+/7NW7boOg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-stately/tooltip@3.4.11(react@18.2.0): + resolution: {integrity: sha512-r1ScIXau2LZ/lUUBQ5PI01S2TB2urF2zrPzNM2xgngFLlG2uTyfIgMga6/035quQQKd3Bd0qGigMvTgZ3GRGEg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/overlays': 3.6.9(react@18.2.0) + '@react-types/tooltip': 3.4.11(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/tooltip@3.4.6(react@18.2.0): resolution: {integrity: sha512-uL93bmsXf+OOgpKLPEKfpDH4z+MK2CuqlqVxx7rshN0vjWOSoezE5nzwgee90+RpDrLNNNWTNa7n+NkDRpI1jA==} peerDependencies: @@ -13492,6 +14481,28 @@ packages: react: 18.2.0 dev: false + /@react-stately/tree@3.8.3(react@18.2.0): + resolution: {integrity: sha512-9sRQOxkK7ZMdtSTGHx0sMabHC39PEM4tMl+IdJKkmcp60bfsm3p6LHXhha3E58jwnZaemBfUrlQmTP/E26BbGw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/selection': 3.16.1(react@18.2.0) + '@react-stately/utils': 3.10.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-stately/utils@3.10.2(react@18.2.0): + resolution: {integrity: sha512-fh6OTQtbeQC0ywp6LJuuKs6tKIgFvt/DlIZEcIpGho6/oZG229UnIk6TUekwxnDbumuYyan6D9EgUtEMmT8UIg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/utils@3.9.0(react@18.2.0): resolution: {integrity: sha512-yPKFY1F88HxuZ15BG2qwAYxtpE4HnIU0Ofi4CuBE0xC6I8mwo4OQjDzi+DZjxQngM9D6AeTTD6F1V8gkozA0Gw==} peerDependencies: @@ -13522,6 +14533,16 @@ packages: react: 18.2.0 dev: false + /@react-types/breadcrumbs@3.7.7(react@18.2.0): + resolution: {integrity: sha512-ZmhXwD2LLzfEA2OvOCp/QvXu8A/Edsrn5q0qUDGsmOZj9SCVeT82bIv8P+mQnATM13mi2gyoik6102Jc1OscJA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/link': 3.5.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/button@3.9.1(react@18.2.0): resolution: {integrity: sha512-bf9iTar3PtqnyV9rA+wyFyrskZKhwmOuOd/ifYIjPs56YNVXWH5Wfqj6Dx3xdFBgtKx8mEVQxVhoX+WkHX+rtw==} peerDependencies: @@ -13531,6 +14552,15 @@ packages: react: 18.2.0 dev: false + /@react-types/button@3.9.6(react@18.2.0): + resolution: {integrity: sha512-8lA+D5JLbNyQikf8M/cPP2cji91aVTcqjrGpDqI7sQnaLFikM8eFR6l1ZWGtZS5MCcbfooko77ha35SYplSQvw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/calendar@3.4.3(react@18.2.0): resolution: {integrity: sha512-96x57ctX5wNEl+8et3sc2NQm8neOJayEeqOQQpyPtI7jyvst/xBrKCwysf9W/dhgPlUC+KeBAYFWfjd5hFVHYA==} peerDependencies: @@ -13541,6 +14571,16 @@ packages: react: 18.2.0 dev: false + /@react-types/calendar@3.4.8(react@18.2.0): + resolution: {integrity: sha512-KVampt/X4uJvWU0TsxIdgPdXIAUClGtxcDWHzuFRJ7YUYkA4rH8Lad0kQ1mVehnwOLpuba8j9GCYKorkbln0gw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/checkbox@3.6.0(react@18.2.0): resolution: {integrity: sha512-vgbuJzQpVCNT5AZWV0OozXCnihqrXxoZKfJFIw0xro47pT2sn3t5UC4RA9wfjDGMoK4frw1K/4HQLsQIOsPBkw==} peerDependencies: @@ -13550,6 +14590,15 @@ packages: react: 18.2.0 dev: false + /@react-types/checkbox@3.8.3(react@18.2.0): + resolution: {integrity: sha512-f4c1mnLEt0iS1NMkyZXgT3q3AgcxzDk7w6MSONOKydcnh0xG5L2oefY14DhVDLkAuQS7jThlUFwiAs+MxiO3MA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/combobox@3.10.0(react@18.2.0): resolution: {integrity: sha512-1IXSNS02TPbguyYopaW2snU6sZusbClHrEyVr4zPeexTV4kpUUBNXOzFQ+eSQRR0r2XW57Z0yRW4GJ6FGU0yCA==} peerDependencies: @@ -13559,6 +14608,15 @@ packages: react: 18.2.0 dev: false + /@react-types/combobox@3.12.1(react@18.2.0): + resolution: {integrity: sha512-bd5YwHZWtgnJx4jGbplWbYzXj7IbO5w3IY5suNR7r891rx6IktquZ8GQwyYH0pQ/x+X5LdK2xI59i6+QC2PmlA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/datepicker@3.7.1(react@18.2.0): resolution: {integrity: sha512-5juVDULOytNzkotqX8j5mYKJckeIpkgbHqVSGkPgLw0++FceIaSZ6RH56cqLup0pO45paqIt9zHh+QXBYX+syg==} peerDependencies: @@ -13571,6 +14629,28 @@ packages: react: 18.2.0 dev: false + /@react-types/datepicker@3.8.1(react@18.2.0): + resolution: {integrity: sha512-ZpxHHVT3rmZ4YsYP4TWCZSMSfOUm+067mZyyGLmvHxg55eYmctiB4uMgrRCqDoeiSiOjtxad0VtpPjf6ftK1GQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@react-types/calendar': 3.4.8(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + + /@react-types/dialog@3.5.12(react@18.2.0): + resolution: {integrity: sha512-JmpQbSpXltqEyYfEwoqDolABIiojeExkqolHNdQlayIsfFuSxZxNwXZPOpz58Ri/iwv21JP7K3QF0Gb2Ohxl9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/dialog@3.5.7(react@18.2.0): resolution: {integrity: sha512-geYoqAyQaTLG43AaXdMUVqZXYgkSifrD9cF7lR2kPAT0uGFv0YREi6ieU+aui8XJ83EW0xcxP+EPWd2YkN4D4w==} peerDependencies: @@ -13590,6 +14670,15 @@ packages: react: 18.2.0 dev: false + /@react-types/grid@3.2.8(react@18.2.0): + resolution: {integrity: sha512-6PJrpukwMqlv3IhJSDkJuVbhHM8Oe6hd2supWqd9adMXrlSP7QHt9a8SgFcFblCCTx8JzUaA0PvY5sTudcEtOQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/link@3.5.2(react@18.2.0): resolution: {integrity: sha512-/s51/WejmpLiyxOgP89s4txgxYoGaPe8pVDItVo1h4+BhU1Puyvgv/Jx8t9dPvo6LUXbraaN+SgKk/QDxaiirw==} peerDependencies: @@ -13599,6 +14688,15 @@ packages: react: 18.2.0 dev: false + /@react-types/link@3.5.7(react@18.2.0): + resolution: {integrity: sha512-2WyaVmm1qr9UrSG3Dq6iz+2ziuVp+DH8CsYZ9CA6aNNb6U18Hxju3LTPb4a5gM0eC7W0mQGNBmrgGlAdDZEJOw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/listbox@3.4.6(react@18.2.0): resolution: {integrity: sha512-XOQvrTqNh5WIPDvKiWiep8T07RAsMfjAXTjDbnjxVlKACUXkcwpts9kFaLnJ9LJRFt6DwItfP+WMkzvmx63/NQ==} peerDependencies: @@ -13608,6 +14706,25 @@ packages: react: 18.2.0 dev: false + /@react-types/listbox@3.5.1(react@18.2.0): + resolution: {integrity: sha512-n5bOgD9lgfK1qaLtag9WPnu151SwXBCNn/OgGY/Br9mWRl+nPUEYtFcPX+2VCld7uThf54kwrTmzlFnaraIlcw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + + /@react-types/menu@3.9.11(react@18.2.0): + resolution: {integrity: sha512-IguQVF70d7aHXgWB1Rd2a/PiIuLZ2Nt7lyayJshLcy/NLOYmgpTmTyn2WCtlA5lTfQwmQrNFf4EvnWkeljJXdA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/menu@3.9.6(react@18.2.0): resolution: {integrity: sha512-w/RbFInOf4nNayQDv5c2L8IMJbcFOkBhsT3xvvpTy+CHvJcQdjggwaV1sRiw7eF/PwB81k2CwigmidUzHJhKDg==} peerDependencies: @@ -13627,6 +14744,15 @@ packages: react: 18.2.0 dev: false + /@react-types/meter@3.4.3(react@18.2.0): + resolution: {integrity: sha512-Y2fX5CTAPGRKxVSeepbeyN6/K+wlF9pMRcNxTSU2qDwdoFqNCtTWMcWuCsU/Y2L/zU0jFWu4x0Vo7WkrcsgcMA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/progress': 3.5.6(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/numberfield@3.7.0(react@18.2.0): resolution: {integrity: sha512-gaGi+vqm1Y8LCWRsWYUjcGftPIzl+8W2VOfkgKMLM8y76nnwTPtmAqs+Ap1cg7sEJSfsiKMq93e9yvP3udrC2w==} peerDependencies: @@ -13636,6 +14762,15 @@ packages: react: 18.2.0 dev: false + /@react-types/numberfield@3.8.5(react@18.2.0): + resolution: {integrity: sha512-LVWggkxwd1nyVZomXBPfQA1E4I4/i4PBifjcDs2AfcV7q5RE9D+DVIDXsYucVOBxPlDOxiAq/T9ypobspWSwHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/overlays@3.8.4(react@18.2.0): resolution: {integrity: sha512-pfgNlQnbF6RB/R2oSxyqAP3Uzz0xE/k5q4n5gUeCDNLjY5qxFHGE8xniZZ503nZYw6VBa9XMN1efDOKQyeiO0w==} peerDependencies: @@ -13645,6 +14780,15 @@ packages: react: 18.2.0 dev: false + /@react-types/overlays@3.8.9(react@18.2.0): + resolution: {integrity: sha512-9ni9upQgXPnR+K9cWmbYWvm3ll9gH8P/XsEZprqIV5zNLMF334jADK48h4jafb1X9RFnj0WbHo6BqcSObzjTig==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/progress@3.5.1(react@18.2.0): resolution: {integrity: sha512-CqsUjczUK/SfuFzDcajBBaXRTW0D3G9S/yqLDj9e8E0ii+lGDLt1PHj24t1J7E88U2rVYqmM9VL4NHTt8o3IYA==} peerDependencies: @@ -13654,6 +14798,15 @@ packages: react: 18.2.0 dev: false + /@react-types/progress@3.5.6(react@18.2.0): + resolution: {integrity: sha512-Nh43sjQ5adyN1bTHBPRaIPhXUdBqP0miYeJpeMY3V/KUl4qmouJLwDnccwFG4xLm6gBfYe22lgbbV7nAfNnuTQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/radio@3.7.0(react@18.2.0): resolution: {integrity: sha512-EcwGAXzSHjSqpFZha7xn3IUrhPiJLj+0yb1Ip0qPmhWz0VVw2DwrkY7q/jfaKroVvQhTo2TbfGhcsAQrt0fRqg==} peerDependencies: @@ -13663,6 +14816,15 @@ packages: react: 18.2.0 dev: false + /@react-types/radio@3.8.3(react@18.2.0): + resolution: {integrity: sha512-fUVJt4Bb6jOReFqnhHVNxWXH7t6c60uSFfoPKuXt/xI9LL1i2jhpur0ggpTfIn3qLIAmNBU6bKBCWAdr4KjeVQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/searchfield@3.5.2(react@18.2.0): resolution: {integrity: sha512-JAK2/Kg4Dr393FYfbRw0TlXKnJPX77sq1x/ZBxtO6p64+MuuIYKqw0i9PwDlo1PViw2QI5u8GFhKA2TgemY9uA==} peerDependencies: @@ -13673,6 +14835,16 @@ packages: react: 18.2.0 dev: false + /@react-types/searchfield@3.5.7(react@18.2.0): + resolution: {integrity: sha512-dyuPwNWGswRZfb4i50Q1Q3tCwTBxRLkrAxcMs+Rf2Rl4t93bawBdSdIQuvxu1KEhgd0EXA9ZUW53ZplqfVmtiw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/textfield': 3.9.5(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/select@3.9.1(react@18.2.0): resolution: {integrity: sha512-EpKSxrnh8HdZvOF9dHQkjivAcdIp1K81FaxmvosH8Lygqh0iYXxAdZGtKLMyBoPI8YFhA+rotIzTcOqgCCnqWA==} peerDependencies: @@ -13682,6 +14854,15 @@ packages: react: 18.2.0 dev: false + /@react-types/select@3.9.6(react@18.2.0): + resolution: {integrity: sha512-cVSFR0eJLup/ht1Uto+y8uyLmHO89J6wNh65SIHb3jeVz9oLBAedP3YNI2qB+F9qFMUcA8PBSLXIIuT6gXzLgQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/shared@3.22.0(react@18.2.0): resolution: {integrity: sha512-yVOekZWbtSmmiThGEIARbBpnmUIuePFlLyctjvCbgJgGhz8JnEJOipLQ/a4anaWfzAgzSceQP8j/K+VOOePleA==} peerDependencies: @@ -13690,6 +14871,14 @@ packages: react: 18.2.0 dev: false + /@react-types/shared@3.24.1(react@18.2.0): + resolution: {integrity: sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + react: 18.2.0 + dev: false + /@react-types/slider@3.7.0(react@18.2.0): resolution: {integrity: sha512-uyQXUVFfqc9SPUW0LZLMan2n232F/OflRafiHXz9viLFa9tVOupVa7GhASRAoHojwkjoJ1LjFlPih7g5dOZ0/Q==} peerDependencies: @@ -13699,6 +14888,15 @@ packages: react: 18.2.0 dev: false + /@react-types/slider@3.7.5(react@18.2.0): + resolution: {integrity: sha512-bRitwQRQjQoOcKEdPMljnvm474dwrmsc6pdsVQDh/qynzr+KO9IHuYc3qPW53WVE2hMQJDohlqtCAWQXWQ5Vcg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/switch@3.5.0(react@18.2.0): resolution: {integrity: sha512-/wNmUGjk69bP6t5k2QkAdrNN5Eb9Rz4dOyp0pCPmoeE+5haW6sV5NmtkvWX1NSc4DQz1xL/a5b+A0vxPCP22Jw==} peerDependencies: @@ -13708,6 +14906,25 @@ packages: react: 18.2.0 dev: false + /@react-types/switch@3.5.5(react@18.2.0): + resolution: {integrity: sha512-SZx1Bd+COhAOs/RTifbZG+uq/llwba7VAKx7XBeX4LeIz1dtguy5bigOBgFTMQi4qsIVCpybSWEEl+daj4XFPw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + + /@react-types/table@3.10.1(react@18.2.0): + resolution: {integrity: sha512-xsNh0Gm4GtNeSknZqkMsfGvc94fycmfhspGO+FzQKim2hB5k4yILwd+lHYQ2UKW6New9GVH/zN2Pd3v67IeZ2g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/table@3.9.2(react@18.2.0): resolution: {integrity: sha512-brw5JUANOzBa2rYNpN8AIl9nDZ9RwRZC6G/wTM/JhtirjC1S42oCtf8Ap5rWJBdmMG/5KOfcGNcAl/huyqb3gg==} peerDependencies: @@ -13727,6 +14944,15 @@ packages: react: 18.2.0 dev: false + /@react-types/tabs@3.3.9(react@18.2.0): + resolution: {integrity: sha512-3Q9kRVvg/qDyeJR/W1+C2z2OyvDWQrSLvOCvAezX5UKzww4rBEAA8OqBlyDwn7q3fiwrh/m64l6p+dbln+RdxQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/textfield@3.9.0(react@18.2.0): resolution: {integrity: sha512-D/DiwzsfkwlAg3uv8hoIfwju+zhB/hWDEdTvxQbPkntDr0kmN/QfI17NMSzbOBCInC4ABX87ViXLGxr940ykGA==} peerDependencies: @@ -13736,6 +14962,25 @@ packages: react: 18.2.0 dev: false + /@react-types/textfield@3.9.5(react@18.2.0): + resolution: {integrity: sha512-0hwZI4WXSEStPzdltKwbNUZWlgHtwbxMWE0LfqIzEW8RB7DyBflYSKzLyTBFqwUZ8j3C1gWy9c9OPSeCOq792Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + + /@react-types/tooltip@3.4.11(react@18.2.0): + resolution: {integrity: sha512-WPikHQxeT5Lb09yJEaW6Ja3ecE0g1YM6ukWYS2v/iZLUPn5YlYrGytspuCYQNSh/u7suCz4zRLEHYCl7OCigjw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/tooltip@3.4.6(react@18.2.0): resolution: {integrity: sha512-RaZewdER7ZcsNL99RhVHs8kSLyzIBkwc0W6eFZrxST2MD9J5GzkVWRhIiqtFOd5U1aYnxdJ6woq72Ef+le6Vfw==} peerDependencies: @@ -15981,6 +17226,10 @@ packages: '@types/node': 18.19.20 dev: false + /@types/invariant@2.2.37: + resolution: {integrity: sha512-IwpIMieE55oGWiXkQPSBY1nw1nFs6bsKXTFskNY8sdS17K24vyEBRQZEwlRS7ZmXCWnJcQtbxWzly+cODWGs2A==} + dev: false + /@types/is-ci@3.0.0: resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} dependencies: @@ -17491,6 +18740,23 @@ packages: resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} dev: false + /@xstate/react@4.1.1(@types/react@18.2.69)(react@18.2.0)(xstate@5.17.1): + resolution: {integrity: sha512-pFp/Y+bnczfaZ0V8B4LOhx3d6Gd71YKAPbzerGqydC2nsYN/mp7RZu3q/w6/kvI2hwR/jeDeetM7xc3JFZH2NA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + xstate: ^5.11.0 + peerDependenciesMeta: + xstate: + optional: true + dependencies: + react: 18.2.0 + use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.69)(react@18.2.0) + use-sync-external-store: 1.2.2(react@18.2.0) + xstate: 5.17.1 + transitivePeerDependencies: + - '@types/react' + dev: false + /@xtuc/ieee754@1.2.0: resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -19639,6 +20905,11 @@ packages: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + /cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + dev: false + /cookiejar@2.1.4: resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} dev: true @@ -23583,6 +24854,25 @@ packages: '@emotion/is-prop-valid': 0.8.8 dev: false + /framer-motion@11.3.24(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-kl0YI7HwAtyV0VOAWuU/rXoOS8+z5qSkMN6rZS+a9oe6fIha6SC3vjJN6u/hBpvjrg5MQNdSnqnjYxm0WYTX9g==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tslib: 2.6.2 + dev: false + /fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -29671,6 +30961,10 @@ packages: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: false + /performant-array-to-tree@1.11.0: + resolution: {integrity: sha512-YwCqIDvnaebXaKuKQhI5yJD6ryDc3FxvoeX/5ougXTKDUWb7s5S2BuBgIyftCa4sBe1+ZU5Kmi4RJy+pjjjrpw==} + dev: false + /periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} dependencies: @@ -30948,6 +32242,53 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /react-aria@3.34.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-vA4BP+SWjFFRfOTQcNJtIp9gKlxuC7kPUXQK9fuNA+2K4mJdIc9mBnmwXQiLl/eAthMf43fD4fETfY9SiCm1Zg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/string': 3.2.3 + '@react-aria/breadcrumbs': 3.5.15(react@18.2.0) + '@react-aria/button': 3.9.7(react@18.2.0) + '@react-aria/calendar': 3.5.10(react-dom@18.2.0)(react@18.2.0) + '@react-aria/checkbox': 3.14.5(react@18.2.0) + '@react-aria/combobox': 3.10.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/datepicker': 3.11.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/dialog': 3.5.16(react-dom@18.2.0)(react@18.2.0) + '@react-aria/dnd': 3.7.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/focus': 3.18.1(react@18.2.0) + '@react-aria/gridlist': 3.9.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/i18n': 3.12.1(react@18.2.0) + '@react-aria/interactions': 3.22.1(react@18.2.0) + '@react-aria/label': 3.7.10(react@18.2.0) + '@react-aria/link': 3.7.3(react@18.2.0) + '@react-aria/listbox': 3.13.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/menu': 3.15.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/meter': 3.4.15(react@18.2.0) + '@react-aria/numberfield': 3.11.5(react-dom@18.2.0)(react@18.2.0) + '@react-aria/overlays': 3.23.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/progress': 3.4.15(react@18.2.0) + '@react-aria/radio': 3.10.6(react@18.2.0) + '@react-aria/searchfield': 3.7.7(react@18.2.0) + '@react-aria/select': 3.14.7(react-dom@18.2.0)(react@18.2.0) + '@react-aria/selection': 3.19.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/separator': 3.4.1(react@18.2.0) + '@react-aria/slider': 3.7.10(react@18.2.0) + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-aria/switch': 3.6.6(react@18.2.0) + '@react-aria/table': 3.15.1(react-dom@18.2.0)(react@18.2.0) + '@react-aria/tabs': 3.9.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/tag': 3.4.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/textfield': 3.14.7(react@18.2.0) + '@react-aria/tooltip': 3.7.6(react@18.2.0) + '@react-aria/utils': 3.25.1(react@18.2.0) + '@react-aria/visually-hidden': 3.8.14(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react-collapse@5.1.1(react@18.2.0): resolution: {integrity: sha512-k6cd7csF1o9LBhQ4AGBIdxB60SUEUMQDAnL2z1YvYNr9KoKr+nDkhN6FK7uGaBd/rYrYfrMpzpmJEIeHRYogBw==} peerDependencies: @@ -31384,6 +32725,32 @@ packages: tslib: 2.5.0 dev: false + /react-window-splitter@0.2.0(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-A7KD0osBfh18uNij87bHbqG6L8SHJ2S9IAbIny1T6vW87FnTg29gS/YRRQtcR8Gu9gxCEO67uqAjLOpMESYW+g==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: '>=16' + react-dom: '>=16' + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.69)(react@18.2.0) + '@react-spring/rafz': 9.7.4 + '@types/invariant': 2.2.37 + '@xstate/react': 4.1.1(@types/react@18.2.69)(react@18.2.0)(xstate@5.17.1) + d3-ease: 3.0.1 + framer-motion: 11.3.24(react-dom@18.2.0)(react@18.2.0) + invariant: 2.2.4 + react: 18.2.0 + react-aria: 3.34.1(react-dom@18.2.0)(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) + reforest: 0.13.0(@types/react@18.2.69)(react@18.2.0) + universal-cookie: 7.2.0 + xstate: 5.17.1 + transitivePeerDependencies: + - '@emotion/is-prop-valid' + - '@types/react' + - immer + dev: false + /react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -31566,6 +32933,19 @@ packages: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} dev: false + /reforest@0.13.0(@types/react@18.2.69)(react@18.2.0): + resolution: {integrity: sha512-f0It/s51f1UWCCCni0viULALDBhxWBPFnLmZRYtKcz4zYeNWqeNTdcnU/OpBry9tk+jyMQcH3MLK8UdzsAvA5w==} + peerDependencies: + react: '>=16.8' + dependencies: + performant-array-to-tree: 1.11.0 + react: 18.2.0 + zustand: 4.5.4(@types/react@18.2.69)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + /regenerate-unicode-properties@10.1.0: resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} engines: {node: '>=4'} @@ -35545,6 +36925,13 @@ packages: unist-util-is: 5.1.1 unist-util-visit-parents: 5.1.1 + /universal-cookie@7.2.0: + resolution: {integrity: sha512-PvcyflJAYACJKr28HABxkGemML5vafHmiL4ICe3e+BEKXRMt0GaFLZhAwgv637kFFnnfiSJ8e6jknrKkMrU+PQ==} + dependencies: + '@types/cookie': 0.6.0 + cookie: 0.6.0 + dev: false + /universal-github-app-jwt@1.1.1: resolution: {integrity: sha512-G33RTLrIBMFmlDV4u4CBF7dh71eWwykck4XgaxaIVeZKOYZRAAxvcGMRFTUclVY6xoUPQvO4Ne5wKGxYm/Yy9w==} dependencies: @@ -35765,6 +37152,14 @@ packages: tslib: 2.6.2 dev: false + /use-sync-external-store@1.2.0(react@18.2.0): + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + /use-sync-external-store@1.2.2(react@18.2.0): resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} peerDependencies: @@ -37124,6 +38519,10 @@ packages: engines: {node: '>=0.4.0'} dev: false + /xstate@5.17.1: + resolution: {integrity: sha512-RNwcXdth+kboWZg+Zhf6f6iNP6CtAAiS4z4qwyTd/fWBH9PHXRqko6OdW3xOTwP62f0mVD+jsPOSqY4Ar8nZKQ==} + dev: false + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -37313,5 +38712,25 @@ packages: /zod@3.22.3: resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} + /zustand@4.5.4(@types/react@18.2.69)(react@18.2.0): + resolution: {integrity: sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0.6' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + dependencies: + '@types/react': 18.2.69 + react: 18.2.0 + use-sync-external-store: 1.2.0(react@18.2.0) + dev: false + /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} From 8afd4c4d35356d792d12171403c735d84cb9e3c8 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 12 Aug 2024 15:04:20 +0100 Subject: [PATCH 02/33] WIP with new resizable panels and SSR --- .../app/components/primitives/Resizable.tsx | 5 + .../route.tsx | 120 +++++++++++++----- .../app/services/resizablePanel.server.ts | 28 ++++ apps/webapp/app/services/resizablePanel.ts | 31 ----- apps/webapp/remix.config.js | 2 + 5 files changed, 121 insertions(+), 65 deletions(-) create mode 100644 apps/webapp/app/services/resizablePanel.server.ts delete mode 100644 apps/webapp/app/services/resizablePanel.ts diff --git a/apps/webapp/app/components/primitives/Resizable.tsx b/apps/webapp/app/components/primitives/Resizable.tsx index f06e3bd6e..a03447fef 100644 --- a/apps/webapp/app/components/primitives/Resizable.tsx +++ b/apps/webapp/app/components/primitives/Resizable.tsx @@ -1,11 +1,13 @@ "use client"; +import React from "react"; import { PanelGroup, Panel, PanelResizer } from "react-window-splitter"; import { cn } from "~/utils/cn"; const ResizablePanelGroup = ({ className, ...props }: React.ComponentProps) => ( ); @@ -24,6 +26,7 @@ const ResizableHandle = ({ "focus-visible:ring-ring group relative flex w-0.75 items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 hover:w-0.75 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-offset-1 [&[data-panel-group-direction=vertical]>div]:rotate-90", className )} + size="3px" {...props} >
@@ -38,3 +41,5 @@ const ResizableHandle = ({ ); export { ResizableHandle, ResizablePanel, ResizablePanelGroup }; + +export type ResizableSnapshot = React.ComponentProps["snapshot"]; diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx index 09f6cf525..9b52b63b5 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx @@ -66,7 +66,6 @@ import { useReplaceLocation } from "~/hooks/useReplaceLocation"; import { Shortcut, useShortcutKeys } from "~/hooks/useShortcutKeys"; import { useUser } from "~/hooks/useUser"; import { RunPresenter } from "~/presenters/v3/RunPresenter.server"; -import { getResizableRunSettings, setResizableRunSettings } from "~/services/resizablePanel"; import { requireUserId } from "~/services/session.server"; import { cn } from "~/utils/cn"; import { lerp } from "~/utils/lerp"; @@ -80,8 +79,38 @@ import { } from "~/utils/pathBuilder"; import { SpanView } from "../resources.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam.spans.$spanParam/route"; import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route"; +import { getResizableSnapshot } from "~/services/resizablePanel.server"; +import { logger } from "~/services/logger.server"; +import { typedjson, UseDataFunctionReturn, useTypedLoaderData } from "remix-typedjson"; -type TraceEvent = NonNullable["trace"]>["events"][0]; +type TraceEvent = NonNullable["trace"]>["events"][0]; + +const resizableSettings = { + parent: { + autosaveId: "panel-run-parent", + handleId: "parent-handle", + main: { + id: "run", + min: "100px" as const, + }, + inspector: { + id: "inspector", + default: "300px" as const, + }, + }, + tree: { + autosaveId: "panel-run-tree", + handleId: "tree-handle", + tree: { + id: "tree", + default: "20%" as const, + }, + timeline: { + id: "timeline", + default: "80%" as const, + }, + }, +}; export const loader = async ({ request, params }: LoaderFunctionArgs) => { const userId = await requireUserId(request); @@ -96,17 +125,26 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { }); //resizable settings - const resizeSettings = await getResizableRunSettings(request); + const parent = await getResizableSnapshot(request, resizableSettings.parent.autosaveId); + const tree = await getResizableSnapshot(request, resizableSettings.tree.autosaveId); - return json({ + logger.log("Resizable snapshots", { + parent, + tree, + }); + + return typedjson({ run: result.run, trace: result.trace, maximumLiveReloadingSetting: env.MAXIMUM_LIVE_RELOADING_EVENTS, - resizeSettings, + resizable: { + parent, + tree, + }, }); }; -type LoaderData = SerializeFrom; +type LoaderData = UseDataFunctionReturn; function getSpanId(location: Location): string | undefined { const search = new URLSearchParams(location.search); @@ -114,8 +152,8 @@ function getSpanId(location: Location): string | undefined { } export default function Page() { - const { run, trace, resizeSettings, maximumLiveReloadingSetting } = - useLoaderData(); + const { run, trace, resizable, maximumLiveReloadingSetting } = + useTypedLoaderData(); const user = useUser(); const organization = useOrganization(); const project = useProject(); @@ -208,14 +246,14 @@ export default function Page() { run={run} trace={trace} maximumLiveReloadingSetting={maximumLiveReloadingSetting} - resizeSettings={resizeSettings} + resizable={resizable} /> ) : ( )} @@ -223,7 +261,7 @@ export default function Page() { ); } -function TraceView({ run, trace, maximumLiveReloadingSetting, resizeSettings }: LoaderData) { +function TraceView({ run, trace, maximumLiveReloadingSetting, resizable }: LoaderData) { const organization = useOrganization(); const project = useProject(); const { location, replaceSearchParam } = useReplaceLocation(); @@ -254,8 +292,15 @@ function TraceView({ run, trace, maximumLiveReloadingSetting, resizeSettings }: return (
- - + + - + {selectedSpanId && ( - + { - if (layout.length !== 2) return; - setResizableRunSettings(document, layout); - }} > - +
{daysSinceCompleted === undefined ? ( @@ -367,8 +415,11 @@ function NoLogsView({ run, resizeSettings }: LoaderData) { )}
- - + {" "} +
@@ -456,15 +507,13 @@ function TasksTreeView({ />
- { - if (layout.length !== 2) return; - setResizableRunSettings(document, layout); - }} - > + {/* Tree list */} - +
{parentRunFriendlyId ? ( @@ -570,9 +619,12 @@ function TasksTreeView({ />
- + {/* Timeline */} - + { + const cookie = createCookie(id, { + httpOnly: false, + secure: false, + path: "/", + }); + + try { + const header = request.headers.get("Cookie"); + const value = await cookie.parse(header); + logger.info("getResizableSnapshot", { id, value, cookie }); + if (value != null && "status" in value) { + return value as ResizableSnapshot; + } else { + return undefined; + } + } catch (error) { + console.error(error); + return undefined; + } +} diff --git a/apps/webapp/app/services/resizablePanel.ts b/apps/webapp/app/services/resizablePanel.ts deleted file mode 100644 index e3196a1c8..000000000 --- a/apps/webapp/app/services/resizablePanel.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { z } from "zod"; - -const ResizableConfig = z - .object({ layout: z.array(z.number()).optional() }) - .default({ layout: undefined }); -type ResizableConfig = z.infer; - -function getCookieValue(cookieHeader: string | null, cookieName: string): ResizableConfig { - const cookieValue = cookieHeader?.split(`${cookieName}=`)[1]?.split(";")[0]; - if (!cookieValue) { - return { layout: undefined }; - } - try { - const json = JSON.parse(cookieValue); - return ResizableConfig.parse(json); - } catch (e) { - return { layout: undefined }; - } -} - -//run page -const runResizableName = "resizable-panels:run"; - -export async function getResizableRunSettings(request: Request): Promise { - const cookieHeader = request.headers.get("Cookie"); - return getCookieValue(cookieHeader, runResizableName); -} - -export async function setResizableRunSettings(document: Document, layout: number[]) { - document.cookie = `${runResizableName}=${JSON.stringify({ layout })}`; -} diff --git a/apps/webapp/remix.config.js b/apps/webapp/remix.config.js index ee2aee289..0cd01caec 100644 --- a/apps/webapp/remix.config.js +++ b/apps/webapp/remix.config.js @@ -22,6 +22,8 @@ module.exports = { "superjson", "prismjs/components/prism-json", "prismjs/components/prism-typescript", + "react-window-splitter", + "d3-ease", ], browserNodeBuiltinsPolyfill: { modules: { path: true, os: true, crypto: true } }, watchPaths: async () => { From 1d12f8a619dc048574ef32740719b64b99da0721 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 12 Aug 2024 15:15:23 +0100 Subject: [PATCH 03/33] Use the cookie package --- .../app/services/resizablePanel.server.ts | 41 ++++++++++++------- apps/webapp/package.json | 2 + pnpm-lock.yaml | 7 +++- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/apps/webapp/app/services/resizablePanel.server.ts b/apps/webapp/app/services/resizablePanel.server.ts index 82c2f7891..f24e92770 100644 --- a/apps/webapp/app/services/resizablePanel.server.ts +++ b/apps/webapp/app/services/resizablePanel.server.ts @@ -1,28 +1,39 @@ -import { createCookie, createCookieSessionStorage } from "@remix-run/node"; +import { parse } from "cookie"; import { type ResizableSnapshot } from "~/components/primitives/Resizable"; import { logger } from "./logger.server"; export async function getResizableSnapshot( request: Request, id: string -): Promise { - const cookie = createCookie(id, { - httpOnly: false, - secure: false, - path: "/", - }); - +): Promise { try { - const header = request.headers.get("Cookie"); - const value = await cookie.parse(header); - logger.info("getResizableSnapshot", { id, value, cookie }); - if (value != null && "status" in value) { - return value as ResizableSnapshot; - } else { + const cookieHeader = request.headers.get("Cookie"); + if (!cookieHeader) { return undefined; } + + const cookies = parse(cookieHeader); + const cookieValue = cookies[id]; + + if (cookieValue) { + try { + const parsedValue = JSON.parse(cookieValue) as any; + if (typeof parsedValue === "object" && "status" in parsedValue) { + return parsedValue as ResizableSnapshot; + } + } catch (parseError) { + logger.error("getResizableSnapshot() error parsing cookie value:", { + parseError, + cookieValue, + }); + } + } + + return undefined; } catch (error) { - console.error(error); + logger.error("getResizableSnapshot() error:", { + error, + }); return undefined; } } diff --git a/apps/webapp/package.json b/apps/webapp/package.json index 77113d26f..d83e27f9d 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -108,6 +108,7 @@ "class-variance-authority": "^0.5.2", "clsx": "^1.2.1", "compression": "^1.7.4", + "cookie": "^0.6.0", "cron-parser": "^4.9.0", "cronstrue": "^2.21.0", "cross-env": "^7.0.3", @@ -193,6 +194,7 @@ "@trigger.dev/eslint-plugin": "workspace:*", "@types/bcryptjs": "^2.4.2", "@types/compression": "^1.7.2", + "@types/cookie": "^0.6.0", "@types/eslint": "^8.4.6", "@types/express": "^4.17.13", "@types/humanize-duration": "^3.27.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d7d489d94..31588c35b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -429,6 +429,9 @@ importers: compression: specifier: ^1.7.4 version: 1.7.4 + cookie: + specifier: ^0.6.0 + version: 0.6.0 cron-parser: specifier: ^4.9.0 version: 4.9.0 @@ -679,6 +682,9 @@ importers: '@types/compression': specifier: ^1.7.2 version: 1.7.2 + '@types/cookie': + specifier: ^0.6.0 + version: 0.6.0 '@types/eslint': specifier: ^8.4.6 version: 8.4.10 @@ -17050,7 +17056,6 @@ packages: /@types/cookie@0.6.0: resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - dev: false /@types/cookiejar@2.1.2: resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==} From b46698b820c35e2360593f2ef6d3e34a180106d0 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Mon, 12 Aug 2024 16:40:59 +0100 Subject: [PATCH 04/33] Resizable storybook page --- .../app/routes/storybook.resizable/route.tsx | 23 +++++++++++++++++++ apps/webapp/app/routes/storybook/route.tsx | 4 ++++ 2 files changed, 27 insertions(+) create mode 100644 apps/webapp/app/routes/storybook.resizable/route.tsx diff --git a/apps/webapp/app/routes/storybook.resizable/route.tsx b/apps/webapp/app/routes/storybook.resizable/route.tsx new file mode 100644 index 000000000..f3f430f89 --- /dev/null +++ b/apps/webapp/app/routes/storybook.resizable/route.tsx @@ -0,0 +1,23 @@ +import { + ResizableHandle, + ResizablePanel, + ResizablePanelGroup, +} from "~/components/primitives/Resizable"; + +export default function Story() { + return ( +
+ + + + + +
+ ); +} diff --git a/apps/webapp/app/routes/storybook/route.tsx b/apps/webapp/app/routes/storybook/route.tsx index ad8e61b0b..b6ac587ff 100644 --- a/apps/webapp/app/routes/storybook/route.tsx +++ b/apps/webapp/app/routes/storybook/route.tsx @@ -72,6 +72,10 @@ const stories: Story[] = [ name: "Radio group", slug: "radio-group", }, + { + name: "Resizable", + slug: "resizable", + }, { name: "Segemented control", slug: "segmented-control", From a8f725d6434ba126a64d4779cc6dd6c4ac890b07 Mon Sep 17 00:00:00 2001 From: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Mon, 12 Aug 2024 17:05:25 +0100 Subject: [PATCH 05/33] Increase indexing memory limit --- apps/kubernetes-provider/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/kubernetes-provider/src/index.ts b/apps/kubernetes-provider/src/index.ts index 9ff238235..be9a4fb9c 100644 --- a/apps/kubernetes-provider/src/index.ts +++ b/apps/kubernetes-provider/src/index.ts @@ -102,7 +102,7 @@ class KubernetesTaskOperations implements TaskOperations { resources: { limits: { cpu: "1", - memory: "1G", + memory: "2G", "ephemeral-storage": "2Gi", }, }, From 37fd0882ae017205607683a94681a6523249e533 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Tue, 13 Aug 2024 11:14:28 +0100 Subject: [PATCH 06/33] Fixed v2 usage meter displaying when on paid plan (#1255) * Fixed v2 usage meter displaying when on paid plan * Show the free usage panel only for v3 projects --- apps/webapp/app/components/navigation/SideMenu.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/webapp/app/components/navigation/SideMenu.tsx b/apps/webapp/app/components/navigation/SideMenu.tsx index e544a97b6..1ea68dd43 100644 --- a/apps/webapp/app/components/navigation/SideMenu.tsx +++ b/apps/webapp/app/components/navigation/SideMenu.tsx @@ -77,9 +77,9 @@ import { PopoverSectionHeader, } from "../primitives/Popover"; import { StepNumber } from "../primitives/StepNumber"; +import { TextLink } from "../primitives/TextLink"; import { SideMenuHeader } from "./SideMenuHeader"; import { SideMenuItem } from "./SideMenuItem"; -import { TextLink } from "../primitives/TextLink"; type SideMenuUser = Pick & { isImpersonating: boolean }; type SideMenuProject = Pick< @@ -106,6 +106,9 @@ export function SideMenu({ user, project, organization, organizations }: SideMen const currentPlan = useCurrentPlan(); const { isManagedCloud } = useFeatures(); + const isV3Project = project.version === "V3"; + const isFreeV3User = currentPlan?.v3Subscription?.isPaying === false; + useEffect(() => { const handleScroll = () => { if (borderRef.current) { @@ -334,7 +337,7 @@ export function SideMenu({ user, project, organization, organizations }: SideMen } /> - {currentPlan?.v3Subscription?.isPaying === false && ( + {isV3Project && isFreeV3User && ( Date: Tue, 13 Aug 2024 11:43:46 +0100 Subject: [PATCH 07/33] Concurrency page and more accurate tracking (#1252) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial TaskRunConcurrencyTracker implementation * MARQS calls a subscriber to events * When enqueuing add the extra required metadata * Track concurrency per environment for tasks too * Admin page for global concurrency * Use the new concurrency tracker on the tasks page * Useful performance test task * getAllTaskIdentifiers() * New page for concurrency * BackgroundWorkerTask index for quick lookup of task identifiers * Added a way to get concurrency for environments * Added upgrade/request more concurrency button * Queued task column working * Use defer and suspense * Added queue column to the concurrency environments table * Some comments added for clarity * Fixed bad log message * Sidemenu: move lower and rename to “Concurrency limits” * Only show the environments, not tasks. Renamed to “Concurrency limits” --- .../app/components/admin/debugTooltip.tsx | 12 +- .../app/components/navigation/SideMenu.tsx | 10 + .../app/models/runtimeEnvironment.server.ts | 2 +- apps/webapp/app/models/task.server.ts | 22 +- .../v3/ConcurrencyPresenter.server.ts | 98 +++++++ .../presenters/v3/RunListPresenter.server.ts | 12 +- .../presenters/v3/TaskListPresenter.server.ts | 52 ++-- .../route.tsx | 138 ++++++++++ apps/webapp/app/routes/admin.concurrency.tsx | 38 +++ apps/webapp/app/routes/admin.orgs.tsx | 11 +- apps/webapp/app/routes/admin.tsx | 13 +- apps/webapp/app/utils/pathBuilder.ts | 4 + apps/webapp/app/v3/marqs/index.server.ts | 12 + apps/webapp/app/v3/marqs/types.ts | 9 +- .../v3/services/enqueueDelayedRun.server.ts | 8 +- .../services/executeTasksWaitingForDeploy.ts | 3 + .../app/v3/services/resumeBatchRun.server.ts | 3 + .../services/resumeTaskDependency.server.ts | 3 + .../taskRunConcurrencyTracker.server.ts | 245 ++++++++++++++++++ .../app/v3/services/triggerTask.server.ts | 8 +- .../migration.sql | 2 + packages/database/prisma/schema.prisma | 2 + .../v3-catalog/src/trigger/performance.ts | 23 ++ 23 files changed, 665 insertions(+), 65 deletions(-) create mode 100644 apps/webapp/app/presenters/v3/ConcurrencyPresenter.server.ts create mode 100644 apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.concurrency/route.tsx create mode 100644 apps/webapp/app/routes/admin.concurrency.tsx create mode 100644 apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts create mode 100644 packages/database/prisma/migrations/20240809153150_background_worker_task_add_index_for_quick_lookup_of_task_identifiers/migration.sql create mode 100644 references/v3-catalog/src/trigger/performance.ts diff --git a/apps/webapp/app/components/admin/debugTooltip.tsx b/apps/webapp/app/components/admin/debugTooltip.tsx index 2ae9a6914..f761e23fa 100644 --- a/apps/webapp/app/components/admin/debugTooltip.tsx +++ b/apps/webapp/app/components/admin/debugTooltip.tsx @@ -1,20 +1,16 @@ -import * as Property from "~/components/primitives/PropertyTable"; import { ShieldCheckIcon } from "@heroicons/react/20/solid"; +import * as Property from "~/components/primitives/PropertyTable"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "~/components/primitives/Tooltip"; -import { - useIsImpersonating, - useOptionalOrganization, - useOrganization, -} from "~/hooks/useOrganizations"; -import { useOptionalProject, useProject } from "~/hooks/useProject"; +import { useIsImpersonating, useOptionalOrganization } from "~/hooks/useOrganizations"; +import { useOptionalProject } from "~/hooks/useProject"; import { useHasAdminAccess, useUser } from "~/hooks/useUser"; -export function AdminDebugTooltip({ children }: { children: React.ReactNode }) { +export function AdminDebugTooltip({ children }: { children?: React.ReactNode }) { const hasAdminAccess = useHasAdminAccess(); const isImpersonating = useIsImpersonating(); diff --git a/apps/webapp/app/components/navigation/SideMenu.tsx b/apps/webapp/app/components/navigation/SideMenu.tsx index 1ea68dd43..f03e37613 100644 --- a/apps/webapp/app/components/navigation/SideMenu.tsx +++ b/apps/webapp/app/components/navigation/SideMenu.tsx @@ -9,6 +9,7 @@ import { CursorArrowRaysIcon, IdentificationIcon, KeyIcon, + RectangleStackIcon, ServerStackIcon, ShieldCheckIcon, SignalIcon, @@ -46,6 +47,7 @@ import { projectTriggersPath, v3ApiKeysPath, v3BillingPath, + v3ConcurrencyPath, v3DeploymentsPath, v3EnvironmentVariablesPath, v3ProjectAlertsPath, @@ -605,6 +607,7 @@ function V3ProjectSideMenu({ to={v3EnvironmentVariablesPath(organization, project)} data-action="environment variables" /> + )} + ` + SELECT DISTINCT(slug), "triggerSource" + FROM ${sqlDatabaseSchema}."BackgroundWorkerTask" + WHERE "projectId" = ${projectId} + ORDER BY slug ASC;`; +} diff --git a/apps/webapp/app/presenters/v3/ConcurrencyPresenter.server.ts b/apps/webapp/app/presenters/v3/ConcurrencyPresenter.server.ts new file mode 100644 index 000000000..af233ee33 --- /dev/null +++ b/apps/webapp/app/presenters/v3/ConcurrencyPresenter.server.ts @@ -0,0 +1,98 @@ +import { QUEUED_STATUSES } from "~/components/runs/v3/TaskRunStatus"; +import { Prisma, sqlDatabaseSchema } from "~/db.server"; +import { type Project } from "~/models/project.server"; +import { + displayableEnvironment, + type DisplayableInputEnvironment, +} from "~/models/runtimeEnvironment.server"; +import { type User } from "~/models/user.server"; +import { getLimit } from "~/services/platform.v3.server"; +import { sortEnvironments } from "~/utils/environmentSort"; +import { concurrencyTracker } from "~/v3/services/taskRunConcurrencyTracker.server"; +import { BasePresenter } from "./basePresenter.server"; + +export type Environment = Awaited< + ReturnType +>[number]; + +export class ConcurrencyPresenter extends BasePresenter { + public async call({ userId, projectSlug }: { userId: User["id"]; projectSlug: Project["slug"] }) { + const project = await this._replica.project.findFirst({ + select: { + id: true, + organizationId: true, + environments: { + select: { + id: true, + apiKey: true, + pkApiKey: true, + type: true, + slug: true, + updatedAt: true, + orgMember: { + select: { + user: { select: { id: true, name: true, displayName: true } }, + }, + }, + maximumConcurrencyLimit: true, + }, + }, + }, + where: { + slug: projectSlug, + organization: { + members: { + some: { + userId, + }, + }, + }, + }, + }); + + if (!project) { + throw new Error(`Project not found: ${projectSlug}`); + } + + return { + environments: this.environmentConcurrency(project.id, userId, project.environments), + }; + } + + async environmentConcurrency( + projectId: string, + userId: string, + environments: (DisplayableInputEnvironment & { maximumConcurrencyLimit: number })[] + ) { + const environmentConcurrency = await concurrencyTracker.environmentConcurrentRunCounts( + projectId, + environments.map((env) => env.id) + ); + + const queued = await this._replica.$queryRaw< + { + runtimeEnvironmentId: string; + count: BigInt; + }[] + >` +SELECT + "runtimeEnvironmentId", + COUNT(*) +FROM + ${sqlDatabaseSchema}."TaskRun" as tr +WHERE + tr."projectId" = ${projectId} + AND tr."status" = ANY(ARRAY[${Prisma.join(QUEUED_STATUSES)}]::\"TaskRunStatus\"[]) +GROUP BY + tr."runtimeEnvironmentId";`; + + const sortedEnvironments = sortEnvironments(environments).map((environment) => ({ + ...displayableEnvironment(environment, userId), + concurrencyLimit: environment.maximumConcurrencyLimit, + concurrency: environmentConcurrency[environment.id] ?? 0, + queued: Number(queued.find((q) => q.runtimeEnvironmentId === environment.id)?.count ?? 0), + })); + + return sortedEnvironments; + } +} diff --git a/apps/webapp/app/presenters/v3/RunListPresenter.server.ts b/apps/webapp/app/presenters/v3/RunListPresenter.server.ts index a11f73e91..51563e26a 100644 --- a/apps/webapp/app/presenters/v3/RunListPresenter.server.ts +++ b/apps/webapp/app/presenters/v3/RunListPresenter.server.ts @@ -6,6 +6,7 @@ import { sqlDatabaseSchema } from "~/db.server"; import { displayableEnvironment } from "~/models/runtimeEnvironment.server"; import { isCancellableRunStatus } from "~/v3/taskStatus"; import { BasePresenter } from "./basePresenter.server"; +import { getAllTaskIdentifiers } from "~/models/task.server"; export type RunListOptions = { userId?: string; @@ -97,16 +98,7 @@ export class RunListPresenter extends BasePresenter { }); //get all possible tasks - const possibleTasksAsync = this._replica.$queryRaw< - { - slug: string; - triggerSource: TaskTriggerSource; - }[] - >` - SELECT DISTINCT(slug), "triggerSource" - FROM ${sqlDatabaseSchema}."BackgroundWorkerTask" - WHERE "projectId" = ${project.id} - ORDER BY slug ASC;`; + const possibleTasksAsync = getAllTaskIdentifiers(this._replica, project.id); //get possible bulk actions const bulkActionsAsync = this._replica.bulkActionGroup.findMany({ diff --git a/apps/webapp/app/presenters/v3/TaskListPresenter.server.ts b/apps/webapp/app/presenters/v3/TaskListPresenter.server.ts index 45fd17bf5..90441e507 100644 --- a/apps/webapp/app/presenters/v3/TaskListPresenter.server.ts +++ b/apps/webapp/app/presenters/v3/TaskListPresenter.server.ts @@ -1,9 +1,9 @@ +import { Prisma } from "@trigger.dev/database"; import type { RuntimeEnvironmentType, TaskTriggerSource, TaskRunStatus as TaskRunStatusType, } from "@trigger.dev/database"; -import { Prisma } from "@trigger.dev/database"; import { QUEUED_STATUSES, RUNNING_STATUSES } from "~/components/runs/v3/TaskRunStatus"; import { sqlDatabaseSchema } from "~/db.server"; import type { Organization } from "~/models/organization.server"; @@ -20,6 +20,7 @@ import { logger } from "~/services/logger.server"; import { BasePresenter } from "./basePresenter.server"; import { TaskRunStatus } from "~/database-types"; import { CURRENT_DEPLOYMENT_LABEL } from "~/consts"; +import { concurrencyTracker } from "~/v3/services/taskRunConcurrencyTracker.server"; export type Task = { slug: string; @@ -114,7 +115,7 @@ export class TaskListPresenter extends BasePresenter { JOIN ${sqlDatabaseSchema}."BackgroundWorkerTask" tasks ON tasks."workerId" = workers.id ORDER BY slug ASC;`; - //group by the task identifier (task.slug). Add the latestRun and add all the environments. + //group by the task identifier (task.slug). const outputTasks = tasks.reduce((acc, task) => { const environment = project.environments.find((env) => env.id === task.runtimeEnvironmentId); if (!environment) { @@ -251,51 +252,40 @@ export class TaskListPresenter extends BasePresenter { return {}; } - const statuses = await this._replica.$queryRaw< + const concurrencies = await concurrencyTracker.taskConcurrentRunCounts(projectId, tasks); + + const queued = await this._replica.$queryRaw< { taskIdentifier: string; - status: TaskRunStatusType; count: BigInt; }[] >` SELECT - tr."taskIdentifier", - tr."status", + tr."taskIdentifier", COUNT(*) FROM ${sqlDatabaseSchema}."TaskRun" as tr WHERE tr."taskIdentifier" IN (${Prisma.join(tasks)}) AND tr."projectId" = ${projectId} - AND tr."status" IN ('PENDING', 'WAITING_FOR_DEPLOY', 'EXECUTING', 'RETRYING_AFTER_FAILURE', 'WAITING_TO_RESUME') + AND tr."status" = ANY(ARRAY[${Prisma.join(QUEUED_STATUSES)}]::\"TaskRunStatus\"[]) GROUP BY - tr."taskIdentifier", - tr."status" + tr."taskIdentifier" ORDER BY - tr."taskIdentifier" ASC, - tr."status" ASC;`; + tr."taskIdentifier" ASC`; - return statuses.reduce((acc, a) => { - let existingTask = acc[a.taskIdentifier]; + //create an object combining the queued and concurrency counts + const result: Record = {}; + for (const task of tasks) { + const concurrency = concurrencies[task] ?? 0; + const queuedCount = queued.find((q) => q.taskIdentifier === task)?.count ?? 0; - if (!existingTask) { - existingTask = { - queued: 0, - running: 0, - }; - - acc[a.taskIdentifier] = existingTask; - } - - if (QUEUED_STATUSES.includes(a.status)) { - existingTask.queued += Number(a.count); - } - if (RUNNING_STATUSES.includes(a.status)) { - existingTask.running += Number(a.count); - } - - return acc; - }, {} as Record); + result[task] = { + queued: Number(queuedCount), + running: concurrency, + }; + } + return result; } async #getAverageDurations(tasks: string[], projectId: string) { diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.concurrency/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.concurrency/route.tsx new file mode 100644 index 000000000..b09446077 --- /dev/null +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.concurrency/route.tsx @@ -0,0 +1,138 @@ +import { ArrowUpCircleIcon, BookOpenIcon } from "@heroicons/react/20/solid"; +import { Await } from "@remix-run/react"; +import { type LoaderFunctionArgs } from "@remix-run/server-runtime"; +import { Suspense } from "react"; +import { typeddefer, useTypedLoaderData } from "remix-typedjson"; +import { AdminDebugTooltip } from "~/components/admin/debugTooltip"; +import { EnvironmentLabel } from "~/components/environments/EnvironmentLabel"; +import { Feedback } from "~/components/Feedback"; +import { PageBody, PageContainer } from "~/components/layout/AppLayout"; +import { Button, LinkButton } from "~/components/primitives/Buttons"; +import { Header2 } from "~/components/primitives/Headers"; +import { NavBar, PageAccessories, PageTitle } from "~/components/primitives/PageHeader"; +import { Spinner } from "~/components/primitives/Spinner"; +import { + Table, + TableBody, + TableCell, + TableHeader, + TableHeaderCell, + TableRow, +} from "~/components/primitives/Table"; +import { useOrganization } from "~/hooks/useOrganizations"; +import { + ConcurrencyPresenter, + type Environment, +} from "~/presenters/v3/ConcurrencyPresenter.server"; +import { requireUserId } from "~/services/session.server"; +import { docsPath, ProjectParamSchema, v3BillingPath } from "~/utils/pathBuilder"; +import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route"; + +export const loader = async ({ request, params }: LoaderFunctionArgs) => { + const userId = await requireUserId(request); + const { projectParam } = ProjectParamSchema.parse(params); + + try { + const presenter = new ConcurrencyPresenter(); + const result = await presenter.call({ + userId, + projectSlug: projectParam, + }); + + return typeddefer(result); + } catch (error) { + console.error(error); + throw new Response(undefined, { + status: 400, + statusText: "Something went wrong, if this problem persists please contact support.", + }); + } +}; + +export default function Page() { + const { environments } = useTypedLoaderData(); + + const organization = useOrganization(); + const plan = useCurrentPlan(); + + return ( + + + + + + + Concurrency docs + + + + +
+
+
+ Environments + {plan ? ( + plan?.v3Subscription?.plan?.limits.concurrentRuns.canExceed ? ( + + Request more concurrency + + } + defaultValue="help" + /> + ) : ( + + Upgrade for more concurrency + + ) + ) : null} +
+ + + + Environment + Queued + Running + Concurrency limit + + + + }> + Error loading environments

}> + {(environments) => } +
+
+
+
+
+
+
+
+ ); +} + +function EnvironmentsTable({ environments }: { environments: Environment[] }) { + return ( + <> + {environments.map((environment) => ( + + + + + {environment.queued} + {environment.concurrency} + {environment.concurrencyLimit} + + ))} + + ); +} diff --git a/apps/webapp/app/routes/admin.concurrency.tsx b/apps/webapp/app/routes/admin.concurrency.tsx new file mode 100644 index 000000000..b0fe1484b --- /dev/null +++ b/apps/webapp/app/routes/admin.concurrency.tsx @@ -0,0 +1,38 @@ +import type { LoaderFunctionArgs } from "@remix-run/server-runtime"; +import { redirect, typedjson, useTypedLoaderData } from "remix-typedjson"; +import { Header1 } from "~/components/primitives/Headers"; +import { Paragraph } from "~/components/primitives/Paragraph"; +import { requireUser } from "~/services/session.server"; +import { concurrencyTracker } from "~/v3/services/taskRunConcurrencyTracker.server"; + +export const loader = async ({ request, params }: LoaderFunctionArgs) => { + const user = await requireUser(request); + if (!user.admin) { + return redirect("/"); + } + + const deployedConcurrency = await concurrencyTracker.globalConcurrentRunCount(true); + const devConcurrency = await concurrencyTracker.globalConcurrentRunCount(false); + + return typedjson({ deployedConcurrency, devConcurrency }); +}; + +export default function AdminDashboardRoute() { + const { deployedConcurrency, devConcurrency } = useTypedLoaderData(); + + return ( +
+
+ Dev + {devConcurrency} +
+
+ Deployed + {deployedConcurrency} +
+
+ ); +} diff --git a/apps/webapp/app/routes/admin.orgs.tsx b/apps/webapp/app/routes/admin.orgs.tsx index b10dd3701..03841ba94 100644 --- a/apps/webapp/app/routes/admin.orgs.tsx +++ b/apps/webapp/app/routes/admin.orgs.tsx @@ -1,7 +1,7 @@ import { MagnifyingGlassIcon } from "@heroicons/react/20/solid"; import { Form } from "@remix-run/react"; import type { LoaderFunctionArgs } from "@remix-run/server-runtime"; -import { typedjson, useTypedLoaderData } from "remix-typedjson"; +import { redirect, typedjson, useTypedLoaderData } from "remix-typedjson"; import { z } from "zod"; import { Button, LinkButton } from "~/components/primitives/Buttons"; import { Input } from "~/components/primitives/Input"; @@ -17,7 +17,7 @@ import { TableRow, } from "~/components/primitives/Table"; import { adminGetOrganizations } from "~/models/admin.server"; -import { requireUserId } from "~/services/session.server"; +import { requireUser, requireUserId } from "~/services/session.server"; import { createSearchParams } from "~/utils/searchParams"; export const SearchParams = z.object({ @@ -28,13 +28,16 @@ export const SearchParams = z.object({ export type SearchParams = z.infer; export const loader = async ({ request, params }: LoaderFunctionArgs) => { - const userId = await requireUserId(request); + const user = await requireUser(request); + if (!user.admin) { + return redirect("/"); + } const searchParams = createSearchParams(request.url, SearchParams); if (!searchParams.success) { throw new Error(searchParams.error); } - const result = await adminGetOrganizations(userId, searchParams.params.getAll()); + const result = await adminGetOrganizations(user.id, searchParams.params.getAll()); return typedjson(result); }; diff --git a/apps/webapp/app/routes/admin.tsx b/apps/webapp/app/routes/admin.tsx index e7803e353..ac8e56c85 100644 --- a/apps/webapp/app/routes/admin.tsx +++ b/apps/webapp/app/routes/admin.tsx @@ -3,15 +3,10 @@ import type { LoaderFunctionArgs } from "@remix-run/server-runtime"; import { redirect, typedjson } from "remix-typedjson"; import { LinkButton } from "~/components/primitives/Buttons"; import { Tabs } from "~/components/primitives/Tabs"; -import { getUser, requireUserId } from "~/services/session.server"; +import { requireUser } from "~/services/session.server"; export async function loader({ request }: LoaderFunctionArgs) { - await requireUserId(request); - const user = await getUser(request); - if (user == null) { - return redirect("/"); - } - + const user = await requireUser(request); if (!user.admin) { return redirect("/"); } @@ -33,6 +28,10 @@ export default function Page() { label: "Organizations", to: "/admin/orgs", }, + { + label: "Concurrency", + to: "/admin/concurrency", + }, ]} layoutId={"admin"} /> diff --git a/apps/webapp/app/utils/pathBuilder.ts b/apps/webapp/app/utils/pathBuilder.ts index a1a5275e2..e6f632f20 100644 --- a/apps/webapp/app/utils/pathBuilder.ts +++ b/apps/webapp/app/utils/pathBuilder.ts @@ -323,6 +323,10 @@ export function v3EnvironmentVariablesPath(organization: OrgForPath, project: Pr return `${v3ProjectPath(organization, project)}/environment-variables`; } +export function v3ConcurrencyPath(organization: OrgForPath, project: ProjectForPath) { + return `${v3ProjectPath(organization, project)}/concurrency`; +} + export function v3NewEnvironmentVariablesPath(organization: OrgForPath, project: ProjectForPath) { return `${v3EnvironmentVariablesPath(organization, project)}/new`; } diff --git a/apps/webapp/app/v3/marqs/index.server.ts b/apps/webapp/app/v3/marqs/index.server.ts index 159ccd3a2..fb7381f67 100644 --- a/apps/webapp/app/v3/marqs/index.server.ts +++ b/apps/webapp/app/v3/marqs/index.server.ts @@ -26,11 +26,13 @@ import { MarQSKeyProducer, MarQSQueuePriorityStrategy, MessagePayload, + MessageQueueSubscriber, QueueCapacities, QueueRange, VisibilityTimeoutStrategy, } from "./types"; import { V3VisibilityTimeout } from "./v3VisibilityTimeout.server"; +import { concurrencyTracker } from "../services/taskRunConcurrencyTracker.server"; const KEY_PREFIX = "marqs:"; @@ -60,6 +62,7 @@ export type MarQSOptions = { visibilityTimeoutStrategy: VisibilityTimeoutStrategy; enableRebalancing?: boolean; verbose?: boolean; + subscriber?: MessageQueueSubscriber; }; /** @@ -207,6 +210,8 @@ export class MarQS { }); await this.#callEnqueueMessage(messagePayload); + + await this.options.subscriber?.messageEnqueued(messagePayload); }, { kind: SpanKind.PRODUCER, @@ -264,6 +269,8 @@ export class MarQS { [SemanticAttributes.CONCURRENCY_KEY]: message.concurrencyKey, [SemanticAttributes.PARENT_QUEUE]: message.parentQueue, }); + + await this.options.subscriber?.messageDequeued(message); } else { logger.error(`Failed to read message, undoing the dequeueing of the message`, { messageData, @@ -427,6 +434,8 @@ export class MarQS { orgConcurrencyKey: this.keys.orgCurrentConcurrencyKeyFromQueue(message.queue), messageId, }); + + await this.options.subscriber?.messageAcked(message); }, { kind: SpanKind.CONSUMER, @@ -580,6 +589,8 @@ export class MarQS { messageId, messageScore: retryAt, }); + + await this.options.subscriber?.messageNacked(message); }, { kind: SpanKind.CONSUMER, @@ -1721,6 +1732,7 @@ function getMarQSClient() { defaultOrgConcurrency: env.DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT, visibilityTimeoutInMs: 120 * 1000, // 2 minutes, enableRebalancing: !env.MARQS_DISABLE_REBALANCING, + subscriber: concurrencyTracker, }); } else { console.warn( diff --git a/apps/webapp/app/v3/marqs/types.ts b/apps/webapp/app/v3/marqs/types.ts index fe5331b35..559b4b23f 100644 --- a/apps/webapp/app/v3/marqs/types.ts +++ b/apps/webapp/app/v3/marqs/types.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { AuthenticatedEnvironment } from "~/services/apiAuth.server"; +import { type AuthenticatedEnvironment } from "~/services/apiAuth.server"; export type QueueCapacity = { current: number; @@ -92,6 +92,13 @@ export const MessagePayload = z.object({ export type MessagePayload = z.infer; +export interface MessageQueueSubscriber { + messageEnqueued(message: MessagePayload): Promise; + messageDequeued(message: MessagePayload): Promise; + messageAcked(message: MessagePayload): Promise; + messageNacked(message: MessagePayload): Promise; +} + export interface VisibilityTimeoutStrategy { heartbeat(messageId: string, timeoutInMs: number): Promise; cancelHeartbeat(messageId: string): Promise; diff --git a/apps/webapp/app/v3/services/enqueueDelayedRun.server.ts b/apps/webapp/app/v3/services/enqueueDelayedRun.server.ts index 5ae916a54..12beb589f 100644 --- a/apps/webapp/app/v3/services/enqueueDelayedRun.server.ts +++ b/apps/webapp/app/v3/services/enqueueDelayedRun.server.ts @@ -65,7 +65,13 @@ export class EnqueueDelayedRunService extends BaseService { run.runtimeEnvironment, run.queue, run.id, - { type: "EXECUTE", taskIdentifier: run.taskIdentifier }, + { + type: "EXECUTE", + taskIdentifier: run.taskIdentifier, + projectId: run.runtimeEnvironment.projectId, + environmentId: run.runtimeEnvironment.id, + environmentType: run.runtimeEnvironment.type, + }, run.concurrencyKey ?? undefined ); } diff --git a/apps/webapp/app/v3/services/executeTasksWaitingForDeploy.ts b/apps/webapp/app/v3/services/executeTasksWaitingForDeploy.ts index dbecf395b..cc11f93e4 100644 --- a/apps/webapp/app/v3/services/executeTasksWaitingForDeploy.ts +++ b/apps/webapp/app/v3/services/executeTasksWaitingForDeploy.ts @@ -79,6 +79,9 @@ export class ExecuteTasksWaitingForDeployService extends BaseService { { type: "EXECUTE", taskIdentifier: run.taskIdentifier, + projectId: backgroundWorker.runtimeEnvironment.projectId, + environmentId: backgroundWorker.runtimeEnvironment.id, + environmentType: backgroundWorker.runtimeEnvironment.type, }, run.concurrencyKey ?? undefined, Date.now() + i * 5 // slight delay to help preserve order diff --git a/apps/webapp/app/v3/services/resumeBatchRun.server.ts b/apps/webapp/app/v3/services/resumeBatchRun.server.ts index 481306b2f..29a9b26bb 100644 --- a/apps/webapp/app/v3/services/resumeBatchRun.server.ts +++ b/apps/webapp/app/v3/services/resumeBatchRun.server.ts @@ -80,6 +80,9 @@ export class ResumeBatchRunService extends BaseService { completedAttemptIds: [sourceTaskAttemptId], resumableAttemptId: batchRun.dependentTaskAttempt.id, checkpointEventId: batchRun.checkpointEventId, + projectId: batchRun.dependentTaskAttempt.runtimeEnvironment.projectId, + environmentId: batchRun.dependentTaskAttempt.runtimeEnvironment.id, + environmentType: batchRun.dependentTaskAttempt.runtimeEnvironment.type, }, dependentRun.concurrencyKey ?? undefined ); diff --git a/apps/webapp/app/v3/services/resumeTaskDependency.server.ts b/apps/webapp/app/v3/services/resumeTaskDependency.server.ts index fd1dd9af5..29f36eb8b 100644 --- a/apps/webapp/app/v3/services/resumeTaskDependency.server.ts +++ b/apps/webapp/app/v3/services/resumeTaskDependency.server.ts @@ -57,6 +57,9 @@ export class ResumeTaskDependencyService extends BaseService { completedAttemptIds: [sourceTaskAttemptId], resumableAttemptId: dependency.dependentAttempt.id, checkpointEventId: dependency.checkpointEventId, + projectId: dependency.taskRun.runtimeEnvironment.projectId, + environmentId: dependency.taskRun.runtimeEnvironment.id, + environmentType: dependency.taskRun.runtimeEnvironment.type, }, dependentRun.concurrencyKey ?? undefined ); diff --git a/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts b/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts new file mode 100644 index 000000000..4711033e5 --- /dev/null +++ b/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts @@ -0,0 +1,245 @@ +import { env } from "~/env.server"; +import Redis, { type RedisOptions } from "ioredis"; +import { singleton } from "~/utils/singleton"; +import { type MessagePayload, type MessageQueueSubscriber } from "../marqs/types"; +import { z } from "zod"; +import { logger } from "~/services/logger.server"; + +type Options = { + redis: RedisOptions; +}; + +const ConcurrentMessageData = z.object({ + taskIdentifier: z.string(), + projectId: z.string(), + environmentId: z.string(), + environmentType: z.string(), +}); + +class TaskRunConcurrencyTracker implements MessageQueueSubscriber { + private redis: Redis; + + constructor(config: Options) { + this.redis = new Redis(config.redis); + } + + async messageEnqueued(message: MessagePayload): Promise {} + + async messageDequeued(message: MessagePayload): Promise { + const data = this.getMessageData(message); + if (!data) { + logger.info( + `TaskRunConcurrencyTracker.messageDequeued(): could not parse message data`, + message + ); + return; + } + + await this.executionStarted({ + projectId: data.projectId, + taskId: data.taskIdentifier, + runId: message.messageId, + environmentId: data.environmentId, + deployed: data.environmentType !== "DEVELOPMENT", + }); + } + + async messageAcked(message: MessagePayload): Promise { + const data = this.getMessageData(message); + if (!data) { + logger.info( + `TaskRunConcurrencyTracker.messageAcked(): could not parse message data`, + message + ); + return; + } + + await this.executionFinished({ + projectId: data.projectId, + taskId: data.taskIdentifier, + runId: message.messageId, + environmentId: data.environmentId, + deployed: data.environmentType !== "DEVELOPMENT", + }); + } + + async messageNacked(message: MessagePayload): Promise { + const data = this.getMessageData(message); + if (!data) { + logger.info( + `TaskRunConcurrencyTracker.messageNacked(): could not parse message data`, + message + ); + return; + } + + await this.executionFinished({ + projectId: data.projectId, + taskId: data.taskIdentifier, + runId: message.messageId, + environmentId: data.environmentId, + deployed: data.environmentType !== "DEVELOPMENT", + }); + } + + private getMessageData(message: MessagePayload) { + const result = ConcurrentMessageData.safeParse(message.data); + if (result.success) { + return result.data; + } + return; + } + + private async executionStarted({ + projectId, + taskId, + runId, + environmentId, + deployed, + }: { + projectId: string; + taskId: string; + runId: string; + environmentId: string; + deployed: boolean; + }): Promise { + const pipeline = this.redis.pipeline(); + + pipeline.sadd(this.getTaskKey(projectId, taskId), runId); + pipeline.sadd(this.getTaskEnvironmentKey(projectId, taskId, environmentId), runId); + pipeline.sadd(this.getEnvironmentKey(projectId, environmentId), runId); + pipeline.sadd(this.getGlobalKey(deployed), runId); + + await pipeline.exec(); + } + + private async executionFinished({ + projectId, + taskId, + runId, + environmentId, + deployed, + }: { + projectId: string; + taskId: string; + runId: string; + environmentId: string; + deployed: boolean; + }): Promise { + const pipeline = this.redis.pipeline(); + + pipeline.srem(this.getTaskKey(projectId, taskId), runId); + pipeline.srem(this.getTaskEnvironmentKey(projectId, taskId, environmentId), runId); + pipeline.srem(this.getEnvironmentKey(projectId, environmentId), runId); + pipeline.srem(this.getGlobalKey(deployed), runId); + + await pipeline.exec(); + } + + async taskConcurrentRunCount(projectId: string, taskId: string): Promise { + return await this.redis.scard(this.getTaskKey(projectId, taskId)); + } + + async globalConcurrentRunCount(deployed: boolean): Promise { + return await this.redis.scard(this.getGlobalKey(deployed)); + } + + async currentlyExecutingRuns(projectId: string, taskId: string): Promise { + return await this.redis.smembers(this.getTaskKey(projectId, taskId)); + } + + private async getTaskCounts(projectId: string, taskIds: string[]): Promise { + const pipeline = this.redis.pipeline(); + taskIds.forEach((taskId) => { + pipeline.scard(this.getTaskKey(projectId, taskId)); + }); + const results = await pipeline.exec(); + if (!results) { + return []; + } + return results.map(([err, count]) => { + if (err) { + console.error("Error in getTaskCounts:", err); + return 0; + } + return count as number; + }); + } + + async projectTotalConcurrentRunCount(projectId: string, taskIds: string[]): Promise { + const counts = await this.getTaskCounts(projectId, taskIds); + return counts.reduce((total, count) => total + count, 0); + } + + async taskConcurrentRunCounts( + projectId: string, + taskIds: string[] + ): Promise> { + const counts = await this.getTaskCounts(projectId, taskIds); + return taskIds.reduce((acc, taskId, index) => { + acc[taskId] = counts[index]; + return acc; + }, {} as Record); + } + + async environmentConcurrentRunCounts( + projectId: string, + environmentIds: string[] + ): Promise> { + const pipeline = this.redis.pipeline(); + environmentIds.forEach((environmentId) => { + pipeline.scard(this.getEnvironmentKey(projectId, environmentId)); + }); + const results = await pipeline.exec(); + if (!results) { + return Object.fromEntries(environmentIds.map((id) => [id, 0])); + } + + return results.reduce((acc, [err, count], index) => { + if (err) { + console.error("Error in environmentConcurrentRunCounts:", err); + return acc; + } + acc[environmentIds[index]] = count as number; + return acc; + }, {} as Record); + } + + private getTaskKey(projectId: string, taskId: string): string { + return `project:${projectId}:task:${taskId}`; + } + + private getTaskEnvironmentKey(projectId: string, taskId: string, environmentId: string): string { + return `project:${projectId}:task:${taskId}:env:${environmentId}`; + } + + private getGlobalKey(deployed: boolean): string { + return `global:${deployed ? "deployed" : "dev"}`; + } + + private getEnvironmentKey(projectId: string, environmentId: string): string { + return `project:${projectId}:env:${environmentId}`; + } +} + +export const concurrencyTracker = singleton("concurrency-tracker", getTracker); + +function getTracker() { + if (!env.REDIS_HOST || !env.REDIS_PORT) { + throw new Error( + "Could not initialize TaskRunConcurrencyTracker because process.env.REDIS_HOST and process.env.REDIS_PORT are required to be set. " + ); + } + + return new TaskRunConcurrencyTracker({ + redis: { + keyPrefix: "concurrencytracker:", + port: env.REDIS_PORT, + host: env.REDIS_HOST, + username: env.REDIS_USERNAME, + password: env.REDIS_PASSWORD, + enableAutoPipelining: true, + ...(env.REDIS_TLS_DISABLED === "true" ? {} : { tls: {} }), + }, + }); +} diff --git a/apps/webapp/app/v3/services/triggerTask.server.ts b/apps/webapp/app/v3/services/triggerTask.server.ts index 4e4a22b20..ddc816001 100644 --- a/apps/webapp/app/v3/services/triggerTask.server.ts +++ b/apps/webapp/app/v3/services/triggerTask.server.ts @@ -392,7 +392,13 @@ export class TriggerTaskService extends BaseService { environment, run.queue, run.id, - { type: "EXECUTE", taskIdentifier: taskId }, + { + type: "EXECUTE", + taskIdentifier: taskId, + projectId: environment.projectId, + environmentId: environment.id, + environmentType: environment.type, + }, body.options?.concurrencyKey ); } diff --git a/packages/database/prisma/migrations/20240809153150_background_worker_task_add_index_for_quick_lookup_of_task_identifiers/migration.sql b/packages/database/prisma/migrations/20240809153150_background_worker_task_add_index_for_quick_lookup_of_task_identifiers/migration.sql new file mode 100644 index 000000000..0e1c9d59b --- /dev/null +++ b/packages/database/prisma/migrations/20240809153150_background_worker_task_add_index_for_quick_lookup_of_task_identifiers/migration.sql @@ -0,0 +1,2 @@ +-- CreateIndex +CREATE INDEX "BackgroundWorkerTask_projectId_slug_idx" ON "BackgroundWorkerTask"("projectId", "slug"); diff --git a/packages/database/prisma/schema.prisma b/packages/database/prisma/schema.prisma index fbea2bb98..8fdbdd596 100644 --- a/packages/database/prisma/schema.prisma +++ b/packages/database/prisma/schema.prisma @@ -1602,6 +1602,8 @@ model BackgroundWorkerTask { triggerSource TaskTriggerSource @default(STANDARD) @@unique([workerId, slug]) + // Quick lookup of task identifiers + @@index([projectId, slug]) } enum TaskTriggerSource { diff --git a/references/v3-catalog/src/trigger/performance.ts b/references/v3-catalog/src/trigger/performance.ts new file mode 100644 index 000000000..e9f0d8ed4 --- /dev/null +++ b/references/v3-catalog/src/trigger/performance.ts @@ -0,0 +1,23 @@ +import { logger, task } from "@trigger.dev/sdk/v3"; + +export const performance = task({ + id: "performance", + run: async ({ count, subtaskDuration = 30_000 }: { count: number; subtaskDuration?: number }) => { + const payloads = Array.from({ length: count }, (_, i) => ({ + payload: { + durationMs: subtaskDuration, + }, + })); + + await longTask.batchTrigger(payloads); + }, +}); + +export const longTask = task({ + id: "long-task", + run: async ({ durationMs }: { durationMs: number }) => { + //sleep for durationMs + await new Promise((resolve) => setTimeout(resolve, durationMs)); + logger.info("long task done"); + }, +}); From 4148921dff96811fe0dab97703861905cf714701 Mon Sep 17 00:00:00 2001 From: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Tue, 13 Aug 2024 11:44:40 +0100 Subject: [PATCH 08/33] v3: fix unfreezable state crashes for runs with multiple waits (#1253) * support named capture groups * write crash errors to attempt.error * make restored pod names unique per checkpoint * use last eight characters of checkpoint id instead * add more chaos monkey env vars * Ignore unfreezable states * prevent excessive queue config parsing errors * handle dependency resume edge case * better entry point logging * ignore checkpoint cancellation timeouts * add missing idempotency keys to wait for dep replays * remove checkpoints between attempts * fix retry container names on kubernetes * add changeset * fix types * bring back internal duration timers --- .changeset/hungry-sloths-promise.md | 12 + apps/coordinator/src/chaosMonkey.ts | 10 +- apps/coordinator/src/checkpointer.ts | 11 +- apps/coordinator/src/index.ts | 43 +- apps/docker-provider/src/index.ts | 8 +- apps/docker-provider/tsconfig.json | 2 +- apps/kubernetes-provider/src/index.ts | 12 +- apps/webapp/app/v3/failedTaskRun.server.ts | 6 +- apps/webapp/app/v3/handleSocketIo.server.ts | 1 + .../v3/marqs/sharedQueueConsumer.server.ts | 20 +- .../app/v3/services/completeAttempt.server.ts | 89 ++-- .../v3/services/createCheckpoint.server.ts | 36 +- .../v3/services/restoreCheckpoint.server.ts | 1 + .../app/v3/services/resumeBatchRun.server.ts | 20 +- .../services/resumeTaskDependency.server.ts | 20 +- .../app/v3/services/triggerTask.server.ts | 2 +- apps/webapp/app/v3/taskStatus.ts | 7 + .../cli-v3/src/workers/prod/entry-point.ts | 474 +++++++++--------- packages/core-apps/src/provider.ts | 4 + packages/core/src/v3/schemas/messages.ts | 26 +- .../migration.sql | 2 + packages/database/prisma/schema.prisma | 5 +- 22 files changed, 461 insertions(+), 350 deletions(-) create mode 100644 .changeset/hungry-sloths-promise.md create mode 100644 packages/database/prisma/migrations/20240809213411_add_checkpoint_attempt_number_column/migration.sql diff --git a/.changeset/hungry-sloths-promise.md b/.changeset/hungry-sloths-promise.md new file mode 100644 index 000000000..4adec45a7 --- /dev/null +++ b/.changeset/hungry-sloths-promise.md @@ -0,0 +1,12 @@ +--- +"@trigger.dev/core-apps": patch +"trigger.dev": patch +"@trigger.dev/core": patch +--- + +Fix issues that could result in unreezable state run crashes. Details: +- Never checkpoint between attempts +- Some messages and socket data now include attempt numbers +- Remove attempt completion replays +- Additional prod entry point logging +- Fail runs that receive deprecated (pre-lazy attempt) execute messages diff --git a/apps/coordinator/src/chaosMonkey.ts b/apps/coordinator/src/chaosMonkey.ts index c92b07224..978ec463d 100644 --- a/apps/coordinator/src/chaosMonkey.ts +++ b/apps/coordinator/src/chaosMonkey.ts @@ -12,7 +12,11 @@ export class ChaosMonkey { private chaosEventRate = 0.2; private delayInSeconds = 45; - constructor(private enabled = false) { + constructor( + private enabled = false, + private disableErrors = false, + private disableDelays = false + ) { if (this.enabled) { console.log("🍌 Chaos monkey enabled"); } @@ -32,8 +36,8 @@ export class ChaosMonkey { async call({ $, - throwErrors = true, - addDelays = true, + throwErrors = !this.disableErrors, + addDelays = !this.disableDelays, }: { $?: Execa$; throwErrors?: boolean; diff --git a/apps/coordinator/src/checkpointer.ts b/apps/coordinator/src/checkpointer.ts index 797764f9c..29eb4df3a 100644 --- a/apps/coordinator/src/checkpointer.ts +++ b/apps/coordinator/src/checkpointer.ts @@ -17,6 +17,7 @@ type CheckpointAndPushOptions = { projectRef: string; deploymentVersion: string; shouldHeartbeat?: boolean; + attemptNumber?: number; }; type CheckpointAndPushResult = @@ -258,6 +259,7 @@ export class Checkpointer { leaveRunning = true, // This mirrors kubernetes behaviour more accurately projectRef, deploymentVersion, + attemptNumber, }: CheckpointAndPushOptions): Promise { this.#logger.log("Checkpointing with backoff", { runId, @@ -297,6 +299,7 @@ export class Checkpointer { leaveRunning, projectRef, deploymentVersion, + attemptNumber, }); if (result.success) { @@ -359,6 +362,7 @@ export class Checkpointer { leaveRunning = true, // This mirrors kubernetes behaviour more accurately projectRef, deploymentVersion, + attemptNumber, }: CheckpointAndPushOptions): Promise { await this.init(); @@ -367,6 +371,7 @@ export class Checkpointer { leaveRunning, projectRef, deploymentVersion, + attemptNumber, }; if (!this.#dockerMode && !this.#canCheckpoint) { @@ -417,7 +422,7 @@ export class Checkpointer { this.#logger.log("Checkpointing:", { options }); - const containterName = this.#getRunContainerName(runId); + const containterName = this.#getRunContainerName(runId, attemptNumber); // Create checkpoint (docker) if (this.#dockerMode) { @@ -581,7 +586,7 @@ export class Checkpointer { return this.#failedCheckpoints.has(runId); } - #getRunContainerName(suffix: string) { - return `task-run-${suffix}`; + #getRunContainerName(suffix: string, attemptNumber?: number) { + return `task-run-${suffix}${attemptNumber && attemptNumber > 1 ? `-att${attemptNumber}` : ""}`; } } diff --git a/apps/coordinator/src/index.ts b/apps/coordinator/src/index.ts index 5be829d5f..9bde51c94 100644 --- a/apps/coordinator/src/index.ts +++ b/apps/coordinator/src/index.ts @@ -49,7 +49,11 @@ const PLATFORM_SECRET = process.env.PLATFORM_SECRET || "coordinator-secret"; const SECURE_CONNECTION = ["1", "true"].includes(process.env.SECURE_CONNECTION ?? "false"); const logger = new SimpleLogger(`[${NODE_NAME}]`); -const chaosMonkey = new ChaosMonkey(!!process.env.CHAOS_MONKEY_ENABLED); +const chaosMonkey = new ChaosMonkey( + !!process.env.CHAOS_MONKEY_ENABLED, + !!process.env.CHAOS_MONKEY_DISABLE_ERRORS, + !!process.env.CHAOS_MONKEY_DISABLE_DELAYS +); class TaskCoordinator { #httpServer: ReturnType; @@ -290,6 +294,7 @@ class TaskCoordinator { setSocketDataFromHeader("projectRef", "x-trigger-project-ref"); setSocketDataFromHeader("runId", "x-trigger-run-id"); setSocketDataFromHeader("attemptFriendlyId", "x-trigger-attempt-friendly-id", false); + setSocketDataFromHeader("attemptNumber", "x-trigger-attempt-number", false); setSocketDataFromHeader("envId", "x-trigger-env-id"); setSocketDataFromHeader("deploymentId", "x-trigger-deployment-id"); setSocketDataFromHeader("deploymentVersion", "x-trigger-deployment-version"); @@ -306,6 +311,10 @@ class TaskCoordinator { onConnection: async (socket, handler, sender) => { const logger = new SimpleLogger(`[prod-worker][${socket.id}]`); + const getAttemptNumber = () => { + return socket.data.attemptNumber ? parseInt(socket.data.attemptNumber) : undefined; + }; + const crashRun = async (error: { name: string; message: string; stack?: string }) => { try { this.#platformSocket?.send("RUN_CRASHED", { @@ -381,6 +390,10 @@ class TaskCoordinator { socket.data.attemptFriendlyId = attemptFriendlyId; }; + const updateAttemptNumber = (attemptNumber: string | number) => { + socket.data.attemptNumber = String(attemptNumber); + }; + this.#platformSocket?.send("LOG", { metadata: socket.data, text: "connected", @@ -430,6 +443,7 @@ class TaskCoordinator { }); updateAttemptFriendlyId(executionAck.payload.execution.attempt.id); + updateAttemptNumber(executionAck.payload.execution.attempt.number); } catch (error) { logger.error("Error", { error }); @@ -505,11 +519,17 @@ class TaskCoordinator { updateAttemptFriendlyId(message.attemptFriendlyId); - this.#platformSocket?.send("READY_FOR_RESUME", message); + if (message.version === "v2") { + updateAttemptNumber(message.attemptNumber); + } + + this.#platformSocket?.send("READY_FOR_RESUME", { ...message, version: "v1" }); }); // MARK: RUN COMPLETED - socket.on("TASK_RUN_COMPLETED", async ({ completion, execution }, callback) => { + socket.on("TASK_RUN_COMPLETED", async (message, callback) => { + const { completion, execution } = message; + logger.log("completed task", { completionId: completion.id }); // Cancel all in-progress checkpoints (if any) @@ -518,8 +538,10 @@ class TaskCoordinator { await chaosMonkey.call({ throwErrors: false }); const completeWithoutCheckpoint = (shouldExit: boolean) => { + const supportsRetryCheckpoints = message.version === "v1"; + this.#platformSocket?.send("TASK_RUN_COMPLETED", { - version: "v1", + version: supportsRetryCheckpoints ? "v1" : "v2", execution, completion, }); @@ -549,6 +571,11 @@ class TaskCoordinator { return; } + if (message.version === "v2") { + completeWithoutCheckpoint(true); + return; + } + const { canCheckpoint, willSimulate } = await this.#checkpointer.init(); const willCheckpointAndRestore = canCheckpoint || willSimulate; @@ -681,6 +708,7 @@ class TaskCoordinator { runId: socket.data.runId, projectRef: socket.data.projectRef, deploymentVersion: socket.data.deploymentVersion, + attemptNumber: getAttemptNumber(), }); if (!checkpoint) { @@ -752,6 +780,7 @@ class TaskCoordinator { runId: socket.data.runId, projectRef: socket.data.projectRef, deploymentVersion: socket.data.deploymentVersion, + attemptNumber: getAttemptNumber(), }); if (!checkpoint) { @@ -821,6 +850,7 @@ class TaskCoordinator { runId: socket.data.runId, projectRef: socket.data.projectRef, deploymentVersion: socket.data.deploymentVersion, + attemptNumber: getAttemptNumber(), }); if (!checkpoint) { @@ -905,6 +935,7 @@ class TaskCoordinator { } updateAttemptFriendlyId(createAttempt.executionPayload.execution.attempt.id); + updateAttemptNumber(createAttempt.executionPayload.execution.attempt.number); callback({ success: true, @@ -924,6 +955,10 @@ class TaskCoordinator { if (message.attemptFriendlyId) { updateAttemptFriendlyId(message.attemptFriendlyId); } + + if (message.attemptNumber) { + updateAttemptNumber(message.attemptNumber); + } }); }, onDisconnect: async (socket, handler, sender, logger) => { diff --git a/apps/docker-provider/src/index.ts b/apps/docker-provider/src/index.ts index c407e4786..7e891c354 100644 --- a/apps/docker-provider/src/index.ts +++ b/apps/docker-provider/src/index.ts @@ -109,7 +109,7 @@ class DockerTaskOperations implements TaskOperations { async create(opts: TaskOperationsCreateOptions) { await this.init(); - const containerName = this.#getRunContainerName(opts.runId); + const containerName = this.#getRunContainerName(opts.runId, opts.nextAttemptNumber); const runArgs = [ "run", @@ -150,7 +150,7 @@ class DockerTaskOperations implements TaskOperations { async restore(opts: TaskOperationsRestoreOptions) { await this.init(); - const containerName = this.#getRunContainerName(opts.runId); + const containerName = this.#getRunContainerName(opts.runId, opts.attemptNumber); if (!this.#canCheckpoint || this.opts.forceSimulate) { logger.log("Simulating restore"); @@ -195,8 +195,8 @@ class DockerTaskOperations implements TaskOperations { return `task-index-${suffix}`; } - #getRunContainerName(suffix: string) { - return `task-run-${suffix}`; + #getRunContainerName(suffix: string, attemptNumber?: number) { + return `task-run-${suffix}${attemptNumber && attemptNumber > 1 ? `-att${attemptNumber}` : ""}`; } async #sendPostStart(containerName: string): Promise { diff --git a/apps/docker-provider/tsconfig.json b/apps/docker-provider/tsconfig.json index 8e6c54f74..ff1edf980 100644 --- a/apps/docker-provider/tsconfig.json +++ b/apps/docker-provider/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es2016", + "target": "es2018", "module": "commonjs", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, diff --git a/apps/kubernetes-provider/src/index.ts b/apps/kubernetes-provider/src/index.ts index be9a4fb9c..d94d5f43c 100644 --- a/apps/kubernetes-provider/src/index.ts +++ b/apps/kubernetes-provider/src/index.ts @@ -139,10 +139,12 @@ class KubernetesTaskOperations implements TaskOperations { } async create(opts: TaskOperationsCreateOptions) { + const containerName = this.#getRunContainerName(opts.runId, opts.nextAttemptNumber); + await this.#createPod( { metadata: { - name: this.#getRunContainerName(opts.runId), + name: containerName, namespace: this.#namespace.metadata.name, labels: { ...this.#getSharedLabels(opts), @@ -157,7 +159,7 @@ class KubernetesTaskOperations implements TaskOperations { terminationGracePeriodSeconds: 60 * 60, containers: [ { - name: this.#getRunContainerName(opts.runId), + name: containerName, image: opts.image, ports: [ { @@ -211,7 +213,7 @@ class KubernetesTaskOperations implements TaskOperations { await this.#createPod( { metadata: { - name: `${this.#getRunContainerName(opts.runId)}-${randomUUID().slice(0, 8)}`, + name: `${this.#getRunContainerName(opts.runId)}-${opts.checkpointId.slice(-8)}`, namespace: this.#namespace.metadata.name, labels: { ...this.#getSharedLabels(opts), @@ -514,8 +516,8 @@ class KubernetesTaskOperations implements TaskOperations { return `task-index-${suffix}`; } - #getRunContainerName(suffix: string) { - return `task-run-${suffix}`; + #getRunContainerName(suffix: string, attemptNumber?: number) { + return `task-run-${suffix}${attemptNumber && attemptNumber > 1 ? `-att${attemptNumber}` : ""}`; } #getPrePullContainerName(suffix: string) { diff --git a/apps/webapp/app/v3/failedTaskRun.server.ts b/apps/webapp/app/v3/failedTaskRun.server.ts index 247e196bc..709167bf3 100644 --- a/apps/webapp/app/v3/failedTaskRun.server.ts +++ b/apps/webapp/app/v3/failedTaskRun.server.ts @@ -1,11 +1,9 @@ import { TaskRunFailedExecutionResult } from "@trigger.dev/core/v3"; -import { TaskRunStatus } from "@trigger.dev/database"; import { logger } from "~/services/logger.server"; import { createExceptionPropertiesFromError, eventRepository } from "./eventRepository.server"; import { BaseService } from "./services/baseService.server"; import { FinalizeTaskRunService } from "./services/finalizeTaskRun.server"; - -const FAILABLE_TASK_RUN_STATUSES: TaskRunStatus[] = ["EXECUTING", "PENDING", "WAITING_FOR_DEPLOY"]; +import { FAILABLE_RUN_STATUSES } from "./taskStatus"; export class FailedTaskRunService extends BaseService { public async call(anyRunId: string, completion: TaskRunFailedExecutionResult) { @@ -27,7 +25,7 @@ export class FailedTaskRunService extends BaseService { return; } - if (!FAILABLE_TASK_RUN_STATUSES.includes(taskRun.status)) { + if (!FAILABLE_RUN_STATUSES.includes(taskRun.status)) { logger.error("[FailedTaskRunService] Task run is not in a failable state", { taskRun, completion, diff --git a/apps/webapp/app/v3/handleSocketIo.server.ts b/apps/webapp/app/v3/handleSocketIo.server.ts index 808e930b5..5b2c60016 100644 --- a/apps/webapp/app/v3/handleSocketIo.server.ts +++ b/apps/webapp/app/v3/handleSocketIo.server.ts @@ -128,6 +128,7 @@ function createCoordinatorNamespace(io: Server) { completion: message.completion, execution: message.execution, checkpoint: message.checkpoint, + supportsRetryCheckpoints: message.version === "v1", }); }, TASK_RUN_FAILED_TO_RUN: async (message) => { diff --git a/apps/webapp/app/v3/marqs/sharedQueueConsumer.server.ts b/apps/webapp/app/v3/marqs/sharedQueueConsumer.server.ts index 1a2dc14e6..4f65a5757 100644 --- a/apps/webapp/app/v3/marqs/sharedQueueConsumer.server.ts +++ b/apps/webapp/app/v3/marqs/sharedQueueConsumer.server.ts @@ -54,6 +54,7 @@ export const SharedQueueMessageBody = z.discriminatedUnion("type", [ type: z.literal("EXECUTE"), taskIdentifier: z.string(), checkpointEventId: z.string().optional(), + retryCheckpointsDisabled: z.boolean().optional(), }), WithTraceContext.extend({ type: z.literal("RESUME"), @@ -294,12 +295,9 @@ export class SharedQueueConsumer { const retryingFromCheckpoint = !!messageBody.data.checkpointEventId; - const EXECUTABLE_RUN_STATUSES: { - fromCheckpoint: TaskRunStatus[]; - withoutCheckpoint: TaskRunStatus[]; - } = { - fromCheckpoint: ["WAITING_TO_RESUME"], - withoutCheckpoint: ["PENDING", "RETRYING_AFTER_FAILURE"], + const EXECUTABLE_RUN_STATUSES = { + fromCheckpoint: ["WAITING_TO_RESUME"] satisfies TaskRunStatus[], + withoutCheckpoint: ["PENDING", "RETRYING_AFTER_FAILURE"] satisfies TaskRunStatus[], }; if ( @@ -474,7 +472,10 @@ export class SharedQueueConsumer { ? lockedTaskRun.attempts[0].number + 1 : 1; - const isRetry = lockedTaskRun.status === "WAITING_TO_RESUME" && nextAttemptNumber > 1; + const isRetry = + nextAttemptNumber > 1 && + (lockedTaskRun.status === "WAITING_TO_RESUME" || + lockedTaskRun.status === "RETRYING_AFTER_FAILURE"); try { if (messageBody.data.checkpointEventId) { @@ -515,11 +516,13 @@ export class SharedQueueConsumer { } } - if (isRetry) { + if (isRetry && !messageBody.data.retryCheckpointsDisabled) { socketIo.coordinatorNamespace.emit("READY_FOR_RETRY", { version: "v1", runId: lockedTaskRun.id, }); + + // Retries for workers with disabled retry checkpoints will be handled just like normal attempts } else { const machineConfig = lockedTaskRun.lockedBy?.machineConfig; const machine = machinePresetFromConfig(machineConfig ?? {}); @@ -531,6 +534,7 @@ export class SharedQueueConsumer { image: deployment.imageReference, version: deployment.version, machine, + nextAttemptNumber, // identifiers id: "placeholder", // TODO: Remove this completely in a future release envId: lockedTaskRun.runtimeEnvironment.id, diff --git a/apps/webapp/app/v3/services/completeAttempt.server.ts b/apps/webapp/app/v3/services/completeAttempt.server.ts index e71e7bd96..57389271e 100644 --- a/apps/webapp/app/v3/services/completeAttempt.server.ts +++ b/apps/webapp/app/v3/services/completeAttempt.server.ts @@ -38,11 +38,13 @@ export class CompleteAttemptService extends BaseService { execution, env, checkpoint, + supportsRetryCheckpoints, }: { completion: TaskRunExecutionResult; execution: TaskRunExecution; env?: AuthenticatedEnvironment; checkpoint?: CheckpointData; + supportsRetryCheckpoints?: boolean; }): Promise<"COMPLETED" | "RETRIED"> { const taskRunAttempt = await findAttempt(this._prisma, execution.attempt.id); @@ -95,13 +97,14 @@ export class CompleteAttemptService extends BaseService { if (completion.ok) { return await this.#completeAttemptSuccessfully(completion, taskRunAttempt, env); } else { - return await this.#completeAttemptFailed( + return await this.#completeAttemptFailed({ completion, execution, taskRunAttempt, env, - checkpoint - ); + checkpoint, + supportsRetryCheckpoints, + }); } } @@ -152,13 +155,21 @@ export class CompleteAttemptService extends BaseService { return "COMPLETED"; } - async #completeAttemptFailed( - completion: TaskRunFailedExecutionResult, - execution: TaskRunExecution, - taskRunAttempt: NonNullable, - env?: AuthenticatedEnvironment, - checkpoint?: CheckpointData - ): Promise<"COMPLETED" | "RETRIED"> { + async #completeAttemptFailed({ + completion, + execution, + taskRunAttempt, + env, + checkpoint, + supportsRetryCheckpoints, + }: { + completion: TaskRunFailedExecutionResult; + execution: TaskRunExecution; + taskRunAttempt: NonNullable; + env?: AuthenticatedEnvironment; + checkpoint?: CheckpointData; + supportsRetryCheckpoints?: boolean; + }): Promise<"COMPLETED" | "RETRIED"> { if ( completion.error.type === "INTERNAL_ERROR" && completion.error.code === "TASK_RUN_CANCELLED" @@ -243,12 +254,13 @@ export class CompleteAttemptService extends BaseService { } if (!checkpoint) { - await this.#retryAttempt( - taskRunAttempt.taskRun, - completion.retry.timestamp, - undefined, - taskRunAttempt.backgroundWorker.supportsLazyAttempts - ); + await this.#retryAttempt({ + run: taskRunAttempt.taskRun, + retryTimestamp: completion.retry.timestamp, + supportsLazyAttempts: taskRunAttempt.backgroundWorker.supportsLazyAttempts, + supportsRetryCheckpoints, + }); + return "RETRIED"; } @@ -263,7 +275,7 @@ export class CompleteAttemptService extends BaseService { }, }); - if (!checkpointCreateResult) { + if (!checkpointCreateResult.success) { logger.error("Failed to create checkpoint", { checkpoint, execution: execution.run.id }); const finalizeService = new FinalizeTaskRunService(); @@ -276,11 +288,13 @@ export class CompleteAttemptService extends BaseService { return "COMPLETED"; } - await this.#retryAttempt( - taskRunAttempt.taskRun, - completion.retry.timestamp, - checkpointCreateResult.event.id - ); + await this.#retryAttempt({ + run: taskRunAttempt.taskRun, + retryTimestamp: completion.retry.timestamp, + checkpointEventId: checkpointCreateResult.event.id, + supportsLazyAttempts: taskRunAttempt.backgroundWorker.supportsLazyAttempts, + supportsRetryCheckpoints, + }); return "RETRIED"; } else { @@ -352,13 +366,27 @@ export class CompleteAttemptService extends BaseService { } } - async #retryAttempt( - run: TaskRun, - retryTimestamp: number, - checkpointEventId?: string, - supportsLazyAttempts?: boolean - ) { - if (checkpointEventId || !supportsLazyAttempts) { + async #retryAttempt({ + run, + retryTimestamp, + checkpointEventId, + supportsLazyAttempts, + supportsRetryCheckpoints, + }: { + run: TaskRun; + retryTimestamp: number; + checkpointEventId?: string; + supportsLazyAttempts: boolean; + supportsRetryCheckpoints?: boolean; + }) { + if (checkpointEventId || !supportsLazyAttempts || !supportsRetryCheckpoints) { + if (!supportsRetryCheckpoints && checkpointEventId) { + logger.error("Worker does not support retry checkpoints, but a checkpoint was created", { + runId: run.id, + checkpointEventId, + }); + } + // Workers without lazy attempt support always need to go through the queue, which is where the attempt is created // We have to replace a potential RESUME with EXECUTE to correctly retry the attempt return await marqs?.replaceMessage( @@ -366,7 +394,8 @@ export class CompleteAttemptService extends BaseService { { type: "EXECUTE", taskIdentifier: run.taskIdentifier, - checkpointEventId: checkpointEventId, + checkpointEventId: supportsRetryCheckpoints ? checkpointEventId : undefined, + retryCheckpointsDisabled: !supportsRetryCheckpoints, }, retryTimestamp ); diff --git a/apps/webapp/app/v3/services/createCheckpoint.server.ts b/apps/webapp/app/v3/services/createCheckpoint.server.ts index 0ed9acab5..56fec5469 100644 --- a/apps/webapp/app/v3/services/createCheckpoint.server.ts +++ b/apps/webapp/app/v3/services/createCheckpoint.server.ts @@ -6,7 +6,6 @@ import { generateFriendlyId } from "../friendlyIdentifiers"; import { marqs } from "~/v3/marqs/index.server"; import { CreateCheckpointRestoreEventService } from "./createCheckpointRestoreEvent.server"; import { BaseService } from "./baseService.server"; -import { CrashTaskRunService } from "./crashTaskRun.server"; import { isFinalRunStatus, isFreezableAttemptStatus, isFreezableRunStatus } from "../taskStatus"; export class CreateCheckpointService extends BaseService { @@ -17,11 +16,15 @@ export class CreateCheckpointService extends BaseService { > ): Promise< | { + success: true; checkpoint: Checkpoint; event: CheckpointRestoreEvent; keepRunAlive: boolean; } - | undefined + | { + success: false; + keepRunAlive?: boolean; + } > { logger.debug(`Creating checkpoint`, params); @@ -46,7 +49,10 @@ export class CreateCheckpointService extends BaseService { if (!attempt) { logger.error("Attempt not found", { attemptFriendlyId: params.attemptFriendlyId }); - return; + + return { + success: false, + }; } if ( @@ -64,14 +70,10 @@ export class CreateCheckpointService extends BaseService { }, }); - // This should only affect CLIs < beta.24, in very limited scenarios - const service = new CrashTaskRunService(this._prisma); - await service.call(attempt.taskRunId, { - crashAttempts: true, - reason: "Unfreezable state: Please upgrade your CLI", - }); - - return; + return { + success: false, + keepRunAlive: true, + }; } const imageRef = attempt.backgroundWorker.deployment?.imageReference; @@ -81,7 +83,10 @@ export class CreateCheckpointService extends BaseService { attemptId: attempt.id, workerId: attempt.backgroundWorker.id, }); - return; + + return { + success: false, + }; } const checkpoint = await this._prisma.checkpoint.create({ @@ -90,6 +95,7 @@ export class CreateCheckpointService extends BaseService { runtimeEnvironmentId: attempt.taskRun.runtimeEnvironmentId, projectId: attempt.taskRun.projectId, attemptId: attempt.id, + attemptNumber: attempt.number, runId: attempt.taskRunId, location: params.location, type: params.docker ? "DOCKER" : "KUBERNETES", @@ -175,7 +181,10 @@ export class CreateCheckpointService extends BaseService { checkpointId: checkpoint.id, }); await marqs?.acknowledgeMessage(attempt.taskRunId); - return; + + return { + success: false, + }; } if (reason.type === "WAIT_FOR_DURATION") { @@ -191,6 +200,7 @@ export class CreateCheckpointService extends BaseService { } return { + success: true, checkpoint, event: checkpointEvent, keepRunAlive, diff --git a/apps/webapp/app/v3/services/restoreCheckpoint.server.ts b/apps/webapp/app/v3/services/restoreCheckpoint.server.ts index dc66c3b00..3ca0efbc3 100644 --- a/apps/webapp/app/v3/services/restoreCheckpoint.server.ts +++ b/apps/webapp/app/v3/services/restoreCheckpoint.server.ts @@ -100,6 +100,7 @@ export class RestoreCheckpointService extends BaseService { reason: checkpoint.reason ?? undefined, imageRef: checkpoint.imageRef, machine, + attemptNumber: checkpoint.attemptNumber ?? undefined, // identifiers checkpointId: checkpoint.id, envId: checkpoint.runtimeEnvironment.id, diff --git a/apps/webapp/app/v3/services/resumeBatchRun.server.ts b/apps/webapp/app/v3/services/resumeBatchRun.server.ts index 29a9b26bb..b7693ca72 100644 --- a/apps/webapp/app/v3/services/resumeBatchRun.server.ts +++ b/apps/webapp/app/v3/services/resumeBatchRun.server.ts @@ -61,16 +61,7 @@ export class ResumeBatchRunService extends BaseService { const dependentRun = batchRun.dependentTaskAttempt.taskRun; - if (batchRun.dependentTaskAttempt.status === "PAUSED") { - if (!batchRun.checkpointEventId) { - logger.error("Can't resume paused attempt without checkpoint event", { - batchRunId: batchRun.id, - }); - - await marqs?.acknowledgeMessage(dependentRun.id); - return; - } - + if (batchRun.dependentTaskAttempt.status === "PAUSED" && batchRun.checkpointEventId) { await marqs?.enqueueMessage( environment, dependentRun.queue, @@ -87,6 +78,15 @@ export class ResumeBatchRunService extends BaseService { dependentRun.concurrencyKey ?? undefined ); } else { + if (batchRun.dependentTaskAttempt.status === "PAUSED" && !batchRun.checkpointEventId) { + // In case of race conditions and other bugs, the status can be PAUSED without a checkpoint event + // The worker may still be up, so we will try to resume the dependent attempt by sending a message to the worker (on dequeue) + logger.error("Batch run resume: Attempt is paused but there's no checkpoint event", { + batchRunId: batchRun.id, + dependentTaskAttemptId: batchRun.dependentTaskAttempt.id, + }); + } + await marqs?.replaceMessage(dependentRun.id, { type: "RESUME", completedAttemptIds: batchRun.items.map((item) => item.taskRunAttemptId).filter(Boolean), diff --git a/apps/webapp/app/v3/services/resumeTaskDependency.server.ts b/apps/webapp/app/v3/services/resumeTaskDependency.server.ts index 29f36eb8b..3151b8ffb 100644 --- a/apps/webapp/app/v3/services/resumeTaskDependency.server.ts +++ b/apps/webapp/app/v3/services/resumeTaskDependency.server.ts @@ -38,16 +38,7 @@ export class ResumeTaskDependencyService extends BaseService { const dependentRun = dependency.dependentAttempt.taskRun; - if (dependency.dependentAttempt.status === "PAUSED") { - if (!dependency.checkpointEventId) { - logger.error("Can't resume paused attempt without checkpoint event", { - attemptId: dependency.id, - }); - - await marqs?.acknowledgeMessage(dependentRun.id); - return; - } - + if (dependency.dependentAttempt.status === "PAUSED" && dependency.checkpointEventId) { await marqs?.enqueueMessage( dependency.taskRun.runtimeEnvironment, dependentRun.queue, @@ -64,6 +55,15 @@ export class ResumeTaskDependencyService extends BaseService { dependentRun.concurrencyKey ?? undefined ); } else { + if (dependency.dependentAttempt.status === "PAUSED" && !dependency.checkpointEventId) { + // In case of race conditions and other bugs, the status can be PAUSED without a checkpoint event + // The worker may still be up, so we will try to resume the dependent attempt by sending a message to the worker (on dequeue) + logger.warn("Task dependency resume: Attempt is paused but there's no checkpoint event", { + attemptId: dependency.id, + dependentAttemptId: dependency.dependentAttempt.id, + }); + } + await marqs?.replaceMessage(dependentRun.id, { type: "RESUME", completedAttemptIds: [sourceTaskAttemptId], diff --git a/apps/webapp/app/v3/services/triggerTask.server.ts b/apps/webapp/app/v3/services/triggerTask.server.ts index ddc816001..88cf557b0 100644 --- a/apps/webapp/app/v3/services/triggerTask.server.ts +++ b/apps/webapp/app/v3/services/triggerTask.server.ts @@ -445,7 +445,7 @@ export class TriggerTaskService extends BaseService { return defaultQueueName; } - const queueConfig = QueueOptions.optional().safeParse(task.queueConfig); + const queueConfig = QueueOptions.optional().nullable().safeParse(task.queueConfig); if (!queueConfig.success) { console.log("Failed to get queue name: Invalid queue config", { diff --git a/apps/webapp/app/v3/taskStatus.ts b/apps/webapp/app/v3/taskStatus.ts index 13e3c0a6e..fe5b723cc 100644 --- a/apps/webapp/app/v3/taskStatus.ts +++ b/apps/webapp/app/v3/taskStatus.ts @@ -69,3 +69,10 @@ export function isRestorableRunStatus(status: TaskRunStatus): boolean { export function isRestorableAttemptStatus(status: TaskRunAttemptStatus): boolean { return RESTORABLE_ATTEMPT_STATUSES.includes(status); } + +export const FAILABLE_RUN_STATUSES = [ + "EXECUTING", + "PENDING", + "WAITING_FOR_DEPLOY", + "RETRYING_AFTER_FAILURE", +] satisfies TaskRunStatus[]; diff --git a/packages/cli-v3/src/workers/prod/entry-point.ts b/packages/cli-v3/src/workers/prod/entry-point.ts index 305a14932..062e7c44b 100644 --- a/packages/cli-v3/src/workers/prod/entry-point.ts +++ b/packages/cli-v3/src/workers/prod/entry-point.ts @@ -27,6 +27,7 @@ import { randomUUID } from "node:crypto"; import { readFile } from "node:fs/promises"; import { createServer } from "node:http"; import { setTimeout as timeout } from "node:timers/promises"; +import { Evt } from "evt"; declare const __PROJECT_CONFIG__: Config; @@ -58,11 +59,14 @@ class ProdWorker { private completed = new Set(); private paused = false; private attemptFriendlyId?: string; + private attemptNumber?: number; private nextResumeAfter?: WaitReason; private waitForPostStart = false; private connectionCount = 0; + private restoreNotification = Evt.create(); + private waitForTaskReplay: | { idempotencyKey: string; @@ -82,16 +86,6 @@ class ProdWorker { idempotencyKey: string; } | undefined; - private submitAttemptCompletionReplay: - | { - idempotencyKey: string; - message: { - execution: ProdTaskRunExecution; - completion: TaskRunExecutionResult; - }; - attempt: number; - } - | undefined; private durationResumeFallback: | { idempotencyKey: string; @@ -190,128 +184,156 @@ class ProdWorker { } // MARK: TASK WAIT - async #waitForTaskHandler(message: OnWaitForTaskMessage, replayIdempotencyKey?: string) { - const waitForTask = await defaultBackoff.execute(async ({ retry }) => { - logger.log("Wait for task with backoff", { retry }); + #waitForTaskHandlerFactory(workerId?: string) { + return async (message: OnWaitForTaskMessage, replayIdempotencyKey?: string) => { + logger.log("onWaitForTask", { workerId, message }); - if (!this.attemptFriendlyId) { - logger.error("Failed to send wait message, attempt friendly ID not set", { message }); + if (this.nextResumeAfter) { + logger.error("Already waiting for resume, skipping wait for task", { + nextResumeAfter: this.nextResumeAfter, + }); - throw new ExponentialBackoff.StopRetrying("No attempt ID"); + return; } - return await this.#coordinatorSocket.socket.timeout(20_000).emitWithAck("WAIT_FOR_TASK", { - version: "v2", - friendlyId: message.friendlyId, - attemptFriendlyId: this.attemptFriendlyId, - }); - }); + const waitForTask = await defaultBackoff.execute(async ({ retry }) => { + logger.log("Wait for task with backoff", { retry }); - if (!waitForTask.success) { - logger.error("Failed to wait for task with backoff", { - cause: waitForTask.cause, - error: waitForTask.error, - }); + if (!this.attemptFriendlyId) { + logger.error("Failed to send wait message, attempt friendly ID not set", { message }); - this.#emitUnrecoverableError( - "WaitForTaskFailed", - `${waitForTask.cause}: ${waitForTask.error}` - ); - - return; - } - - const { willCheckpointAndRestore } = waitForTask.result; - - await this.#prepareForWait("WAIT_FOR_TASK", willCheckpointAndRestore); - - if (willCheckpointAndRestore) { - // We need to replay this on next connection if we don't receive RESUME_AFTER_DEPENDENCY within a reasonable time - if (!this.waitForTaskReplay) { - this.waitForTaskReplay = { - message, - attempt: 1, - idempotencyKey: randomUUID(), - }; - } else { - if ( - replayIdempotencyKey && - replayIdempotencyKey !== this.waitForTaskReplay.idempotencyKey - ) { - logger.error( - "wait for task handler called with mismatched idempotency key, won't overwrite replay request" - ); - return; + throw new ExponentialBackoff.StopRetrying("No attempt ID"); } - this.waitForTaskReplay.attempt++; + return await this.#coordinatorSocket.socket.timeout(20_000).emitWithAck("WAIT_FOR_TASK", { + version: "v2", + friendlyId: message.friendlyId, + attemptFriendlyId: this.attemptFriendlyId, + }); + }); + + if (!waitForTask.success) { + logger.error("Failed to wait for task with backoff", { + cause: waitForTask.cause, + error: waitForTask.error, + }); + + this.#emitUnrecoverableError( + "WaitForTaskFailed", + `${waitForTask.cause}: ${waitForTask.error}` + ); + + return; } - } + + const { willCheckpointAndRestore } = waitForTask.result; + + await this.#prepareForWait("WAIT_FOR_TASK", willCheckpointAndRestore); + + if (willCheckpointAndRestore) { + // We need to replay this on next connection if we don't receive RESUME_AFTER_DEPENDENCY within a reasonable time + if (!this.waitForTaskReplay) { + this.waitForTaskReplay = { + message, + attempt: 1, + idempotencyKey: randomUUID(), + }; + } else { + if ( + replayIdempotencyKey && + replayIdempotencyKey !== this.waitForTaskReplay.idempotencyKey + ) { + logger.error( + "wait for task handler called with mismatched idempotency key, won't overwrite replay request" + ); + return; + } + + this.waitForTaskReplay.attempt++; + } + } + }; } // MARK: BATCH WAIT - async #waitForBatchHandler(message: OnWaitForBatchMessage, replayIdempotencyKey?: string) { - const waitForBatch = await defaultBackoff.execute(async ({ retry }) => { - logger.log("Wait for batch with backoff", { retry }); + #waitForBatchHandlerFactory(workerId?: string) { + return async (message: OnWaitForBatchMessage, replayIdempotencyKey?: string) => { + logger.log("onWaitForBatch", { workerId, message }); - if (!this.attemptFriendlyId) { - logger.error("Failed to send wait message, attempt friendly ID not set", { message }); + if (this.nextResumeAfter) { + logger.error("Already waiting for resume, skipping wait for batch", { + nextResumeAfter: this.nextResumeAfter, + }); - throw new ExponentialBackoff.StopRetrying("No attempt ID"); + return; } - return await this.#coordinatorSocket.socket.timeout(20_000).emitWithAck("WAIT_FOR_BATCH", { - version: "v2", - batchFriendlyId: message.batchFriendlyId, - runFriendlyIds: message.runFriendlyIds, - attemptFriendlyId: this.attemptFriendlyId, - }); - }); + const waitForBatch = await defaultBackoff.execute(async ({ retry }) => { + logger.log("Wait for batch with backoff", { retry }); - if (!waitForBatch.success) { - logger.error("Failed to wait for batch with backoff", { - cause: waitForBatch.cause, - error: waitForBatch.error, - }); + if (!this.attemptFriendlyId) { + logger.error("Failed to send wait message, attempt friendly ID not set", { message }); - this.#emitUnrecoverableError( - "WaitForBatchFailed", - `${waitForBatch.cause}: ${waitForBatch.error}` - ); - - return; - } - - const { willCheckpointAndRestore } = waitForBatch.result; - - await this.#prepareForWait("WAIT_FOR_BATCH", willCheckpointAndRestore); - - if (willCheckpointAndRestore) { - // We need to replay this on next connection if we don't receive RESUME_AFTER_DEPENDENCY within a reasonable time - if (!this.waitForBatchReplay) { - this.waitForBatchReplay = { - message, - attempt: 1, - idempotencyKey: randomUUID(), - }; - } else { - if ( - replayIdempotencyKey && - replayIdempotencyKey !== this.waitForBatchReplay.idempotencyKey - ) { - logger.error( - "wait for task handler called with mismatched idempotency key, won't overwrite replay request" - ); - return; + throw new ExponentialBackoff.StopRetrying("No attempt ID"); } - this.waitForBatchReplay.attempt++; + return await this.#coordinatorSocket.socket.timeout(20_000).emitWithAck("WAIT_FOR_BATCH", { + version: "v2", + batchFriendlyId: message.batchFriendlyId, + runFriendlyIds: message.runFriendlyIds, + attemptFriendlyId: this.attemptFriendlyId, + }); + }); + + if (!waitForBatch.success) { + logger.error("Failed to wait for batch with backoff", { + cause: waitForBatch.cause, + error: waitForBatch.error, + }); + + this.#emitUnrecoverableError( + "WaitForBatchFailed", + `${waitForBatch.cause}: ${waitForBatch.error}` + ); + + return; } - } + + const { willCheckpointAndRestore } = waitForBatch.result; + + await this.#prepareForWait("WAIT_FOR_BATCH", willCheckpointAndRestore); + + if (willCheckpointAndRestore) { + // We need to replay this on next connection if we don't receive RESUME_AFTER_DEPENDENCY within a reasonable time + if (!this.waitForBatchReplay) { + this.waitForBatchReplay = { + message, + attempt: 1, + idempotencyKey: randomUUID(), + }; + } else { + if ( + replayIdempotencyKey && + replayIdempotencyKey !== this.waitForBatchReplay.idempotencyKey + ) { + logger.error( + "wait for task handler called with mismatched idempotency key, won't overwrite replay request" + ); + return; + } + + this.waitForBatchReplay.attempt++; + } + } + }; } // MARK: WORKER CREATION #createBackgroundWorker() { + const workerId = randomUUID(); + + logger.log("Creating background worker", { workerId }); + const backgroundWorker = new ProdBackgroundWorker("worker.js", { projectConfig: __PROJECT_CONFIG__, env: { @@ -325,7 +347,10 @@ class ProdWorker { }); backgroundWorker.onTaskHeartbeat.attach((attemptFriendlyId) => { - logger.log("onTaskHeartbeat", { attemptFriendlyId }); + logger.log("onTaskHeartbeat", { + workerId, + attemptFriendlyId, + }); this.#coordinatorSocket.socket.volatile.emit("TASK_HEARTBEAT", { version: "v1", @@ -334,13 +359,19 @@ class ProdWorker { }); backgroundWorker.onTaskRunHeartbeat.attach((runId) => { - logger.log("onTaskRunHeartbeat", { runId }); + logger.log("onTaskRunHeartbeat", { + workerId, + runId, + }); this.#coordinatorSocket.socket.volatile.emit("TASK_RUN_HEARTBEAT", { version: "v1", runId }); }); backgroundWorker.onCreateTaskRunAttempt.attach(async (message) => { - logger.log("onCreateTaskRunAttempt()", { message }); + logger.log("onCreateTaskRunAttempt()", { + workerId, + message, + }); const createAttempt = await defaultBackoff.execute(async ({ retry }) => { logger.log("Create task run attempt with backoff", { retry }); @@ -377,6 +408,7 @@ class ProdWorker { backgroundWorker.attemptCreatedNotification.attach((message) => { logger.log("attemptCreatedNotification", { + workerId, success: message.success, ...(message.success ? { @@ -396,10 +428,24 @@ class ProdWorker { // Workers with lazy attempt support set their friendly ID here this.attemptFriendlyId = message.execution.attempt.id; + this.attemptNumber = message.execution.attempt.number; }); + // MARK: WAIT_FOR_DURATION backgroundWorker.onWaitForDuration.attach(async (message) => { - logger.log("onWaitForDuration", { ...message, drift: Date.now() - message.now }); + logger.log("onWaitForDuration", { + workerId, + ...message, + drift: Date.now() - message.now, + }); + + if (this.nextResumeAfter) { + logger.error("Already waiting for resume, skipping wait for duration", { + nextResumeAfter: this.nextResumeAfter, + }); + + return; + } noResume: { const { ms, waitThresholdInMs } = message; @@ -457,6 +503,17 @@ class ProdWorker { // checkpointSafeInternalTimeout is accurate even after non-simulated restores await Promise.race([internalTimeout, checkpointSafeInternalTimeout]); + const idempotencyKey = randomUUID(); + this.durationResumeFallback = { idempotencyKey }; + + try { + await this.restoreNotification.waitFor(5_000); + } catch (error) { + logger.error("Did not receive restore notification in time", { + error, + }); + } + try { // The coordinator should cancel any in-progress checkpoints so we don't end up with race conditions const { checkpointCanceled } = await this.#coordinatorSocket.socket @@ -475,9 +532,6 @@ class ProdWorker { logger.log("Waiting for external duration resume as we may have been restored"); - const idempotencyKey = randomUUID(); - this.durationResumeFallback = { idempotencyKey }; - setTimeout(() => { if (!this.durationResumeFallback) { logger.error("Already resumed after duration, skipping fallback"); @@ -494,9 +548,12 @@ class ProdWorker { this.#resumeAfterDuration(); }, 15_000); } catch (error) { - // If the cancellation times out, we will proceed as if the checkpoint was canceled - logger.debug("Checkpoint cancellation timed out", { error }); - break noResume; + // Just log this for now, but don't automatically resume. Wait for the external checkpoint-based resume. + logger.debug("Checkpoint cancellation timed out", { + workerId, + message, + error, + }); } return; @@ -505,8 +562,8 @@ class ProdWorker { this.#resumeAfterDuration(); }); - backgroundWorker.onWaitForTask.attach(this.#waitForTaskHandler.bind(this)); - backgroundWorker.onWaitForBatch.attach(this.#waitForBatchHandler.bind(this)); + backgroundWorker.onWaitForTask.attach(this.#waitForTaskHandlerFactory(workerId).bind(this)); + backgroundWorker.onWaitForBatch.attach(this.#waitForBatchHandlerFactory(workerId).bind(this)); return backgroundWorker; } @@ -514,6 +571,18 @@ class ProdWorker { async #prepareForWait(reason: WaitReason, willCheckpointAndRestore: boolean) { logger.log(`prepare for ${reason}`, { willCheckpointAndRestore }); + if (this.nextResumeAfter) { + logger.error("Already waiting for resume, skipping prepare for wait", { + nextResumeAfter: this.nextResumeAfter, + params: { + reason, + willCheckpointAndRestore, + }, + }); + + return; + } + if (!willCheckpointAndRestore) { return; } @@ -526,19 +595,11 @@ class ProdWorker { } // MARK: RETRY PREP - async #prepareForRetry( - willCheckpointAndRestore: boolean, - shouldExit: boolean, - exitCode?: number - ) { - logger.log("prepare for retry", { willCheckpointAndRestore, shouldExit, exitCode }); + async #prepareForRetry(shouldExit: boolean, exitCode?: number) { + logger.log("prepare for retry", { shouldExit, exitCode }); // Graceful shutdown on final attempt if (shouldExit) { - if (willCheckpointAndRestore) { - logger.error("WARNING: Will checkpoint but also requested exit. This won't end well."); - } - await this.#exitGracefully(false, exitCode); return; } @@ -548,15 +609,7 @@ class ProdWorker { this.waitForPostStart = false; this.executing = false; this.attemptFriendlyId = undefined; - - if (!willCheckpointAndRestore) { - return; - } - - this.waitForPostStart = true; - - // We already flush after completion, so we don't need to do it here - await this.#prepareForCheckpoint(false); + this.attemptNumber = undefined; } // MARK: CHECKPOINT PREP @@ -591,6 +644,8 @@ class ProdWorker { this.nextResumeAfter = undefined; this.waitForPostStart = false; + this.durationResumeFallback = undefined; + this.#backgroundWorker.waitCompletedNotification(); } @@ -683,7 +738,7 @@ class ProdWorker { return await this.#coordinatorSocket.socket .timeout(20_000) .emitWithAck("TASK_RUN_COMPLETED", { - version: "v1", + version: "v2", execution, completion, }); @@ -711,32 +766,10 @@ class ProdWorker { ? EXIT_CODE_CHILD_NONZERO : 0; - await this.#prepareForRetry(willCheckpointAndRestore, shouldExit, exitCode); + await this.#prepareForRetry(shouldExit, exitCode); if (willCheckpointAndRestore) { - // We need to replay this on next connection if we don't receive READY_FOR_RETRY within a reasonable time - if (!this.submitAttemptCompletionReplay) { - this.submitAttemptCompletionReplay = { - message: { - execution, - completion, - }, - attempt: 1, - idempotencyKey: randomUUID(), - }; - } else { - if ( - replayIdempotencyKey && - replayIdempotencyKey !== this.submitAttemptCompletionReplay.idempotencyKey - ) { - logger.error( - "attempt completion handler called with mismatched idempotency key, won't overwrite replay request" - ); - return; - } - - this.submitAttemptCompletionReplay.attempt++; - } + logger.error("This worker should never be checkpointed between attempts. This is a bug."); } } @@ -767,6 +800,10 @@ class ProdWorker { extraHeaders["x-trigger-attempt-friendly-id"] = this.attemptFriendlyId; } + if (this.attemptNumber !== undefined) { + extraHeaders["x-trigger-attempt-number"] = String(this.attemptNumber); + } + logger.log(`connecting to coordinator: ${host}:${COORDINATOR_PORT}`); logger.debug(`connecting with extra headers`, { extraHeaders }); @@ -851,40 +888,14 @@ class ProdWorker { return; } - this.durationResumeFallback = undefined; - this.#resumeAfterDuration(); }, - // Deprecated: This will never get called as this worker supports lazy attempts. It's only here for a quick view of the flow old workers use. - EXECUTE_TASK_RUN: async ({ executionPayload }) => { - if (this.executing) { - logger.error("dropping execute request, already executing"); - return; - } - - if (this.completed.has(executionPayload.execution.attempt.id)) { - logger.error("dropping execute request, already completed"); - return; - } - - this.executing = true; - this.attemptFriendlyId = executionPayload.execution.attempt.id; - const completion = await this.#backgroundWorker.executeTaskRun(executionPayload); - - logger.log("completed", completion); - - this.completed.add(executionPayload.execution.attempt.id); - - const { willCheckpointAndRestore, shouldExit } = - await this.#coordinatorSocket.socket.emitWithAck("TASK_RUN_COMPLETED", { - version: "v1", - execution: executionPayload.execution, - completion, - }); - - logger.log("completion acknowledged", { willCheckpointAndRestore, shouldExit }); - - await this.#prepareForRetry(willCheckpointAndRestore, shouldExit); + EXECUTE_TASK_RUN: async () => { + // These messages should only be received by old workers that don't support lazy attempts + this.#failRun( + this.runId, + "Received deprecated EXECUTE_TASK_RUN message. Please contact us if you see this error." + ); }, EXECUTE_TASK_RUN_LAZY_ATTEMPT: async (message) => { this.readyForLazyAttemptReplay = undefined; @@ -947,8 +958,6 @@ class ProdWorker { return; } - this.submitAttemptCompletionReplay = undefined; - await this.#readyForLazyAttempt(); }, }, @@ -960,7 +969,11 @@ class ProdWorker { }); // We need to send our current state to the coordinator - socket.emit("SET_STATE", { version: "v1", attemptFriendlyId: this.attemptFriendlyId }); + socket.emit("SET_STATE", { + version: "v1", + attemptFriendlyId: this.attemptFriendlyId, + attemptNumber: this.attemptNumber ? String(this.attemptNumber) : undefined, + }); try { if (this.waitForPostStart) { @@ -981,7 +994,7 @@ class ProdWorker { } if (!this.attemptFriendlyId) { - logger.error("Missing friendly ID", { status: this.#status }); + logger.error("Missing attempt friendly ID", { status: this.#status }); this.#emitUnrecoverableError( "NoAttemptId", @@ -991,9 +1004,21 @@ class ProdWorker { return; } + if (!this.attemptNumber) { + logger.error("Missing attempt number", { status: this.#status }); + + this.#emitUnrecoverableError( + "NoAttemptNumber", + "Attempt number not set while resuming from paused state" + ); + + return; + } + socket.emit("READY_FOR_RESUME", { - version: "v1", + version: "v2", attemptFriendlyId: this.attemptFriendlyId, + attemptNumber: this.attemptNumber, type: this.nextResumeAfter, }); @@ -1169,7 +1194,7 @@ class ProdWorker { try { await backoff.wait(attempt + 1); - await this.#waitForTaskHandler(message); + await this.#waitForTaskHandlerFactory("replay")(message, idempotencyKey); } catch (error) { if (error instanceof ExponentialBackoff.RetryLimitExceeded) { logger.error("wait for task replay retry limit exceeded", { error }); @@ -1212,7 +1237,7 @@ class ProdWorker { try { await backoff.wait(attempt + 1); - await this.#waitForBatchHandler(message); + await this.#waitForBatchHandlerFactory("replay")(message, idempotencyKey); } catch (error) { if (error instanceof ExponentialBackoff.RetryLimitExceeded) { logger.error("wait for batch replay retry limit exceeded", { error }); @@ -1223,49 +1248,6 @@ class ProdWorker { return; } - - if (this.submitAttemptCompletionReplay) { - logger.log("replaying attempt completion", { - ...this.submitAttemptCompletionReplay, - cancellationDelay: replayCancellationDelay, - }); - - const { idempotencyKey, message, attempt } = this.submitAttemptCompletionReplay; - - // Give the platform some time to send READY_FOR_RETRY - await timeout(replayCancellationDelay); - - if (!this.submitAttemptCompletionReplay) { - logger.error("attempt completion replay cancelled, discarding", { - originalMessage: { idempotencyKey, message, attempt }, - }); - - return; - } - - if (idempotencyKey !== this.submitAttemptCompletionReplay.idempotencyKey) { - logger.error("attempt completion replay idempotency key mismatch, discarding", { - originalMessage: { idempotencyKey, message, attempt }, - newMessage: this.submitAttemptCompletionReplay, - }); - - return; - } - - try { - await backoff.wait(attempt + 1); - - await this.#submitAttemptCompletion(message.execution, message.completion, idempotencyKey); - } catch (error) { - if (error instanceof ExponentialBackoff.RetryLimitExceeded) { - logger.error("attempt completion replay retry limit exceeded", { error }); - } else { - logger.error("attempt completion replay error", { error }); - } - } - - return; - } } // MARK: HTTP SERVER @@ -1345,6 +1327,7 @@ class ProdWorker { } case "restore": { await this.#reconnectAfterPostStart(); + this.restoreNotification.post(); break; } default: { @@ -1452,6 +1435,7 @@ class ProdWorker { nextResumeAfter: this.nextResumeAfter, waitForPostStart: this.waitForPostStart, attemptFriendlyId: this.attemptFriendlyId, + attemptNumber: this.attemptNumber, waitForTaskReplay: this.waitForTaskReplay, waitForBatchReplay: this.waitForBatchReplay, }; diff --git a/packages/core-apps/src/provider.ts b/packages/core-apps/src/provider.ts index bfb88f1f0..74c7b2c7f 100644 --- a/packages/core-apps/src/provider.ts +++ b/packages/core-apps/src/provider.ts @@ -43,6 +43,7 @@ export interface TaskOperationsCreateOptions { image: string; machine: MachinePreset; version: string; + nextAttemptNumber?: number; // identifiers envId: string; envType: EnvironmentType; @@ -55,6 +56,7 @@ export interface TaskOperationsRestoreOptions { imageRef: string; checkpointRef: string; machine: MachinePreset; + attemptNumber?: number; // identifiers envId: string; envType: EnvironmentType; @@ -142,6 +144,7 @@ export class ProviderShell implements Provider { image: message.data.image, machine: message.data.machine, version: message.data.version, + nextAttemptNumber: message.data.nextAttemptNumber, // identifiers envId: message.data.envId, envType: message.data.envType, @@ -278,6 +281,7 @@ export class ProviderShell implements Provider { checkpointRef: message.location, machine: message.machine, imageRef: message.imageRef, + attemptNumber: message.attemptNumber, // identifiers envId: message.envId, envType: message.envType, diff --git a/packages/core/src/v3/schemas/messages.ts b/packages/core/src/v3/schemas/messages.ts index 72a80ab1d..5e5122f2a 100644 --- a/packages/core/src/v3/schemas/messages.ts +++ b/packages/core/src/v3/schemas/messages.ts @@ -31,6 +31,7 @@ export const BackgroundWorkerServerMessages = z.discriminatedUnion("type", [ image: z.string(), version: z.string(), machine: MachinePreset, + nextAttemptNumber: z.number().optional(), // identifiers id: z.string().optional(), // TODO: Remove this completely in a future release envId: z.string(), @@ -357,6 +358,7 @@ export const PlatformToProviderMessages = { location: z.string(), reason: z.string().optional(), imageRef: z.string(), + attemptNumber: z.number().optional(), machine: MachinePreset, // identifiers checkpointId: z.string(), @@ -482,7 +484,7 @@ export const CoordinatorToPlatformMessages = { }, TASK_RUN_COMPLETED: { message: z.object({ - version: z.literal("v1").default("v1"), + version: z.enum(["v1", "v2"]).default("v1"), execution: ProdTaskRunExecution, completion: TaskRunExecutionResult, checkpoint: z @@ -701,11 +703,19 @@ export const ProdWorkerToCoordinatorMessages = { }), }, READY_FOR_RESUME: { - message: z.object({ - version: z.literal("v1").default("v1"), - attemptFriendlyId: z.string(), - type: WaitReason, - }), + message: z.discriminatedUnion("version", [ + z.object({ + version: z.literal("v1"), + attemptFriendlyId: z.string(), + type: WaitReason, + }), + z.object({ + version: z.literal("v2"), + attemptFriendlyId: z.string(), + attemptNumber: z.number(), + type: WaitReason, + }), + ]), }, READY_FOR_CHECKPOINT: { message: z.object({ @@ -744,7 +754,7 @@ export const ProdWorkerToCoordinatorMessages = { }, TASK_RUN_COMPLETED: { message: z.object({ - version: z.literal("v1").default("v1"), + version: z.enum(["v1", "v2"]).default("v1"), execution: ProdTaskRunExecution, completion: TaskRunExecutionResult, }), @@ -835,6 +845,7 @@ export const ProdWorkerToCoordinatorMessages = { message: z.object({ version: z.literal("v1").default("v1"), attemptFriendlyId: z.string().optional(), + attemptNumber: z.string().optional(), }), }, }; @@ -899,6 +910,7 @@ export const ProdWorkerSocketData = z.object({ envId: z.string(), runId: z.string(), attemptFriendlyId: z.string().optional(), + attemptNumber: z.string().optional(), podName: z.string(), deploymentId: z.string(), deploymentVersion: z.string(), diff --git a/packages/database/prisma/migrations/20240809213411_add_checkpoint_attempt_number_column/migration.sql b/packages/database/prisma/migrations/20240809213411_add_checkpoint_attempt_number_column/migration.sql new file mode 100644 index 000000000..738f17c4d --- /dev/null +++ b/packages/database/prisma/migrations/20240809213411_add_checkpoint_attempt_number_column/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Checkpoint" ADD COLUMN "attemptNumber" INTEGER; diff --git a/packages/database/prisma/schema.prisma b/packages/database/prisma/schema.prisma index 8fdbdd596..88ac6e368 100644 --- a/packages/database/prisma/schema.prisma +++ b/packages/database/prisma/schema.prisma @@ -2115,8 +2115,9 @@ model Checkpoint { run TaskRun @relation(fields: [runId], references: [id], onDelete: Cascade, onUpdate: Cascade) runId String - attempt TaskRunAttempt @relation(fields: [attemptId], references: [id], onDelete: Cascade, onUpdate: Cascade) - attemptId String + attempt TaskRunAttempt @relation(fields: [attemptId], references: [id], onDelete: Cascade, onUpdate: Cascade) + attemptId String + attemptNumber Int? project Project @relation(fields: [projectId], references: [id], onDelete: Cascade, onUpdate: Cascade) projectId String From 0e990fd2b57fa8e2b9ce83e6fe56240f93cc23fa Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 13 Aug 2024 14:54:50 +0100 Subject: [PATCH 09/33] Added more logging to TaskRunConcurrencyTracker and some more try/catches --- .../taskRunConcurrencyTracker.server.ts | 120 ++++++++++++------ 1 file changed, 79 insertions(+), 41 deletions(-) diff --git a/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts b/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts index 4711033e5..dba230419 100644 --- a/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts +++ b/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts @@ -26,6 +26,11 @@ class TaskRunConcurrencyTracker implements MessageQueueSubscriber { async messageEnqueued(message: MessagePayload): Promise {} async messageDequeued(message: MessagePayload): Promise { + logger.debug("TaskRunConcurrencyTracker.messageDequeued()", { + data: message.data, + messageId: message.messageId, + }); + const data = this.getMessageData(message); if (!data) { logger.info( @@ -45,6 +50,11 @@ class TaskRunConcurrencyTracker implements MessageQueueSubscriber { } async messageAcked(message: MessagePayload): Promise { + logger.debug("TaskRunConcurrencyTracker.messageAcked()", { + data: message.data, + messageId: message.messageId, + }); + const data = this.getMessageData(message); if (!data) { logger.info( @@ -64,6 +74,11 @@ class TaskRunConcurrencyTracker implements MessageQueueSubscriber { } async messageNacked(message: MessagePayload): Promise { + logger.debug("TaskRunConcurrencyTracker.messageNacked()", { + data: message.data, + messageId: message.messageId, + }); + const data = this.getMessageData(message); if (!data) { logger.info( @@ -103,14 +118,18 @@ class TaskRunConcurrencyTracker implements MessageQueueSubscriber { environmentId: string; deployed: boolean; }): Promise { - const pipeline = this.redis.pipeline(); + try { + const pipeline = this.redis.pipeline(); - pipeline.sadd(this.getTaskKey(projectId, taskId), runId); - pipeline.sadd(this.getTaskEnvironmentKey(projectId, taskId, environmentId), runId); - pipeline.sadd(this.getEnvironmentKey(projectId, environmentId), runId); - pipeline.sadd(this.getGlobalKey(deployed), runId); + pipeline.sadd(this.getTaskKey(projectId, taskId), runId); + pipeline.sadd(this.getTaskEnvironmentKey(projectId, taskId, environmentId), runId); + pipeline.sadd(this.getEnvironmentKey(projectId, environmentId), runId); + pipeline.sadd(this.getGlobalKey(deployed), runId); - await pipeline.exec(); + await pipeline.exec(); + } catch (error) { + logger.error("TaskRunConcurrencyTracker.executionStarted() error", { error }); + } } private async executionFinished({ @@ -126,14 +145,18 @@ class TaskRunConcurrencyTracker implements MessageQueueSubscriber { environmentId: string; deployed: boolean; }): Promise { - const pipeline = this.redis.pipeline(); + try { + const pipeline = this.redis.pipeline(); - pipeline.srem(this.getTaskKey(projectId, taskId), runId); - pipeline.srem(this.getTaskEnvironmentKey(projectId, taskId, environmentId), runId); - pipeline.srem(this.getEnvironmentKey(projectId, environmentId), runId); - pipeline.srem(this.getGlobalKey(deployed), runId); + pipeline.srem(this.getTaskKey(projectId, taskId), runId); + pipeline.srem(this.getTaskEnvironmentKey(projectId, taskId, environmentId), runId); + pipeline.srem(this.getEnvironmentKey(projectId, environmentId), runId); + pipeline.srem(this.getGlobalKey(deployed), runId); - await pipeline.exec(); + await pipeline.exec(); + } catch (error) { + logger.error("TaskRunConcurrencyTracker.executionFinished() error", { error }); + } } async taskConcurrentRunCount(projectId: string, taskId: string): Promise { @@ -149,21 +172,26 @@ class TaskRunConcurrencyTracker implements MessageQueueSubscriber { } private async getTaskCounts(projectId: string, taskIds: string[]): Promise { - const pipeline = this.redis.pipeline(); - taskIds.forEach((taskId) => { - pipeline.scard(this.getTaskKey(projectId, taskId)); - }); - const results = await pipeline.exec(); - if (!results) { + try { + const pipeline = this.redis.pipeline(); + taskIds.forEach((taskId) => { + pipeline.scard(this.getTaskKey(projectId, taskId)); + }); + const results = await pipeline.exec(); + if (!results) { + return []; + } + return results.map(([err, count]) => { + if (err) { + console.error("Error in getTaskCounts:", err); + return 0; + } + return count as number; + }); + } catch (error) { + logger.error("TaskRunConcurrencyTracker.getTaskCounts() error", { error }); return []; } - return results.map(([err, count]) => { - if (err) { - console.error("Error in getTaskCounts:", err); - return 0; - } - return count as number; - }); } async projectTotalConcurrentRunCount(projectId: string, taskIds: string[]): Promise { @@ -177,7 +205,7 @@ class TaskRunConcurrencyTracker implements MessageQueueSubscriber { ): Promise> { const counts = await this.getTaskCounts(projectId, taskIds); return taskIds.reduce((acc, taskId, index) => { - acc[taskId] = counts[index]; + acc[taskId] = counts[index] ?? 0; return acc; }, {} as Record); } @@ -186,23 +214,28 @@ class TaskRunConcurrencyTracker implements MessageQueueSubscriber { projectId: string, environmentIds: string[] ): Promise> { - const pipeline = this.redis.pipeline(); - environmentIds.forEach((environmentId) => { - pipeline.scard(this.getEnvironmentKey(projectId, environmentId)); - }); - const results = await pipeline.exec(); - if (!results) { + try { + const pipeline = this.redis.pipeline(); + environmentIds.forEach((environmentId) => { + pipeline.scard(this.getEnvironmentKey(projectId, environmentId)); + }); + const results = await pipeline.exec(); + if (!results) { + return Object.fromEntries(environmentIds.map((id) => [id, 0])); + } + + return results.reduce((acc, [err, count], index) => { + if (err) { + console.error("Error in environmentConcurrentRunCounts:", err); + return acc; + } + acc[environmentIds[index]] = count as number; + return acc; + }, {} as Record); + } catch (error) { + logger.error("TaskRunConcurrencyTracker.environmentConcurrentRunCounts() error", { error }); return Object.fromEntries(environmentIds.map((id) => [id, 0])); } - - return results.reduce((acc, [err, count], index) => { - if (err) { - console.error("Error in environmentConcurrentRunCounts:", err); - return acc; - } - acc[environmentIds[index]] = count as number; - return acc; - }, {} as Record); } private getTaskKey(projectId: string, taskId: string): string { @@ -231,6 +264,11 @@ function getTracker() { ); } + logger.debug("Initializing TaskRunConcurrencyTracker", { + redisHost: env.REDIS_HOST, + redisPort: env.REDIS_PORT, + }); + return new TaskRunConcurrencyTracker({ redis: { keyPrefix: "concurrencytracker:", From 6b0c37ae6d3751a8ae32cb2f20c585055b011031 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 13 Aug 2024 15:31:25 +0100 Subject: [PATCH 10/33] Call subscriber.messageDequeued in dequeueMessageInSharedQueue --- apps/webapp/app/v3/marqs/index.server.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/webapp/app/v3/marqs/index.server.ts b/apps/webapp/app/v3/marqs/index.server.ts index fb7381f67..bd8247b5a 100644 --- a/apps/webapp/app/v3/marqs/index.server.ts +++ b/apps/webapp/app/v3/marqs/index.server.ts @@ -386,6 +386,8 @@ export class MarQS { [SemanticAttributes.CONCURRENCY_KEY]: message.concurrencyKey, [SemanticAttributes.PARENT_QUEUE]: message.parentQueue, }); + + await this.options.subscriber?.messageDequeued(message); } await this.options.visibilityTimeoutStrategy.heartbeat( From 41c551de3d3d4f1b5a303c1e76d14780f5ca3b83 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 13 Aug 2024 16:36:39 +0100 Subject: [PATCH 11/33] Added messageReplaced to concurrency tracking (when freezing) --- apps/webapp/app/v3/marqs/index.server.ts | 2 ++ apps/webapp/app/v3/marqs/types.ts | 1 + .../taskRunConcurrencyTracker.server.ts | 24 +++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/apps/webapp/app/v3/marqs/index.server.ts b/apps/webapp/app/v3/marqs/index.server.ts index bd8247b5a..252723f90 100644 --- a/apps/webapp/app/v3/marqs/index.server.ts +++ b/apps/webapp/app/v3/marqs/index.server.ts @@ -507,6 +507,8 @@ export class MarQS { }); await this.#callEnqueueMessage(newMessage); + + await this.options.subscriber?.messageReplaced(newMessage); }, { kind: SpanKind.CONSUMER, diff --git a/apps/webapp/app/v3/marqs/types.ts b/apps/webapp/app/v3/marqs/types.ts index 559b4b23f..afe6c8fef 100644 --- a/apps/webapp/app/v3/marqs/types.ts +++ b/apps/webapp/app/v3/marqs/types.ts @@ -97,6 +97,7 @@ export interface MessageQueueSubscriber { messageDequeued(message: MessagePayload): Promise; messageAcked(message: MessagePayload): Promise; messageNacked(message: MessagePayload): Promise; + messageReplaced(message: MessagePayload): Promise; } export interface VisibilityTimeoutStrategy { diff --git a/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts b/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts index dba230419..451a5e20b 100644 --- a/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts +++ b/apps/webapp/app/v3/services/taskRunConcurrencyTracker.server.ts @@ -97,6 +97,30 @@ class TaskRunConcurrencyTracker implements MessageQueueSubscriber { }); } + async messageReplaced(message: MessagePayload): Promise { + logger.debug("TaskRunConcurrencyTracker.messageReplaced()", { + data: message.data, + messageId: message.messageId, + }); + + const data = this.getMessageData(message); + if (!data) { + logger.info( + `TaskRunConcurrencyTracker.messageReplaced(): could not parse message data`, + message + ); + return; + } + + await this.executionFinished({ + projectId: data.projectId, + taskId: data.taskIdentifier, + runId: message.messageId, + environmentId: data.environmentId, + deployed: data.environmentType !== "DEVELOPMENT", + }); + } + private getMessageData(message: MessagePayload) { const result = ConcurrentMessageData.safeParse(message.data); if (result.success) { From ff435fb8ad3b6951af603595a119acb146d23022 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Tue, 13 Aug 2024 17:06:38 +0100 Subject: [PATCH 12/33] Added depenenciesToBundle guide to bundle all packages --- docs/snippets/bundle-packages.mdx | 31 +++++++++++++++++++++++++++++++ docs/trigger-config.mdx | 12 +++--------- docs/troubleshooting.mdx | 14 +++----------- 3 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 docs/snippets/bundle-packages.mdx diff --git a/docs/snippets/bundle-packages.mdx b/docs/snippets/bundle-packages.mdx new file mode 100644 index 000000000..a4477b5b5 --- /dev/null +++ b/docs/snippets/bundle-packages.mdx @@ -0,0 +1,31 @@ + + + + Bundle all ESM packages so that you don't have to specifiy them manually like this: + + ```ts trigger.config.ts + import type { TriggerConfig } from "@trigger.dev/sdk/v3"; + + export const config: TriggerConfig = { + //..other stuff + dependenciesToBundle: [/.*/], + }; + ``` + + + + + Bundle individual packages using strings or regex like this: + + ```ts trigger.config.ts + import type { TriggerConfig } from "@trigger.dev/sdk/v3"; + + export const config: TriggerConfig = { + //..other stuff + //either regex or strings of package names + dependenciesToBundle: [/@sindresorhus/, "escape-string-regexp"], + }; + ``` + + + \ No newline at end of file diff --git a/docs/trigger-config.mdx b/docs/trigger-config.mdx index 360cb9557..15e8cd40a 100644 --- a/docs/trigger-config.mdx +++ b/docs/trigger-config.mdx @@ -4,6 +4,8 @@ sidebarTitle: "trigger.config file" description: "This file is used to configure your project and how it's bundled." --- +import BundlePackages from '/snippets/bundle-packages.mdx'; + Let's take a look at a basic `trigger.config.ts` file. This is generated for you when you follow [the quick start guide](/quick-start). This file is used to configure your project and how it's bundled. ```ts trigger.config.ts @@ -110,15 +112,7 @@ You can sync environment variables from another service using the `resolveEnvVar We'll let you know when running the CLI dev command if this is a problem. Some packages are ESM-only so they don't work directly from CJS when using Node.js. In that case you need to add them to the `dependenciesToBundle` array in your `trigger.config.ts` file. -```ts trigger.config.ts -import type { TriggerConfig } from "@trigger.dev/sdk/v3"; - -export const config: TriggerConfig = { - //..other stuff - //either regex or strings of package names - dependenciesToBundle: [/@sindresorhus/, "escape-string-regexp"], -}; -``` + ## Prisma (and other generators) diff --git a/docs/troubleshooting.mdx b/docs/troubleshooting.mdx index 0dd5871ba..8d82d9447 100644 --- a/docs/troubleshooting.mdx +++ b/docs/troubleshooting.mdx @@ -3,6 +3,8 @@ title: "Common problems" description: "Some common problems you might experience and their solutions" --- +import BundlePackages from '/snippets/bundle-packages.mdx'; + ## Development ### `EACCES: permission denied` @@ -44,17 +46,7 @@ You can skip typechecking, by adding the `--skip-typecheck` flag when calling de This errors occurs if we can't figure out how to automatically import some code. You can fix this by adding it to the `dependenciesToBundle` array in the [trigger.config file](/trigger-config). -Like this: - -```ts trigger.config.ts -import type { TriggerConfig } from "@trigger.dev/sdk/v3"; - -export const config: TriggerConfig = { - //..other stuff - //either regex or strings of package names - dependenciesToBundle: [/@sindresorhus/, "escape-string-regexp"], -}; -``` + ### `Failed to build project image: Error building image` From 26e872aa547dba98230e1a1f8266c12cab983d83 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 13 Aug 2024 17:09:27 +0100 Subject: [PATCH 13/33] Include the old message data when replacing, so we get the projectId etc. --- apps/webapp/app/v3/marqs/index.server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/webapp/app/v3/marqs/index.server.ts b/apps/webapp/app/v3/marqs/index.server.ts index 252723f90..373908af1 100644 --- a/apps/webapp/app/v3/marqs/index.server.ts +++ b/apps/webapp/app/v3/marqs/index.server.ts @@ -480,7 +480,7 @@ export class MarQS { const newMessage: MessagePayload = { version: "1", // preserve original trace context - data: { ...messageData, ...traceContext }, + data: { ...oldMessage.data, ...messageData, ...traceContext }, queue: oldMessage.queue, concurrencyKey: oldMessage.concurrencyKey, timestamp: timestamp ?? Date.now(), From cbaaa3bb1f324d2023cbeba4ff46699affe0e452 Mon Sep 17 00:00:00 2001 From: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Tue, 13 Aug 2024 17:17:40 +0100 Subject: [PATCH 14/33] Fix restored container names --- apps/coordinator/src/checkpointer.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/coordinator/src/checkpointer.ts b/apps/coordinator/src/checkpointer.ts index 29eb4df3a..d469541d7 100644 --- a/apps/coordinator/src/checkpointer.ts +++ b/apps/coordinator/src/checkpointer.ts @@ -422,14 +422,15 @@ export class Checkpointer { this.#logger.log("Checkpointing:", { options }); - const containterName = this.#getRunContainerName(runId, attemptNumber); + const containterName = this.#getRunContainerName(runId); + const containterNameWithAttempt = this.#getRunContainerName(runId, attemptNumber); // Create checkpoint (docker) if (this.#dockerMode) { try { if (this.opts.forceSimulate || !this.#canCheckpoint) { this.#logger.log("Simulating checkpoint"); - this.#logger.debug(await $$`docker pause ${containterName}`); + this.#logger.debug(await $$`docker pause ${containterNameWithAttempt}`); } else { if (this.simulateCheckpointFailure) { if (performance.now() < this.simulateCheckpointFailureSeconds * 1000) { @@ -440,11 +441,11 @@ export class Checkpointer { if (leaveRunning) { this.#logger.debug( - await $$`docker checkpoint create --leave-running ${containterName} ${exportLocation}` + await $$`docker checkpoint create --leave-running ${containterNameWithAttempt} ${exportLocation}` ); } else { this.#logger.debug( - await $$`docker checkpoint create ${containterName} ${exportLocation}` + await $$`docker checkpoint create ${containterNameWithAttempt} ${exportLocation}` ); } } From 494e1eadaa0840032fa0ed70ff7a137e01ae5922 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Wed, 14 Aug 2024 11:23:16 +0100 Subject: [PATCH 15/33] Fix for schedule page not scrolling --- .../route.tsx | 130 +++++++++--------- 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.schedules/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.schedules/route.tsx index a5cbc7889..53b4f31ec 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.schedules/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.schedules/route.tsx @@ -51,7 +51,7 @@ import { useProject } from "~/hooks/useProject"; import { redirectWithErrorMessage } from "~/models/message.server"; import { findProjectBySlug } from "~/models/project.server"; import { - ScheduleListItem, + type ScheduleListItem, ScheduleListPresenter, } from "~/presenters/v3/ScheduleListPresenter.server"; import { requireUserId } from "~/services/session.server"; @@ -179,72 +179,74 @@ export default function Page() { - {possibleTasks.length === 0 ? ( - - ) : schedules.length === 0 && !hasFilters ? ( - - ) : ( -
-
- -
- + {possibleTasks.length === 0 ? ( + + ) : schedules.length === 0 && !hasFilters ? ( + + ) : ( +
+
+ +
+ +
+
+ + +
+ {requiresUpgrade ? ( + + + You've used all {limits.limit} of your available schedules. Upgrade your + plan to enable more. + + + ) : ( +
+
+ + You've used {limits.used}/{limits.limit} of your schedules. + + + {canUpgrade ? ( + + Upgrade + + ) : ( + Request more} + defaultValue="help" + /> + )} +
+
+
+
+
+ )} +
- - -
- {requiresUpgrade ? ( - - - You've used all {limits.limit} of your available schedules. Upgrade your - plan to enable more. - - - ) : ( -
-
- - You've used {limits.used}/{limits.limit} of your schedules. - - - {canUpgrade ? ( - - Upgrade - - ) : ( - Request more} - defaultValue="help" - /> - )} -
-
-
-
-
- )} - -
-
- )} + )} +
{(isShowingNewPane || isShowingSchedule) && ( <> From cd10d47ae0f3c195a3c27369340e428623c5227b Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Wed, 14 Aug 2024 11:33:15 +0100 Subject: [PATCH 16/33] Added a description panel to the Concurrency admin page --- apps/webapp/app/routes/admin.concurrency.tsx | 24 +++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/apps/webapp/app/routes/admin.concurrency.tsx b/apps/webapp/app/routes/admin.concurrency.tsx index b0fe1484b..a24f7debb 100644 --- a/apps/webapp/app/routes/admin.concurrency.tsx +++ b/apps/webapp/app/routes/admin.concurrency.tsx @@ -1,6 +1,8 @@ +import { InformationCircleIcon } from "@heroicons/react/20/solid"; import type { LoaderFunctionArgs } from "@remix-run/server-runtime"; import { redirect, typedjson, useTypedLoaderData } from "remix-typedjson"; import { Header1 } from "~/components/primitives/Headers"; +import { InfoPanel } from "~/components/primitives/InfoPanel"; import { Paragraph } from "~/components/primitives/Paragraph"; import { requireUser } from "~/services/session.server"; import { concurrencyTracker } from "~/v3/services/taskRunConcurrencyTracker.server"; @@ -23,16 +25,22 @@ export default function AdminDashboardRoute() { return (
-
- Dev - {devConcurrency} -
-
- Deployed - {deployedConcurrency} +
+
+ Dev + {devConcurrency} +
+
+ Deployed + {deployedConcurrency} +
+ + This refers to the number of 'Dequeued' runs, which are either currently executing or about + to begin execution. +
); } From 31da143be01eb6abe98bf6ac73ade0b781dc573e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:39:44 +0100 Subject: [PATCH 17/33] chore: Update version for release (beta) (#1256) Co-authored-by: github-actions[bot] --- .changeset/pre.json | 1 + integrations/airtable/CHANGELOG.md | 7 +++++++ integrations/airtable/package.json | 6 +++--- integrations/github/CHANGELOG.md | 7 +++++++ integrations/github/package.json | 6 +++--- integrations/linear/CHANGELOG.md | 7 +++++++ integrations/linear/package.json | 6 +++--- integrations/openai/CHANGELOG.md | 7 +++++++ integrations/openai/package.json | 6 +++--- integrations/plain/CHANGELOG.md | 7 +++++++ integrations/plain/package.json | 6 +++--- integrations/replicate/CHANGELOG.md | 7 +++++++ integrations/replicate/package.json | 6 +++--- integrations/resend/CHANGELOG.md | 7 +++++++ integrations/resend/package.json | 6 +++--- integrations/sendgrid/CHANGELOG.md | 7 +++++++ integrations/sendgrid/package.json | 6 +++--- integrations/shopify/CHANGELOG.md | 7 +++++++ integrations/shopify/package.json | 6 +++--- integrations/slack/CHANGELOG.md | 6 ++++++ integrations/slack/package.json | 4 ++-- integrations/stripe/CHANGELOG.md | 7 +++++++ integrations/stripe/package.json | 6 +++--- integrations/supabase/CHANGELOG.md | 7 +++++++ integrations/supabase/package.json | 6 +++--- integrations/typeform/CHANGELOG.md | 7 +++++++ integrations/typeform/package.json | 6 +++--- packages/astro/CHANGELOG.md | 6 ++++++ packages/astro/package.json | 4 ++-- packages/cli-v3/CHANGELOG.md | 13 +++++++++++++ packages/cli-v3/package.json | 4 ++-- packages/cli/CHANGELOG.md | 8 ++++++++ packages/cli/package.json | 2 +- packages/core-apps/CHANGELOG.md | 11 +++++++++++ packages/core-apps/package.json | 2 +- packages/core-backend/CHANGELOG.md | 2 ++ packages/core-backend/package.json | 2 +- packages/core/CHANGELOG.md | 11 +++++++++++ packages/core/package.json | 2 +- packages/eslint-plugin/CHANGELOG.md | 2 ++ packages/eslint-plugin/package.json | 2 +- packages/express/CHANGELOG.md | 6 ++++++ packages/express/package.json | 6 +++--- packages/hono/CHANGELOG.md | 6 ++++++ packages/hono/package.json | 4 ++-- packages/integration-kit/CHANGELOG.md | 7 +++++++ packages/integration-kit/package.json | 2 +- packages/nestjs/CHANGELOG.md | 6 ++++++ packages/nestjs/package.json | 6 +++--- packages/nextjs/CHANGELOG.md | 6 ++++++ packages/nextjs/package.json | 4 ++-- packages/otlp-importer/CHANGELOG.md | 2 ++ packages/otlp-importer/package.json | 2 +- packages/react/CHANGELOG.md | 7 +++++++ packages/react/package.json | 4 ++-- packages/remix/CHANGELOG.md | 6 ++++++ packages/remix/package.json | 4 ++-- packages/sveltekit/CHANGELOG.md | 6 ++++++ packages/sveltekit/package.json | 4 ++-- packages/testing/CHANGELOG.md | 8 ++++++++ packages/testing/package.json | 2 +- packages/trigger-sdk/CHANGELOG.md | 8 ++++++++ packages/trigger-sdk/package.json | 6 +++--- packages/yalt/CHANGELOG.md | 2 ++ packages/yalt/package.json | 2 +- 65 files changed, 284 insertions(+), 70 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 062f53b3c..25d5b5191 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -84,6 +84,7 @@ "hot-buckets-behave", "hot-fishes-retire", "hot-wasps-sin", + "hungry-sloths-promise", "itchy-chairs-itch", "khaki-apricots-design", "khaki-poems-lay", diff --git a/integrations/airtable/CHANGELOG.md b/integrations/airtable/CHANGELOG.md index 429fc6f00..fc5542b7c 100644 --- a/integrations/airtable/CHANGELOG.md +++ b/integrations/airtable/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/airtable +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/airtable/package.json b/integrations/airtable/package.json index 978ec5ce7..959fd8088 100644 --- a/integrations/airtable/package.json +++ b/integrations/airtable/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/airtable", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev integration for airtable", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -25,8 +25,8 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "airtable": "^0.12.1", "zod": "3.22.3" }, diff --git a/integrations/github/CHANGELOG.md b/integrations/github/CHANGELOG.md index 74d53b790..83c3d5f25 100644 --- a/integrations/github/CHANGELOG.md +++ b/integrations/github/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/github +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/github/package.json b/integrations/github/package.json index 6ee8cdb1f..c9f7a89c3 100644 --- a/integrations/github/package.json +++ b/integrations/github/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/github", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "The official GitHub integration for Trigger.dev", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -30,8 +30,8 @@ "@octokit/request-error": "^5.0.1", "@octokit/webhooks": "^12.0.10", "octokit": "^3.1.2", - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "zod": "3.22.3" }, "engines": { diff --git a/integrations/linear/CHANGELOG.md b/integrations/linear/CHANGELOG.md index 343ca98ea..cd98bcf6f 100644 --- a/integrations/linear/CHANGELOG.md +++ b/integrations/linear/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/linear +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/linear/package.json b/integrations/linear/package.json index 52c84ae97..af502baf6 100644 --- a/integrations/linear/package.json +++ b/integrations/linear/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/linear", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev integration for @linear/sdk", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -26,8 +26,8 @@ }, "dependencies": { "@linear/sdk": "^8.0.0", - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "zod": "3.22.3" }, "engines": { diff --git a/integrations/openai/CHANGELOG.md b/integrations/openai/CHANGELOG.md index 568a2f79c..9d865bfdf 100644 --- a/integrations/openai/CHANGELOG.md +++ b/integrations/openai/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/slack +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/openai/package.json b/integrations/openai/package.json index 8b8b5f20f..a70ce806b 100644 --- a/integrations/openai/package.json +++ b/integrations/openai/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/openai", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "The official OpenAI integration for Trigger.dev", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -42,8 +42,8 @@ }, "dependencies": { "openai": "^4.16.1", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52" + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53" }, "engines": { "node": ">=18.0.0" diff --git a/integrations/plain/CHANGELOG.md b/integrations/plain/CHANGELOG.md index c8dccc632..06ca03f29 100644 --- a/integrations/plain/CHANGELOG.md +++ b/integrations/plain/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/plain +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/plain/package.json b/integrations/plain/package.json index 75f051294..6bf54229e 100644 --- a/integrations/plain/package.json +++ b/integrations/plain/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/plain", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "The official Plain.com integration for Trigger.dev", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -24,8 +24,8 @@ "build:tsup": "tsup" }, "dependencies": { - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "@team-plain/typescript-sdk": "^2.7.0" }, "engines": { diff --git a/integrations/replicate/CHANGELOG.md b/integrations/replicate/CHANGELOG.md index 2618d8fc8..699b11533 100644 --- a/integrations/replicate/CHANGELOG.md +++ b/integrations/replicate/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/replicate +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/replicate/package.json b/integrations/replicate/package.json index 47b0414cc..dadc5c4ef 100644 --- a/integrations/replicate/package.json +++ b/integrations/replicate/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/replicate", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev integration for replicate", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -25,8 +25,8 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "replicate": "^0.18.1", "zod": "3.22.3" }, diff --git a/integrations/resend/CHANGELOG.md b/integrations/resend/CHANGELOG.md index a0896b6dc..1c06799a0 100644 --- a/integrations/resend/CHANGELOG.md +++ b/integrations/resend/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/resend +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/resend/package.json b/integrations/resend/package.json index 1a68c151f..b6aa06233 100644 --- a/integrations/resend/package.json +++ b/integrations/resend/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/resend", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "The official Resend.com integration for Trigger.dev", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -24,8 +24,8 @@ "build:tsup": "tsup" }, "dependencies": { - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "resend": "^2.1.0" }, "engines": { diff --git a/integrations/sendgrid/CHANGELOG.md b/integrations/sendgrid/CHANGELOG.md index 8ad3311ce..1bd6bf8ab 100644 --- a/integrations/sendgrid/CHANGELOG.md +++ b/integrations/sendgrid/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/sendgrid +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/sendgrid/package.json b/integrations/sendgrid/package.json index 451e35f47..9f6423021 100644 --- a/integrations/sendgrid/package.json +++ b/integrations/sendgrid/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/sendgrid", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev integration for @sendgrid/mail", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -26,8 +26,8 @@ }, "dependencies": { "@sendgrid/mail": "^7.7.0", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52" + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53" }, "engines": { "node": ">=16.8.0" diff --git a/integrations/shopify/CHANGELOG.md b/integrations/shopify/CHANGELOG.md index 20aa76589..d18153763 100644 --- a/integrations/shopify/CHANGELOG.md +++ b/integrations/shopify/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/shopify +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/shopify/package.json b/integrations/shopify/package.json index 0d89f90a0..ec01228e1 100644 --- a/integrations/shopify/package.json +++ b/integrations/shopify/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/shopify", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev integration for @shopify/shopify-api", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -26,8 +26,8 @@ }, "dependencies": { "@shopify/shopify-api": "^8.0.2", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", "zod": "3.22.3" }, "engines": { diff --git a/integrations/slack/CHANGELOG.md b/integrations/slack/CHANGELOG.md index 2f7c4ec45..fa34d8c65 100644 --- a/integrations/slack/CHANGELOG.md +++ b/integrations/slack/CHANGELOG.md @@ -1,5 +1,11 @@ # @trigger.dev/slack +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/slack/package.json b/integrations/slack/package.json index 83a192278..de6cbf44c 100644 --- a/integrations/slack/package.json +++ b/integrations/slack/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/slack", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "The official Slack integration for Trigger.dev", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -25,7 +25,7 @@ }, "dependencies": { "@slack/web-api": "^6.8.1", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "zod": "3.22.3" }, "engines": { diff --git a/integrations/stripe/CHANGELOG.md b/integrations/stripe/CHANGELOG.md index 2150b53b9..e3fda8412 100644 --- a/integrations/stripe/CHANGELOG.md +++ b/integrations/stripe/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/stripe +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/stripe/package.json b/integrations/stripe/package.json index 41d121068..3af0573b4 100644 --- a/integrations/stripe/package.json +++ b/integrations/stripe/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/stripe", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev integration for stripe", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -25,8 +25,8 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "stripe": "^12.14.0", "zod": "3.22.3" }, diff --git a/integrations/supabase/CHANGELOG.md b/integrations/supabase/CHANGELOG.md index 536bb65b5..a9cbcc787 100644 --- a/integrations/supabase/CHANGELOG.md +++ b/integrations/supabase/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/supabase +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/supabase/package.json b/integrations/supabase/package.json index 4e4073984..3649b1e03 100644 --- a/integrations/supabase/package.json +++ b/integrations/supabase/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/supabase", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev integration for @supabase/supabase-js", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -26,8 +26,8 @@ }, "dependencies": { "@supabase/supabase-js": "^2.26.0", - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "supabase-management-js": "^1.0.0", "zod": "3.22.3" }, diff --git a/integrations/typeform/CHANGELOG.md b/integrations/typeform/CHANGELOG.md index 1030f36e6..6a00075c0 100644 --- a/integrations/typeform/CHANGELOG.md +++ b/integrations/typeform/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/typeform +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/integration-kit@3.0.0-beta.53 +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/integrations/typeform/package.json b/integrations/typeform/package.json index 6daffd91a..c7bfc2520 100644 --- a/integrations/typeform/package.json +++ b/integrations/typeform/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/typeform", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "The official Typeform integration for Trigger.dev", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -24,8 +24,8 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.52", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/integration-kit": "workspace:^3.0.0-beta.53", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "@typeform/api-client": "^1.8.0", "zod": "3.22.3" }, diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index 2de859366..8b1896dc9 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -1,5 +1,11 @@ # @trigger.dev/astro +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/astro/package.json b/packages/astro/package.json index 297881f17..596fdfc22 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,7 +1,7 @@ { "name": "@trigger.dev/astro", "description": "An Astro-native integration for Trigger.dev background jobs platform", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ @@ -20,7 +20,7 @@ "build:tsup": "tsup" }, "peerDependencies": { - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52" + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53" }, "devDependencies": { "astro": "^3.0.12", diff --git a/packages/cli-v3/CHANGELOG.md b/packages/cli-v3/CHANGELOG.md index 0e39f02e0..c956784e1 100644 --- a/packages/cli-v3/CHANGELOG.md +++ b/packages/cli-v3/CHANGELOG.md @@ -1,5 +1,18 @@ # trigger.dev +## 3.0.0-beta.53 + +### Patch Changes + +- 5cf90da72: Fix issues that could result in unreezable state run crashes. Details: + - Never checkpoint between attempts + - Some messages and socket data now include attempt numbers + - Remove attempt completion replays + - Additional prod entry point logging + - Fail runs that receive deprecated (pre-lazy attempt) execute messages +- Updated dependencies [5cf90da72] + - @trigger.dev/core@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/cli-v3/package.json b/packages/cli-v3/package.json index fbd7b30da..abdd96a96 100644 --- a/packages/cli-v3/package.json +++ b/packages/cli-v3/package.json @@ -1,6 +1,6 @@ { "name": "trigger.dev", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "A Command-Line Interface for Trigger.dev (v3) projects", "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -87,7 +87,7 @@ "@opentelemetry/sdk-trace-base": "^1.22.0", "@opentelemetry/sdk-trace-node": "^1.22.0", "@opentelemetry/semantic-conventions": "^1.22.0", - "@trigger.dev/core": "workspace:3.0.0-beta.52", + "@trigger.dev/core": "workspace:3.0.0-beta.53", "@types/degit": "^2.8.3", "chalk": "^5.2.0", "chokidar": "^3.5.3", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 7962779b1..0739f672b 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,13 @@ # create-trigger +## 3.0.0-beta.53 + +### Patch Changes + +- Updated dependencies [5cf90da72] + - @trigger.dev/core@3.0.0-beta.53 + - @trigger.dev/yalt@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 7c5635021..9c16717ff 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/cli", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "The Trigger.dev CLI", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/packages/core-apps/CHANGELOG.md b/packages/core-apps/CHANGELOG.md index 93c6f2a82..93a94414d 100644 --- a/packages/core-apps/CHANGELOG.md +++ b/packages/core-apps/CHANGELOG.md @@ -1,5 +1,16 @@ # @trigger.dev/core-apps +## 3.0.0-beta.53 + +### Patch Changes + +- 5cf90da72: Fix issues that could result in unreezable state run crashes. Details: + - Never checkpoint between attempts + - Some messages and socket data now include attempt numbers + - Remove attempt completion replays + - Additional prod entry point logging + - Fail runs that receive deprecated (pre-lazy attempt) execute messages + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/core-apps/package.json b/packages/core-apps/package.json index 9ba471f44..cac90d07b 100644 --- a/packages/core-apps/package.json +++ b/packages/core-apps/package.json @@ -1,7 +1,7 @@ { "name": "@trigger.dev/core-apps", "description": "Backend core code used across apps", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "private": true, "license": "MIT", "main": "./dist/index.js", diff --git a/packages/core-backend/CHANGELOG.md b/packages/core-backend/CHANGELOG.md index 37f4cc977..0d18f3b5b 100644 --- a/packages/core-backend/CHANGELOG.md +++ b/packages/core-backend/CHANGELOG.md @@ -1,5 +1,7 @@ # @trigger.dev/core-backend +## 3.0.0-beta.53 + ## 3.0.0-beta.52 ## 3.0.0-beta.51 diff --git a/packages/core-backend/package.json b/packages/core-backend/package.json index 16279414d..39ded63a8 100644 --- a/packages/core-backend/package.json +++ b/packages/core-backend/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/core-backend", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Core code used across `@trigger.dev/sdk` and Trigger.dev server", "license": "MIT", "main": "./dist/index.js", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index e8d048089..f37a123a8 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,16 @@ # internal-platform +## 3.0.0-beta.53 + +### Patch Changes + +- 5cf90da72: Fix issues that could result in unreezable state run crashes. Details: + - Never checkpoint between attempts + - Some messages and socket data now include attempt numbers + - Remove attempt completion replays + - Additional prod entry point logging + - Fail runs that receive deprecated (pre-lazy attempt) execute messages + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index bb5478d97..5dbe1df22 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/core", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Core code used across the Trigger.dev SDK and platform", "license": "MIT", "main": "./dist/index.js", diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index a785c763b..6c514ba10 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -1,5 +1,7 @@ # @trigger.dev/eslint-plugin +## 3.0.0-beta.53 + ## 3.0.0-beta.52 ## 3.0.0-beta.51 diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 553d40c1a..c731a08f7 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/eslint-plugin", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "ESLint plugin with trigger.dev best practices", "keywords": [ "eslint", diff --git a/packages/express/CHANGELOG.md b/packages/express/CHANGELOG.md index ff483a076..6b2d02969 100644 --- a/packages/express/CHANGELOG.md +++ b/packages/express/CHANGELOG.md @@ -1,5 +1,11 @@ # @trigger.dev/express +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/express/package.json b/packages/express/package.json index d96479840..a350db70b 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/express", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Official Express adapter for Trigger.dev", "license": "MIT", "main": "./dist/index.js", @@ -23,7 +23,7 @@ "./package.json": "./package.json" }, "devDependencies": { - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "@trigger.dev/tsconfig": "workspace:*", "@types/debug": "^4.1.7", "@types/express": "^4.17.13", @@ -39,7 +39,7 @@ "build:tsup": "tsup" }, "peerDependencies": { - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52" + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53" }, "dependencies": { "debug": "^4.3.4", diff --git a/packages/hono/CHANGELOG.md b/packages/hono/CHANGELOG.md index ada55b09a..852f9fa3b 100644 --- a/packages/hono/CHANGELOG.md +++ b/packages/hono/CHANGELOG.md @@ -1,5 +1,11 @@ # @trigger.dev/hono +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/hono/package.json b/packages/hono/package.json index 1db6189d1..465d899b9 100644 --- a/packages/hono/package.json +++ b/packages/hono/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/hono", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "A Trigger.dev adapter for Hono.dev", "license": "MIT", "main": "./dist/index.js", @@ -32,7 +32,7 @@ }, "peerDependencies": { "hono": "3.x", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52" + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53" }, "devDependencies": { "@trigger.dev/tsconfig": "workspace:*", diff --git a/packages/integration-kit/CHANGELOG.md b/packages/integration-kit/CHANGELOG.md index e52ba6ac3..218426b26 100644 --- a/packages/integration-kit/CHANGELOG.md +++ b/packages/integration-kit/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/integration-kit +## 3.0.0-beta.53 + +### Patch Changes + +- Updated dependencies [5cf90da72] + - @trigger.dev/core@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/integration-kit/package.json b/packages/integration-kit/package.json index 12c17c0c0..2b641c147 100644 --- a/packages/integration-kit/package.json +++ b/packages/integration-kit/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/integration-kit", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev Integration Kit has helpers to make creating integrations easier", "license": "MIT", "main": "./dist/index.js", diff --git a/packages/nestjs/CHANGELOG.md b/packages/nestjs/CHANGELOG.md index fd41d8f2e..b2f0ed2be 100644 --- a/packages/nestjs/CHANGELOG.md +++ b/packages/nestjs/CHANGELOG.md @@ -1,5 +1,11 @@ # @trigger.dev/nestjs +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index 11042046b..62f4a19ba 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/nestjs", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Official NestJS adapter for Trigger.dev", "license": "MIT", "main": "./dist/index.js", @@ -23,7 +23,7 @@ "./package.json": "./package.json" }, "devDependencies": { - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "@trigger.dev/tsconfig": "workspace:*", "@types/debug": "^4.1.7", "@types/express": "^4.17.13", @@ -41,7 +41,7 @@ }, "peerDependencies": { "@nestjs/common": ">=10.0.0", - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52" + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53" }, "dependencies": { "@nestjs/common": "^10.2.4", diff --git a/packages/nextjs/CHANGELOG.md b/packages/nextjs/CHANGELOG.md index 9b65e941e..574ee72b0 100644 --- a/packages/nextjs/CHANGELOG.md +++ b/packages/nextjs/CHANGELOG.md @@ -1,5 +1,11 @@ # @trigger.dev/nextjs +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index d069fd613..a20b75bd5 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/nextjs", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev Next.js integration", "license": "MIT", "main": "./dist/index.js", @@ -41,7 +41,7 @@ "build:tsup": "tsup" }, "peerDependencies": { - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "next": ">=12.0.0" }, "dependencies": { diff --git a/packages/otlp-importer/CHANGELOG.md b/packages/otlp-importer/CHANGELOG.md index e692dd628..ea6fe8920 100644 --- a/packages/otlp-importer/CHANGELOG.md +++ b/packages/otlp-importer/CHANGELOG.md @@ -1,5 +1,7 @@ # @trigger.dev/otlp-importer +## 3.0.0-beta.53 + ## 3.0.0-beta.52 ## 3.0.0-beta.51 diff --git a/packages/otlp-importer/package.json b/packages/otlp-importer/package.json index bbffb3c3b..e8f7873f0 100644 --- a/packages/otlp-importer/package.json +++ b/packages/otlp-importer/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/otlp-importer", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "OpenTelemetry OTLP Importer for Node.js written in TypeScript", "license": "MIT", "main": "./dist/index.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 7a1e28f28..c320684d7 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,12 @@ # @trigger.dev/react +## 3.0.0-beta.53 + +### Patch Changes + +- Updated dependencies [5cf90da72] + - @trigger.dev/core@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 156332295..dbb4e591f 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/react", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev React SDK", "license": "MIT", "types": "dist/index.d.ts", @@ -27,7 +27,7 @@ }, "dependencies": { "@tanstack/react-query": "5.0.0-beta.2", - "@trigger.dev/core": "workspace:^3.0.0-beta.52", + "@trigger.dev/core": "workspace:^3.0.0-beta.53", "debug": "^4.3.4", "zod": "3.22.3" }, diff --git a/packages/remix/CHANGELOG.md b/packages/remix/CHANGELOG.md index 656f1780d..7af5965c4 100644 --- a/packages/remix/CHANGELOG.md +++ b/packages/remix/CHANGELOG.md @@ -1,5 +1,11 @@ # @trigger.dev/remix +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/remix/package.json b/packages/remix/package.json index 17ab40fde..88bb7331d 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/remix", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev Remix integration", "license": "MIT", "main": "./dist/index.js", @@ -39,7 +39,7 @@ "build:tsup": "tsup" }, "peerDependencies": { - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52", + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53", "@remix-run/server-runtime": ">1.19.0" }, "dependencies": { diff --git a/packages/sveltekit/CHANGELOG.md b/packages/sveltekit/CHANGELOG.md index 476eba0e8..10debc683 100644 --- a/packages/sveltekit/CHANGELOG.md +++ b/packages/sveltekit/CHANGELOG.md @@ -1,5 +1,11 @@ # @trigger.dev/sveltekit +## 3.0.0-beta.53 + +### Patch Changes + +- @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index 5fffa2b4d..dbb755f69 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/sveltekit", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "Trigger.dev svelteKit integration", "license": "MIT", "main": "./dist/index.js", @@ -39,7 +39,7 @@ "build:tsup": "tsup" }, "peerDependencies": { - "@trigger.dev/sdk": "workspace:^3.0.0-beta.52" + "@trigger.dev/sdk": "workspace:^3.0.0-beta.53" }, "dependencies": { "debug": "^4.3.4" diff --git a/packages/testing/CHANGELOG.md b/packages/testing/CHANGELOG.md index 414dbe41d..1172f4168 100644 --- a/packages/testing/CHANGELOG.md +++ b/packages/testing/CHANGELOG.md @@ -1,5 +1,13 @@ # @trigger.dev/testing +## 3.0.0-beta.53 + +### Patch Changes + +- Updated dependencies [5cf90da72] + - @trigger.dev/core@3.0.0-beta.53 + - @trigger.dev/sdk@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/testing/package.json b/packages/testing/package.json index c26eb30cd..199d60480 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,7 +1,7 @@ { "name": "@trigger.dev/testing", "description": "A collection of useful tools to write tests for Trigger.dev.", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "license": "MIT", "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/packages/trigger-sdk/CHANGELOG.md b/packages/trigger-sdk/CHANGELOG.md index eb632a740..0af4b6d1b 100644 --- a/packages/trigger-sdk/CHANGELOG.md +++ b/packages/trigger-sdk/CHANGELOG.md @@ -1,5 +1,13 @@ # @trigger.dev/sdk +## 3.0.0-beta.53 + +### Patch Changes + +- Updated dependencies [5cf90da72] + - @trigger.dev/core@3.0.0-beta.53 + - @trigger.dev/core-backend@3.0.0-beta.53 + ## 3.0.0-beta.52 ### Patch Changes diff --git a/packages/trigger-sdk/package.json b/packages/trigger-sdk/package.json index 84842a6dc..7179a035e 100644 --- a/packages/trigger-sdk/package.json +++ b/packages/trigger-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/sdk", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "trigger.dev Node.JS SDK", "license": "MIT", "main": "./dist/index.js", @@ -48,8 +48,8 @@ "@opentelemetry/api": "^1.8.0", "@opentelemetry/api-logs": "^0.48.0", "@opentelemetry/semantic-conventions": "^1.22.0", - "@trigger.dev/core": "workspace:3.0.0-beta.52", - "@trigger.dev/core-backend": "workspace:3.0.0-beta.52", + "@trigger.dev/core": "workspace:3.0.0-beta.53", + "@trigger.dev/core-backend": "workspace:3.0.0-beta.53", "chalk": "^5.2.0", "cronstrue": "^2.21.0", "debug": "^4.3.4", diff --git a/packages/yalt/CHANGELOG.md b/packages/yalt/CHANGELOG.md index 861621102..08995cca1 100644 --- a/packages/yalt/CHANGELOG.md +++ b/packages/yalt/CHANGELOG.md @@ -1,5 +1,7 @@ # @trigger.dev/yalt +## 3.0.0-beta.53 + ## 3.0.0-beta.52 ## 3.0.0-beta.51 diff --git a/packages/yalt/package.json b/packages/yalt/package.json index 6d38ba003..b3451ddf6 100644 --- a/packages/yalt/package.json +++ b/packages/yalt/package.json @@ -1,6 +1,6 @@ { "name": "@trigger.dev/yalt", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "yalt.dev client library", "license": "MIT", "main": "./dist/index.js", From 95b3754685886bb9f2402a59504e20fc3354c78d Mon Sep 17 00:00:00 2001 From: nicktrn <55853254+nicktrn@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:40:38 +0100 Subject: [PATCH 18/33] Release 3.0.0-beta.53 --- pnpm-lock.yaml | 70 +++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31588c35b..3077e9901 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -887,10 +887,10 @@ importers: integrations/airtable: dependencies: '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk airtable: specifier: ^0.12.1 @@ -930,10 +930,10 @@ importers: specifier: ^12.0.10 version: 12.0.10 '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk octokit: specifier: ^3.1.2 @@ -973,10 +973,10 @@ importers: specifier: ^8.0.0 version: 8.0.0 '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk zod: specifier: 3.22.3 @@ -1004,10 +1004,10 @@ importers: integrations/openai: dependencies: '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk openai: specifier: ^4.16.1 @@ -1047,10 +1047,10 @@ importers: specifier: ^2.7.0 version: 2.7.0 '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk devDependencies: '@trigger.dev/tsconfig': @@ -1075,10 +1075,10 @@ importers: integrations/replicate: dependencies: '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk replicate: specifier: ^0.18.1 @@ -1109,10 +1109,10 @@ importers: integrations/resend: dependencies: '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk resend: specifier: ^2.1.0 @@ -1143,10 +1143,10 @@ importers: specifier: ^7.7.0 version: 7.7.0 '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk devDependencies: '@trigger.dev/tsconfig': @@ -1174,10 +1174,10 @@ importers: specifier: ^8.0.2 version: 8.0.2 '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk zod: specifier: 3.22.3 @@ -1208,7 +1208,7 @@ importers: specifier: ^6.8.1 version: 6.8.1 '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk zod: specifier: 3.22.3 @@ -1236,10 +1236,10 @@ importers: integrations/stripe: dependencies: '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk stripe: specifier: ^12.14.0 @@ -1273,10 +1273,10 @@ importers: specifier: ^2.26.0 version: 2.31.0 '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk supabase-management-js: specifier: ^1.0.0 @@ -1307,10 +1307,10 @@ importers: integrations/typeform: dependencies: '@trigger.dev/integration-kit': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/integration-kit '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../../packages/trigger-sdk '@typeform/api-client': specifier: ^1.8.0 @@ -1338,7 +1338,7 @@ importers: packages/astro: dependencies: '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../trigger-sdk debug: specifier: ^4.3.4 @@ -1556,7 +1556,7 @@ importers: specifier: ^1.22.0 version: 1.22.0 '@trigger.dev/core': - specifier: workspace:3.0.0-beta.52 + specifier: workspace:3.0.0-beta.53 version: link:../core '@types/degit': specifier: ^2.8.3 @@ -1981,7 +1981,7 @@ importers: version: 4.18.2 devDependencies: '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../trigger-sdk '@trigger.dev/tsconfig': specifier: workspace:* @@ -2076,7 +2076,7 @@ importers: version: 4.3.4(supports-color@8.1.1) devDependencies: '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../trigger-sdk '@trigger.dev/tsconfig': specifier: workspace:* @@ -2109,7 +2109,7 @@ importers: packages/nextjs: dependencies: '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../trigger-sdk debug: specifier: ^4.3.4 @@ -2195,7 +2195,7 @@ importers: specifier: 5.0.0-beta.2 version: 5.0.0-beta.2(react@18.2.0) '@trigger.dev/core': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../core debug: specifier: ^4.3.4 @@ -2238,7 +2238,7 @@ importers: packages/remix: dependencies: '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../trigger-sdk debug: specifier: ^4.3.4 @@ -2275,7 +2275,7 @@ importers: packages/sveltekit: dependencies: '@trigger.dev/sdk': - specifier: workspace:^3.0.0-beta.52 + specifier: workspace:^3.0.0-beta.53 version: link:../trigger-sdk debug: specifier: ^4.3.4 @@ -2349,10 +2349,10 @@ importers: specifier: ^1.22.0 version: 1.22.0 '@trigger.dev/core': - specifier: workspace:3.0.0-beta.52 + specifier: workspace:3.0.0-beta.53 version: link:../core '@trigger.dev/core-backend': - specifier: workspace:3.0.0-beta.52 + specifier: workspace:3.0.0-beta.53 version: link:../core-backend chalk: specifier: ^5.2.0 From fa24ae69a69c581ac3584bbf3253ca8b1fd5d537 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Wed, 14 Aug 2024 13:25:06 +0100 Subject: [PATCH 19/33] Added a note to use batchTrigger() instead of trigger() --- docs/triggering.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/triggering.mdx b/docs/triggering.mdx index b43a74ac9..8b9830deb 100644 --- a/docs/triggering.mdx +++ b/docs/triggering.mdx @@ -36,6 +36,8 @@ Triggers a single run of a task with the payload you pass in, and any options yo If called from within a task, you can use the `AndWait` version to pause execution until the triggered run is complete. +If you need to call `trigger()` on a task in a loop, use [`batchTrigger()`](/triggering#task-batchtrigger) instead which will trigger up to 100 tasks in a single call. + ```ts Next.js API route From d3810fc5bc2d1f1d601c816273bf101b40eff2b6 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Thu, 15 Aug 2024 10:34:31 +0100 Subject: [PATCH 20/33] The latest react-window-splitter fixes the ESM issues --- apps/webapp/package.json | 2 +- apps/webapp/remix.config.js | 2 -- pnpm-lock.yaml | 48 ++++++++++++++++--------------------- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/apps/webapp/package.json b/apps/webapp/package.json index d83e27f9d..52b5e74dd 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -152,7 +152,7 @@ "react-resizable-panels": "^2.0.9", "react-stately": "^3.29.1", "react-use": "^17.4.0", - "react-window-splitter": "^0.2.0", + "react-window-splitter": "^0.2.3", "recharts": "^2.12.6", "regression": "^2.0.1", "remix-auth": "^3.6.0", diff --git a/apps/webapp/remix.config.js b/apps/webapp/remix.config.js index 0cd01caec..ee2aee289 100644 --- a/apps/webapp/remix.config.js +++ b/apps/webapp/remix.config.js @@ -22,8 +22,6 @@ module.exports = { "superjson", "prismjs/components/prism-json", "prismjs/components/prism-typescript", - "react-window-splitter", - "d3-ease", ], browserNodeBuiltinsPolyfill: { modules: { path: true, os: true, crypto: true } }, watchPaths: async () => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3077e9901..1e88a283c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -562,8 +562,8 @@ importers: specifier: ^17.4.0 version: 17.4.0(react-dom@18.2.0)(react@18.2.0) react-window-splitter: - specifier: ^0.2.0 - version: 0.2.0(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0) + specifier: ^0.2.3 + version: 0.2.3(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0) recharts: specifier: ^2.12.6 version: 2.12.6(react-dom@18.2.0)(react@18.2.0) @@ -18736,6 +18736,17 @@ packages: tslib: 2.6.2 dev: false + /@window-splitter/state@0.2.3: + resolution: {integrity: sha512-jruhVNrGjTc/z/ETdR2pX8owD7VHiDigZ+vnUPtS4toOxSKgm/ga9QDc+Rcwie5HV+7/rLApZ1xl9pQpgImbWg==} + engines: {node: '>=18.0.0'} + dependencies: + '@react-spring/rafz': 9.7.4 + '@types/invariant': 2.2.37 + big.js: 6.2.1 + invariant: 2.2.4 + xstate: 5.17.1 + dev: false + /@xmldom/xmldom@0.8.6: resolution: {integrity: sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg==} engines: {node: '>=10.0.0'} @@ -19824,6 +19835,10 @@ packages: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} dev: true + /big.js@6.2.1: + resolution: {integrity: sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==} + dev: false + /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} @@ -24859,25 +24874,6 @@ packages: '@emotion/is-prop-valid': 0.8.8 dev: false - /framer-motion@11.3.24(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-kl0YI7HwAtyV0VOAWuU/rXoOS8+z5qSkMN6rZS+a9oe6fIha6SC3vjJN6u/hBpvjrg5MQNdSnqnjYxm0WYTX9g==} - peerDependencies: - '@emotion/is-prop-valid': '*' - react: ^18.0.0 - react-dom: ^18.0.0 - peerDependenciesMeta: - '@emotion/is-prop-valid': - optional: true - react: - optional: true - react-dom: - optional: true - dependencies: - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - tslib: 2.6.2 - dev: false - /fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -32730,19 +32726,16 @@ packages: tslib: 2.5.0 dev: false - /react-window-splitter@0.2.0(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-A7KD0osBfh18uNij87bHbqG6L8SHJ2S9IAbIny1T6vW87FnTg29gS/YRRQtcR8Gu9gxCEO67uqAjLOpMESYW+g==} + /react-window-splitter@0.2.3(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aWGd6ROi9+xAFgqhVCEeAuDWh6jPidghQmv25lc/67FlFMLpi/NB+NaZEeSANFQV8kLxMokUfN/vfz+uuz/fAA==} engines: {node: '>=18.0.0'} peerDependencies: react: '>=16' react-dom: '>=16' dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.69)(react@18.2.0) - '@react-spring/rafz': 9.7.4 - '@types/invariant': 2.2.37 + '@window-splitter/state': 0.2.3 '@xstate/react': 4.1.1(@types/react@18.2.69)(react@18.2.0)(xstate@5.17.1) - d3-ease: 3.0.1 - framer-motion: 11.3.24(react-dom@18.2.0)(react@18.2.0) invariant: 2.2.4 react: 18.2.0 react-aria: 3.34.1(react-dom@18.2.0)(react@18.2.0) @@ -32751,7 +32744,6 @@ packages: universal-cookie: 7.2.0 xstate: 5.17.1 transitivePeerDependencies: - - '@emotion/is-prop-valid' - '@types/react' - immer dev: false From 194c56aa621bd6db990851f99785659642fc2ad8 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Thu, 15 Aug 2024 10:34:39 +0100 Subject: [PATCH 21/33] Set sensible defaults for the run page --- .../route.tsx | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx index 9b52b63b5..71d91afa5 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx @@ -10,8 +10,8 @@ import { StopCircleIcon, } from "@heroicons/react/20/solid"; import type { Location } from "@remix-run/react"; -import { useLoaderData, useParams, useRevalidator } from "@remix-run/react"; -import { LoaderFunctionArgs, SerializeFrom, json } from "@remix-run/server-runtime"; +import { useParams, useRevalidator } from "@remix-run/react"; +import { LoaderFunctionArgs } from "@remix-run/server-runtime"; import { Virtualizer } from "@tanstack/react-virtual"; import { formatDurationMilliseconds, @@ -22,6 +22,7 @@ import { RuntimeEnvironmentType } from "@trigger.dev/database"; import { motion } from "framer-motion"; import { useCallback, useEffect, useRef, useState } from "react"; import { useHotkeys } from "react-hotkeys-hook"; +import { UseDataFunctionReturn, typedjson, useTypedLoaderData } from "remix-typedjson"; import { ShowParentIcon, ShowParentIconSelected } from "~/assets/icons/ShowParentIcon"; import tileBgPath from "~/assets/images/error-banner-tile@2x.png"; import { AdminDebugTooltip } from "~/components/admin/debugTooltip"; @@ -66,6 +67,8 @@ import { useReplaceLocation } from "~/hooks/useReplaceLocation"; import { Shortcut, useShortcutKeys } from "~/hooks/useShortcutKeys"; import { useUser } from "~/hooks/useUser"; import { RunPresenter } from "~/presenters/v3/RunPresenter.server"; +import { logger } from "~/services/logger.server"; +import { getResizableSnapshot } from "~/services/resizablePanel.server"; import { requireUserId } from "~/services/session.server"; import { cn } from "~/utils/cn"; import { lerp } from "~/utils/lerp"; @@ -77,11 +80,8 @@ import { v3RunStreamingPath, v3RunsPath, } from "~/utils/pathBuilder"; -import { SpanView } from "../resources.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam.spans.$spanParam/route"; import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route"; -import { getResizableSnapshot } from "~/services/resizablePanel.server"; -import { logger } from "~/services/logger.server"; -import { typedjson, UseDataFunctionReturn, useTypedLoaderData } from "remix-typedjson"; +import { SpanView } from "../resources.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam.spans.$spanParam/route"; type TraceEvent = NonNullable["trace"]>["events"][0]; @@ -95,7 +95,8 @@ const resizableSettings = { }, inspector: { id: "inspector", - default: "300px" as const, + default: "430px" as const, + min: "50px" as const, }, }, tree: { @@ -103,11 +104,13 @@ const resizableSettings = { handleId: "tree-handle", tree: { id: "tree", - default: "20%" as const, + default: "50%" as const, + min: "50px" as const, }, timeline: { id: "timeline", - default: "80%" as const, + default: "50%" as const, + min: "50px" as const, }, }, }; @@ -328,6 +331,7 @@ function TraceView({ run, trace, maximumLiveReloadingSetting, resizable }: Loade @@ -512,6 +517,7 @@ function TasksTreeView({
@@ -624,6 +630,7 @@ function TasksTreeView({ Date: Thu, 15 Aug 2024 10:56:46 +0100 Subject: [PATCH 22/33] Deployments page --- .../route.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.deployments/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.deployments/route.tsx index 0ec72c574..deed5f50a 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.deployments/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.deployments/route.tsx @@ -104,8 +104,8 @@ export default function Page() { - - + + {hasDeployments ? (
@@ -211,8 +211,8 @@ export default function Page() { {deploymentParam && ( <> - - + + From c3298f974f47f0d1431c4fbe21bffeef54366a8a Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Thu, 15 Aug 2024 11:11:08 +0100 Subject: [PATCH 23/33] Test page --- .../route.tsx | 16 ++++++++-------- .../route.tsx | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.test.tasks.$taskParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.test.tasks.$taskParam/route.tsx index 76cf92ecc..f8fbde5bd 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.test.tasks.$taskParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.test.tasks.$taskParam/route.tsx @@ -180,8 +180,8 @@ function StandardTaskForm({ task, runs }: { task: TestTask["task"]; runs: Standa onSubmit={(e) => submitForm(e)} > - - + +
- - + + - - + +
@@ -402,8 +402,8 @@ function ScheduledTaskForm({
- - + +
- - + +
@@ -135,8 +135,8 @@ export default function Page() { )}
- - + + From 4027045f32be7d00df0dd5097922b1bd08ff80a3 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Thu, 15 Aug 2024 11:11:11 +0100 Subject: [PATCH 24/33] Schedules page --- .../route.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.schedules/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.schedules/route.tsx index 53b4f31ec..70941ef5b 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.schedules/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.schedules/route.tsx @@ -177,8 +177,8 @@ export default function Page() { - - + +
{possibleTasks.length === 0 ? ( @@ -250,8 +250,8 @@ export default function Page() { {(isShowingNewPane || isShowingSchedule) && ( <> - - + + From 2416f426b897c3ef7fe8450a96d71f327fdeabae Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Sun, 18 Aug 2024 12:46:24 +0100 Subject: [PATCH 25/33] Latest version of react-window-splitter (0.2.5) --- apps/webapp/package.json | 2 +- pnpm-lock.yaml | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/apps/webapp/package.json b/apps/webapp/package.json index 52b5e74dd..39dfa68af 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -152,7 +152,7 @@ "react-resizable-panels": "^2.0.9", "react-stately": "^3.29.1", "react-use": "^17.4.0", - "react-window-splitter": "^0.2.3", + "react-window-splitter": "^0.2.5", "recharts": "^2.12.6", "regression": "^2.0.1", "remix-auth": "^3.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1e88a283c..6b3fa97a6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -562,8 +562,8 @@ importers: specifier: ^17.4.0 version: 17.4.0(react-dom@18.2.0)(react@18.2.0) react-window-splitter: - specifier: ^0.2.3 - version: 0.2.3(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0) + specifier: ^0.2.5 + version: 0.2.5(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0) recharts: specifier: ^2.12.6 version: 2.12.6(react-dom@18.2.0)(react@18.2.0) @@ -18736,15 +18736,15 @@ packages: tslib: 2.6.2 dev: false - /@window-splitter/state@0.2.3: - resolution: {integrity: sha512-jruhVNrGjTc/z/ETdR2pX8owD7VHiDigZ+vnUPtS4toOxSKgm/ga9QDc+Rcwie5HV+7/rLApZ1xl9pQpgImbWg==} + /@window-splitter/state@0.2.5: + resolution: {integrity: sha512-Dm9AIzbeqUTo/s6pqLHPrJSHgVBok2zUWsF7VBftpgH6nJ8H5PTOohLmyPNuBftblQ07PIB+itpnrYfEAINy6w==} engines: {node: '>=18.0.0'} dependencies: '@react-spring/rafz': 9.7.4 '@types/invariant': 2.2.37 big.js: 6.2.1 invariant: 2.2.4 - xstate: 5.17.1 + xstate: 5.17.4 dev: false /@xmldom/xmldom@0.8.6: @@ -18756,7 +18756,7 @@ packages: resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} dev: false - /@xstate/react@4.1.1(@types/react@18.2.69)(react@18.2.0)(xstate@5.17.1): + /@xstate/react@4.1.1(@types/react@18.2.69)(react@18.2.0)(xstate@5.17.4): resolution: {integrity: sha512-pFp/Y+bnczfaZ0V8B4LOhx3d6Gd71YKAPbzerGqydC2nsYN/mp7RZu3q/w6/kvI2hwR/jeDeetM7xc3JFZH2NA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -18768,7 +18768,7 @@ packages: react: 18.2.0 use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.69)(react@18.2.0) use-sync-external-store: 1.2.2(react@18.2.0) - xstate: 5.17.1 + xstate: 5.17.4 transitivePeerDependencies: - '@types/react' dev: false @@ -32726,23 +32726,23 @@ packages: tslib: 2.5.0 dev: false - /react-window-splitter@0.2.3(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-aWGd6ROi9+xAFgqhVCEeAuDWh6jPidghQmv25lc/67FlFMLpi/NB+NaZEeSANFQV8kLxMokUfN/vfz+uuz/fAA==} + /react-window-splitter@0.2.5(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-rTSJpoBsdJ9ovb2Kcp0YOMPr+JIT3v6mZ7vK3SiWvEQ/EGPjLrRgRNSe/8dhGMYn0capvy3Vf1U32yP1G8OW/A==} engines: {node: '>=18.0.0'} peerDependencies: react: '>=16' react-dom: '>=16' dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.69)(react@18.2.0) - '@window-splitter/state': 0.2.3 - '@xstate/react': 4.1.1(@types/react@18.2.69)(react@18.2.0)(xstate@5.17.1) + '@window-splitter/state': 0.2.5 + '@xstate/react': 4.1.1(@types/react@18.2.69)(react@18.2.0)(xstate@5.17.4) invariant: 2.2.4 react: 18.2.0 react-aria: 3.34.1(react-dom@18.2.0)(react@18.2.0) react-dom: 18.2.0(react@18.2.0) reforest: 0.13.0(@types/react@18.2.69)(react@18.2.0) universal-cookie: 7.2.0 - xstate: 5.17.1 + xstate: 5.17.4 transitivePeerDependencies: - '@types/react' - immer @@ -38516,8 +38516,8 @@ packages: engines: {node: '>=0.4.0'} dev: false - /xstate@5.17.1: - resolution: {integrity: sha512-RNwcXdth+kboWZg+Zhf6f6iNP6CtAAiS4z4qwyTd/fWBH9PHXRqko6OdW3xOTwP62f0mVD+jsPOSqY4Ar8nZKQ==} + /xstate@5.17.4: + resolution: {integrity: sha512-KM2FYVOUJ04HlOO4TY3wEXqoYPR/XsDu+ewm+IWw0vilXqND0jVfvv04tEFwp8Mkk7I/oHXM8t1Ex9xJyUS4ZA==} dev: false /xtend@4.0.2: From d36f07b79c21e3709d63f3456ffd58daa55eaf2f Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Fri, 23 Aug 2024 16:18:49 +0100 Subject: [PATCH 26/33] Updated to the latest version: react-window-splitter --- apps/webapp/package.json | 2 +- pnpm-lock.yaml | 1447 +++++++++++++++++++++++++++++++++++++- 2 files changed, 1445 insertions(+), 4 deletions(-) diff --git a/apps/webapp/package.json b/apps/webapp/package.json index 647a00ba8..f39548f30 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -151,7 +151,7 @@ "react-resizable-panels": "^2.0.9", "react-stately": "^3.29.1", "react-use": "^17.4.0", - "react-window-splitter": "^0.2.5", + "react-window-splitter": "^0.4.0", "recharts": "^2.12.6", "regression": "^2.0.1", "remix-auth": "^3.6.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b20b0fee7..b53ecfb04 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -414,6 +414,9 @@ importers: compression: specifier: ^1.7.4 version: 1.7.4 + cookie: + specifier: ^0.6.0 + version: 0.6.0 cron-parser: specifier: ^4.9.0 version: 4.9.0 @@ -543,6 +546,9 @@ importers: react-use: specifier: ^17.4.0 version: 17.4.0(react-dom@18.2.0)(react@18.2.0) + react-window-splitter: + specifier: ^0.4.0 + version: 0.4.0(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0) recharts: specifier: ^2.12.6 version: 2.12.6(react-dom@18.2.0)(react@18.2.0) @@ -658,6 +664,9 @@ importers: '@types/compression': specifier: ^1.7.2 version: 1.7.2 + '@types/cookie': + specifier: ^0.6.0 + version: 0.6.0 '@types/eslint': specifier: ^8.4.6 version: 8.4.10 @@ -1462,6 +1471,10 @@ packages: resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} engines: {node: '>=0.10.0'} + /@adobe/css-tools@4.4.0: + resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==} + dev: false + /@alloc/quick-lru@5.2.0: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} @@ -6331,6 +6344,12 @@ packages: '@swc/helpers': 0.5.2 dev: false + /@internationalized/date@3.5.5: + resolution: {integrity: sha512-H+CfYvOZ0LTJeeLOqm19E3uj/4YjrmOFtBufDHPfvtI80hFAMqtrp7oCACpe4Cil5l8S0Qu/9dYfZc/5lY8WQQ==} + dependencies: + '@swc/helpers': 0.5.2 + dev: false + /@internationalized/message@3.1.1: resolution: {integrity: sha512-ZgHxf5HAPIaR0th+w0RUD62yF6vxitjlprSxmLJ1tam7FOekqRSDELMg4Cr/DdszG5YLsp5BG3FgHgqquQZbqw==} dependencies: @@ -6338,18 +6357,37 @@ packages: intl-messageformat: 10.5.8 dev: false + /@internationalized/message@3.1.4: + resolution: {integrity: sha512-Dygi9hH1s7V9nha07pggCkvmRfDd3q2lWnMGvrJyrOwYMe1yj4D2T9BoH9I6MGR7xz0biQrtLPsqUkqXzIrBOw==} + dependencies: + '@swc/helpers': 0.5.2 + intl-messageformat: 10.5.8 + dev: false + /@internationalized/number@3.5.0: resolution: {integrity: sha512-ZY1BW8HT9WKYvaubbuqXbbDdHhOUMfE2zHHFJeTppid0S+pc8HtdIxFxaYMsGjCb4UsF+MEJ4n2TfU7iHnUK8w==} dependencies: '@swc/helpers': 0.5.2 dev: false + /@internationalized/number@3.5.3: + resolution: {integrity: sha512-rd1wA3ebzlp0Mehj5YTuTI50AQEx80gWFyHcQu+u91/5NgdwBecO8BH6ipPfE+lmQ9d63vpB3H9SHoIUiupllw==} + dependencies: + '@swc/helpers': 0.5.2 + dev: false + /@internationalized/string@3.2.0: resolution: {integrity: sha512-Xx3Sy3f2c9ctT+vh8c7euEaEHQZltp0euZ3Hy4UfT3E13r6lxpUS3kgKyumEjboJZSnaZv7JhqWz3D75v+IxQg==} dependencies: '@swc/helpers': 0.5.2 dev: false + /@internationalized/string@3.2.3: + resolution: {integrity: sha512-9kpfLoA8HegiWTeCbR2livhdVeKobCnVv8tlJ6M2jF+4tcMqDo94ezwlnrUANBWPgd8U7OXIHCk2Ov2qhk4KXw==} + dependencies: + '@swc/helpers': 0.5.2 + dev: false + /@ioredis/commands@1.2.0: resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} dev: false @@ -8112,6 +8150,19 @@ packages: react: 18.2.0 dev: false + /@radix-ui/react-compose-refs@1.1.0(@types/react@18.2.69)(react@18.2.0): + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.69 + react: 18.2.0 + dev: false + /@radix-ui/react-context@1.0.0(react@18.2.0): resolution: {integrity: sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==} peerDependencies: @@ -9472,6 +9523,20 @@ packages: '@babel/runtime': 7.24.5 dev: false + /@react-aria/breadcrumbs@3.5.16(react@18.2.0): + resolution: {integrity: sha512-OXLKKu4SmjnSaSHkk4kow5/aH/SzlHWPJt+Uq3xec9TwDOr/Ob8aeFVGFoY0HxfGozuQlUz+4e+d29vfA0jNWg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/link': 3.7.4(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/breadcrumbs': 3.7.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/breadcrumbs@3.5.9(react@18.2.0): resolution: {integrity: sha512-asbXTL5NjeHl1+YIF0K70y8tNHk8Lb6VneYH8yOkpLO49ejyNDYBK0tp0jtI9IZAQiTa2qkhYq58c9LloTwebQ==} peerDependencies: @@ -9501,6 +9566,41 @@ packages: react: 18.2.0 dev: false + /@react-aria/button@3.9.8(react@18.2.0): + resolution: {integrity: sha512-MdbMQ3t5KSCkvKtwYd/Z6sgw0v+r1VQFRYOZ4L53xOkn+u140z8vBpNeWKZh/45gxGv7SJn9s2KstLPdCWmIxw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/toggle': 3.7.7(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-aria/calendar@3.5.11(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-VLhBovLVu3uJXBkHbgEippmo/K58QLcc/tSJQ0aJUNyHsrvPgHEcj484cb+Uj/yOirXEIzaoW6WEvhcdKrb49Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/calendar': 3.5.4(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/calendar': 3.4.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/calendar@3.5.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-8k7khgea5kwfWriZJWCADNB0R2d7g5A6tTjUEktK4FFZcTb0RCubFejts4hRyzKlF9XHUro2dfh6sbZrzfMKDQ==} peerDependencies: @@ -9539,6 +9639,50 @@ packages: react: 18.2.0 dev: false + /@react-aria/checkbox@3.14.6(react@18.2.0): + resolution: {integrity: sha512-LICY1PR3WsW/VbuLMjZbxo75+poeo3XCXGcUnk6hxMlWfp/Iy/XHVsHlGu9stRPKRF8BSuOGteaHWVn6IXfwtA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/toggle': 3.10.7(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/checkbox': 3.6.8(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/toggle': 3.7.7(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-aria/combobox@3.10.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-EdDwr2Rp1xy7yWjOYHt2qF1IpAtUrkaNKZJzlIw1XSwcqizQY6E8orNPdZr6ZwD6/tgujxF1N71JTKyffrR0Xw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/listbox': 3.13.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/menu': 3.15.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/overlays': 3.23.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/textfield': 3.14.8(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/combobox': 3.9.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/combobox': 3.12.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/combobox@3.8.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-q8Kdw1mx6nSSydXqRagRuyKH1NPGvpSOFjUfgxdO8ZqaEEuZX3ObOoiO/DLtXDndViNc03dMbMpfuJoLYXfCtg==} peerDependencies: @@ -9564,6 +9708,34 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/datepicker@3.11.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-6sbLln3VXSBcBRDgSACBzIzF/5KV5NlNOhZvXPFE6KqFw6GbevjZQTv5BNDXiwA3CQoawIRF7zgRvTANw8HkNA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@internationalized/number': 3.5.3 + '@internationalized/string': 3.2.3 + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/spinbutton': 3.6.8(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/datepicker': 3.10.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/calendar': 3.4.9(react@18.2.0) + '@react-types/datepicker': 3.8.2(react@18.2.0) + '@react-types/dialog': 3.5.12(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/datepicker@3.9.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-bdlY2H/zwe3hQf64Lp1oGTf7Va8ennDyAv4Ffowb+BOoL8+FB9smtGyONKe87zXu7VJL2M5xYAi4n7c004PM+w==} peerDependencies: @@ -9608,6 +9780,22 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/dialog@3.5.17(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-lvfEgaqg922J1hurscqCS600OZQVitGtdpo81kAefJaUzMnCxzrYviyT96aaW0simHOlimbYF5js8lxBLZJRaw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/overlays': 3.23.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/dialog': 3.5.12(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/dnd@3.5.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-7OPGePdle+xNYHAIAUOvIETRMfnkRt7h/C0bCkxUR2GYefEbTzfraso4ppNH2JZ7fCRd0K/Qe+jvQklwusHAKA==} peerDependencies: @@ -9628,6 +9816,26 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/dnd@3.7.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-NuE3EGqoBbe9aXAO9mDfbu4kMO7S4MCgkjkCqYi16TWfRUf38ajQbIlqodCx91b3LVN3SYvNbE3D4Tj5ebkljw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/string': 3.2.3 + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/overlays': 3.23.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/dnd': 3.4.2(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/focus@3.16.0(react@18.2.0): resolution: {integrity: sha512-GP6EYI07E8NKQQcXHjpIocEU0vh0oi0Vcsd+/71fKS0NnTR0TUOEeil0JuuQ9ymkmPDTu51Aaaa4FxVsuN/23A==} peerDependencies: @@ -9641,6 +9849,19 @@ packages: react: 18.2.0 dev: false + /@react-aria/focus@3.18.2(react@18.2.0): + resolution: {integrity: sha512-Jc/IY+StjA3uqN73o6txKQ527RFU7gnG5crEl5Xy3V+gbYp2O5L3ezAo/E0Ipi2cyMbG6T5Iit1IDs7hcGu8aw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + clsx: 2.1.0 + react: 18.2.0 + dev: false + /@react-aria/form@3.0.1(react@18.2.0): resolution: {integrity: sha512-6586oODMDR4/ciGRwXjpvEAg7tWGSDrXE//waK0n5e5sMuzlPOo1DHc5SpPTvz0XdJsu6VDt2rHdVWVIC9LEyw==} peerDependencies: @@ -9654,6 +9875,42 @@ packages: react: 18.2.0 dev: false + /@react-aria/form@3.0.8(react@18.2.0): + resolution: {integrity: sha512-8S2QiyUdAgK43M3flohI0R+2rTyzH088EmgeRArA8euvJTL16cj/oSOKMEgWVihjotJ9n6awPb43ZhKboyNsMg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-aria/grid@3.10.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-l0r9mz05Gwjq3t6JOTNQOf+oAoWN0bXELPJtIr8m0XyXMPFCQe1xsTaX8igVQdrDmXyBc75RAWS0BJo2JF2fIA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/grid': 3.9.2(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/grid@3.8.6(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-JlQDkdm5heG1FfRyy5KnB8b6s/hRqSI6Xt2xN2AccLX5kcbfFr2/d5KVxyf6ahfa4Gfd46alN6477ju5eTWJew==} peerDependencies: @@ -9697,6 +9954,27 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/gridlist@3.9.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-bb9GnKKeuL6NljoVUcHxr9F0cy/2WDOXRYeMikTnviRw6cuX95oojrhFfCUvz2d6ID22Btrvh7LkE+oIPVuc+g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/grid': 3.10.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-stately/tree': 3.8.4(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/i18n@3.10.0(react@18.2.0): resolution: {integrity: sha512-sviD5Y1pLPG49HHRmVjR+5nONrp0HK219+nu9Y7cDfUhXu2EjyhMS9t/n9/VZ69hHChZ2PnHYLEE2visu9CuCg==} peerDependencies: @@ -9713,6 +9991,22 @@ packages: react: 18.2.0 dev: false + /@react-aria/i18n@3.12.2(react@18.2.0): + resolution: {integrity: sha512-PvEyC6JWylTpe8dQEWqQwV6GiA+pbTxHQd//BxtMSapRW3JT9obObAnb/nFhj3HthkUvqHyj0oO1bfeN+mtD8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@internationalized/message': 3.1.4 + '@internationalized/number': 3.5.3 + '@internationalized/string': 3.2.3 + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/interactions@3.20.1(react@18.2.0): resolution: {integrity: sha512-PLNBr87+SzRhe9PvvF9qvzYeP4ofTwfKSorwmO+hjr3qoczrSXf4LRQlb27wB6hF10C7ZE/XVbUI1lj4QQrZ/g==} peerDependencies: @@ -9725,6 +10019,29 @@ packages: react: 18.2.0 dev: false + /@react-aria/interactions@3.22.2(react@18.2.0): + resolution: {integrity: sha512-xE/77fRVSlqHp2sfkrMeNLrqf2amF/RyuAS6T5oDJemRSgYM3UoxTbWjucPhfnoW7r32pFPHHgz4lbdX8xqD/g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-aria/label@3.7.11(react@18.2.0): + resolution: {integrity: sha512-REgejE5Qr8cXG/b8H2GhzQmjQlII/0xQW/4eDzydskaTLvA7lF5HoJUE6biYTquH5va38d8XlH465RPk+bvHzA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/label@3.7.4(react@18.2.0): resolution: {integrity: sha512-3Y0yyrqpLzZdzHw+TOyzwuyx5wa2ujU5DGfKuL5GFnU9Ii4DtdwBGSYS7Yu7qadU+eQmG4OGhAgFVswbIgIwJw==} peerDependencies: @@ -9750,6 +10067,20 @@ packages: react: 18.2.0 dev: false + /@react-aria/link@3.7.4(react@18.2.0): + resolution: {integrity: sha512-E8SLDuS9ssm/d42+3sDFNthfMcNXMUrT2Tq1DIZt22EsMcuEzmJ9B0P7bDP5RgvIw05xVGqZ20nOpU4mKTxQtA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/link': 3.5.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/listbox@3.11.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-PBrnldmyEYUUJvfDeljW8ITvZyBTfGpLNf0b5kfBPK3TDgRH4niEH2vYEcaZvSqb0FrpdvcunuTRXcOpfb+gCQ==} peerDependencies: @@ -9769,12 +10100,37 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/listbox@3.13.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-htluPyDfFtn66OEYaJdIaFCYH9wGCNk30vOgZrQkPul9F9Cjce52tTyPVR0ERsf14oCUsjjS5qgeq3dGidRqEw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-types/listbox': 3.5.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/live-announcer@3.3.1: resolution: {integrity: sha512-hsc77U7S16trM86d+peqJCOCQ7/smO1cybgdpOuzXyiwcHQw8RQ4GrXrS37P4Ux/44E9nMZkOwATQRT2aK8+Ew==} dependencies: '@swc/helpers': 0.5.2 dev: false + /@react-aria/live-announcer@3.3.4: + resolution: {integrity: sha512-w8lxs35QrRrn6pBNzVfyGOeqWdxeVKf9U6bXIVwhq7rrTqRULL8jqy8RJIMfIs1s8G5FpwWYjyBOjl2g5Cu1iA==} + dependencies: + '@swc/helpers': 0.5.2 + dev: false + /@react-aria/menu@3.12.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Nsujv3b61WR0gybDKnBjAeyxDVJOfPLMggRUf9SQDfPWnrPXEsAFxaPaVcAkzlfI4HiQs1IxNwsKFNpc3PPZTQ==} peerDependencies: @@ -9798,6 +10154,41 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/menu@3.15.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-vvUmVjJwIg3h2r+7isQXTwlmoDlPAFBckHkg94p3afrT1kNOTHveTsaVl17mStx/ymIioaAi3PrIXk/PZXp1jw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/overlays': 3.23.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/menu': 3.8.2(react@18.2.0) + '@react-stately/tree': 3.8.4(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/menu': 3.9.11(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@react-aria/meter@3.4.16(react@18.2.0): + resolution: {integrity: sha512-hJqKnEE6mmK2Psx5kcI7NZ44OfTg0Bp7DatQSQ4zZE4yhnykRRwxqSKjze37tPR63cCqgRXtQ5LISfBfG54c0Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/progress': 3.4.16(react@18.2.0) + '@react-types/meter': 3.4.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/meter@3.4.9(react@18.2.0): resolution: {integrity: sha512-1/FHFmFmSyfQBJ2oH152lp4nps76v1UdhnFbIsmRIH+0g0IfMv1yDT2M9dIZ/b9DgVZSx527FmWOXm0eHGKD6w==} peerDependencies: @@ -9831,6 +10222,27 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/numberfield@3.11.6(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-nvEWiQcWRwj6O2JXmkXEeWoBX/GVZT9zumFJcew3XknGTWJUr3h2AOymIQFt9g4mpag8IgOFEpSIlwhtZHdp1A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/spinbutton': 3.6.8(react-dom@18.2.0)(react@18.2.0) + '@react-aria/textfield': 3.14.8(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/numberfield': 3.9.6(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/numberfield': 3.8.5(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/overlays@3.20.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-2m7MpRJL5UucbEuu08lMHsiFJoDowkJV4JAIFBZYK1NzVH0vF/A+w9HRNM7jRwx2DUxE+iIsZnl8yKV/7KY8OQ==} peerDependencies: @@ -9852,6 +10264,41 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/overlays@3.23.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-vjlplr953YAuJfHiP4O+CyrTlr6OaFgXAGrzWq4MVMjnpV/PT5VRJWYFHR0sUGlHTPqeKS4NZbi/xCSgl/3pGQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-aria/visually-hidden': 3.8.15(react@18.2.0) + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@react-aria/progress@3.4.16(react@18.2.0): + resolution: {integrity: sha512-RbDIFQg4+/LG+KYZeLAijt2zH7K2Gp0CY9RKWdho3nU5l3/w57Fa7NrfDGWtpImrt7bR2nRmXMA6ESfr7THfrg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/progress': 3.5.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/progress@3.4.9(react@18.2.0): resolution: {integrity: sha512-CME1ZLsJHOmSgK8IAPOC/+vYO5Oc614mkEw5MluT/yclw5rMyjAkK1XsHLjEXy81uwPeiRyoQQIMPKG2/sMxFQ==} peerDependencies: @@ -9884,6 +10331,24 @@ packages: react: 18.2.0 dev: false + /@react-aria/radio@3.10.7(react@18.2.0): + resolution: {integrity: sha512-o2tqIe7xd1y4HeCBQfz/sXIwLJuI6LQbVoCQ1hgk/5dGhQ0LiuXohRYitGRl9zvxW8jYdgLULmOEDt24IflE8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/radio': 3.10.7(react@18.2.0) + '@react-types/radio': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/searchfield@3.7.1(react@18.2.0): resolution: {integrity: sha512-ebhnV/reNByIZzpcQLHIo1RQ+BrYS8HdwX624i9R7dep1gxGHXYEaqL9aSY+RdngNerB4OeiWmB75em9beSpjQ==} peerDependencies: @@ -9900,6 +10365,22 @@ packages: react: 18.2.0 dev: false + /@react-aria/searchfield@3.7.8(react@18.2.0): + resolution: {integrity: sha512-SsF5xwH8Us548QgzivvbM7nhFbw7pu23xnRRIuhlP3MwOR3jRUFh17NKxf3Z0jvrDv/u0xfm3JKHIgaUN0KJ2A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/textfield': 3.14.8(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/searchfield': 3.5.6(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/searchfield': 3.5.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/select@3.14.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pAy/+Xbj11Lx6bi/O1hWH0NSIDRxFb6V7N0ry2L8x7MALljh516VbpnAc5RgvbjbuKq0cHUAcdINOzOzpYWm4A==} peerDependencies: @@ -9924,6 +10405,30 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/select@3.14.9(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-tiNgMyA2G9nKnFn3pB/lMSgidNToxSFU7r6l4OcG+Vyr63J7B/3dF2lTXq8IYhlfOR3K3uQkjroSx52CmC3NDw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/listbox': 3.13.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/menu': 3.15.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-aria/visually-hidden': 3.8.15(react@18.2.0) + '@react-stately/select': 3.6.7(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/select': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/selection@3.17.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-xl2sgeGH61ngQeE05WOWWPVpGRTPMjQEFmsAWEprArFi4Z7ihSZgpGX22l1w7uSmtXM/eN/v0W8hUYUju5iXlQ==} peerDependencies: @@ -9941,6 +10446,23 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/selection@3.19.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-GYoObXCXlmGK08hp7Qfl6Bk0U+bKP5YDWSsX+MzNjJsqzQSLm4S06tRB9ACM7gIo9dDCvL4IRxdSYTJAlJc6bw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/separator@3.3.9(react@18.2.0): resolution: {integrity: sha512-1wEXiaSJjq2+DR5TC0RKnUBsfZN+YXTzyI7XMzjQoc3YlclumX8wQtzPAOGOEjHB1JKUgo1Gw70FtupVXz58QQ==} peerDependencies: @@ -9952,6 +10474,34 @@ packages: react: 18.2.0 dev: false + /@react-aria/separator@3.4.2(react@18.2.0): + resolution: {integrity: sha512-Xql9Kg3VlGesEUC7QheE+L5b3KgBv0yxiUU+/4JP8V2vfU/XSz4xmprHEeq7KVQVOetn38iiXU8gA5g26SEsUA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-aria/slider@3.7.11(react@18.2.0): + resolution: {integrity: sha512-2WAwjANXPsA2LHJ5nxxV4c7ihFAzz2spaBz8+FJ7MDYE7WroYnE8uAXElea1aGo+Lk0DTiAdepLpBkggqPNanw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/slider': 3.5.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/slider': 3.7.5(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/slider@3.7.4(react@18.2.0): resolution: {integrity: sha512-OFJWeGSL2duVDFs/kcjlWsY6bqCVKZgM0aFn2QN4wmID+vfBvBnqGHAgWv3BCePTAPS3+GBjMN002TrftorjwQ==} peerDependencies: @@ -9985,6 +10535,22 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/spinbutton@3.6.8(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-OJMAYRIZ0WrWE+5tZsywrSg4t+aOwl6vl/e1+J64YcGMM+p+AKd61KGG5T0OgNSORXjoVIZOmj6wZ6Od4xfPMw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/ssr@3.9.1(react@18.2.0): resolution: {integrity: sha512-NqzkLFP8ZVI4GSorS0AYljC13QW2sc8bDqJOkBvkAt3M8gbcAXJWVRGtZBCRscki9RZF+rNlnPdg0G0jYkhJcg==} engines: {node: '>= 12'} @@ -9995,6 +10561,16 @@ packages: react: 18.2.0 dev: false + /@react-aria/ssr@3.9.5(react@18.2.0): + resolution: {integrity: sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==} + engines: {node: '>= 12'} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/switch@3.6.0(react@18.2.0): resolution: {integrity: sha512-YNWc5fGLNXE4XlmDAKyqAdllRiClGR7ki4KGFY7nL+xR5jxzjCGU3S3ToMK5Op3QSMGZLxY/aYmC4O+MvcoADQ==} peerDependencies: @@ -10007,6 +10583,19 @@ packages: react: 18.2.0 dev: false + /@react-aria/switch@3.6.7(react@18.2.0): + resolution: {integrity: sha512-yBNvKylhc3ZRQ0+7mD0mIenRRe+1yb8YaqMMZr8r3Bf87LaiFtQyhRFziq6ZitcwTJz5LEWjBihxbSVvUrf49w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/toggle': 3.10.7(react@18.2.0) + '@react-stately/toggle': 3.7.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/switch': 3.5.5(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/table@3.13.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-AzmETpyxwNqISTzwHJPs85x9gujG40IIsSOBUdp49oKhB85RbPLvMwhadp4wCVAoHw3erOC/TJxHtVc7o2K1LA==} peerDependencies: @@ -10033,6 +10622,31 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/table@3.15.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-nQCLjlEvyJHyuijHw8ESqnA9fxNJfQHx0WPcl08VDEb8VxcE/MVzSAIedSWaqjG5k9Oflz6o/F/zHtzw4AFAow==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/grid': 3.10.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/live-announcer': 3.3.4 + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-aria/visually-hidden': 3.8.15(react@18.2.0) + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/flags': 3.0.3 + '@react-stately/table': 3.12.2(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/table': 3.10.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/tabs@3.8.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Plw0K/5Qv35vYq7pHZFfQB2BF5OClFx4Abzo9hLVx4oMy3qb7i5lxmLBVbt81yPX/MdjYeP4zO1EHGBl4zMRhA==} peerDependencies: @@ -10051,6 +10665,24 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/tabs@3.9.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aQZGAoOIg1B16qlvXIy6+rHbNBNVcWkGjOjeyvqTTPMjXt/FmElkICnqckI7MRJ1lTqzyppCOBitYOHSXRo8Uw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/tabs': 3.6.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/tabs': 3.3.9(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/tag@3.3.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-w7d8sVZqxTo8VFfeg2ixLp5kawtrcguGznVY4mt5aE6K8LMJOeNVDqNNfolfyia80VjOWjeX+RpVdVJRdrv/GQ==} peerDependencies: @@ -10071,6 +10703,26 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@react-aria/tag@3.4.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-iyJuATQ8t2cdLC7hiZm143eeZze/MtgxaMq0OewlI9TUje54bkw2Q+CjERdgisIo3Eemf55JJgylGrTcalEJAg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/gridlist': 3.9.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-types/button': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@react-aria/textfield@3.14.1(react@18.2.0): resolution: {integrity: sha512-UMepuYtDdCgrUF4dMphNxrUm23xOmR54aZD1pbp9cJyfioVkJN35BTXZVkD0D07gHLn4RhxKIZxBortQQrLB9g==} peerDependencies: @@ -10088,6 +10740,23 @@ packages: react: 18.2.0 dev: false + /@react-aria/textfield@3.14.8(react@18.2.0): + resolution: {integrity: sha512-FHEvsHdE1cMR2B7rlf+HIneITrC40r201oLYbHAp3q26jH/HUujzFBB9I20qhXjyBohMWfQLqJhSwhs1VW1RJQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/form': 3.0.8(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/textfield': 3.9.6(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/toggle@3.10.0(react@18.2.0): resolution: {integrity: sha512-6cUf4V9TuG2J7AvXUdU/GspEPFCubUOID3mrselSe563RViy+mMZk0vUEOdyoNanDcEXl58W4dE3SGWxFn71vg==} peerDependencies: @@ -10102,6 +10771,21 @@ packages: react: 18.2.0 dev: false + /@react-aria/toggle@3.10.7(react@18.2.0): + resolution: {integrity: sha512-/RJQU8QlPZXRElZ3Tt10F5K5STgUBUGPpfuFUGuwF3Kw3GpPxYsA1YAVjxXz2MMGwS0+y6+U/J1xIs1AF0Jwzg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/toggle': 3.7.7(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/tooltip@3.7.0(react@18.2.0): resolution: {integrity: sha512-+u9Sftkfe09IDyPEnbbreFKS50vh9X/WTa7n1u2y3PenI9VreLpUR6czyzda4BlvQ95e9jQz1cVxUjxTNaZmBw==} peerDependencies: @@ -10117,6 +10801,21 @@ packages: react: 18.2.0 dev: false + /@react-aria/tooltip@3.7.7(react@18.2.0): + resolution: {integrity: sha512-UOTTDbbUz7OaE48VjNSWl+XQbYCUs5Gss4I3Tv1pfRLXzVtGYXv3ur/vRayvZR0xd12ANY26fZPNkSmCFpmiXw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-stately/tooltip': 3.4.12(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/tooltip': 3.4.11(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/utils@3.23.0(react@18.2.0): resolution: {integrity: sha512-fJA63/VU4iQNT8WUvrmll3kvToqMurD69CcgVmbQ56V7ZbvlzFi44E7BpnoaofScYLLtFWRjVdaHsohT6O/big==} peerDependencies: @@ -10130,6 +10829,31 @@ packages: react: 18.2.0 dev: false + /@react-aria/utils@3.25.2(react@18.2.0): + resolution: {integrity: sha512-GdIvG8GBJJZygB4L2QJP1Gabyn2mjFsha73I2wSe+o4DYeGWoJiMZRM06PyTIxLH4S7Sn7eVDtsSBfkc2VY/NA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + clsx: 2.1.0 + react: 18.2.0 + dev: false + + /@react-aria/visually-hidden@3.8.15(react@18.2.0): + resolution: {integrity: sha512-l+sJ7xTdD5Sd6+rDNDaeJCSPnHOsI+BaJyApvb/YcVgHa7rB47lp6TXCWUCDItcPY4JqRGyeByRJVrtzBFTWCw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-aria/visually-hidden@3.8.8(react@18.2.0): resolution: {integrity: sha512-Cn2PYKD4ijGDtF0+dvsh8qa4y7KTNAlkTG6h20r8Q+6UTyRNmtE2/26QEaApRF8CBiNy9/BZC/ZC4FK2OjvCoA==} peerDependencies: @@ -10592,6 +11316,10 @@ packages: react: 18.2.0 dev: false + /@react-spring/rafz@9.7.4: + resolution: {integrity: sha512-mqDI6rW0Ca8IdryOMiXRhMtVGiEGLIO89vIOyFQXRIwwIMX30HLya24g9z4olDvFyeDW3+kibiKwtZnA4xhldA==} + dev: false + /@react-stately/calendar@3.4.3(react@18.2.0): resolution: {integrity: sha512-OrEcdskszDjnjVnFuSiDC2PVBJ6lWMCJROD5s6W1LUehUtBp8LX9wPavAGHV43LbhN9ldj560sxaQ4WCddrRCA==} peerDependencies: @@ -10605,6 +11333,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/calendar@3.5.4(react@18.2.0): + resolution: {integrity: sha512-R2011mtFSXIjzMXaA+CZ1sflPm9XkTBMqVk77Bnxso2ZsG7FUX8nqFmaDavxwTuHFC6OUexAGSMs8bP9KycTNg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/calendar': 3.4.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/checkbox@3.6.1(react@18.2.0): resolution: {integrity: sha512-rOjFeVBy32edYwhKiHj3ZLdLeO+xZ2fnBwxnOBjcygnw4Neygm8FJH/dB1J0hdYYR349yby86ED2x0wRc84zPw==} peerDependencies: @@ -10618,6 +11359,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/checkbox@3.6.8(react@18.2.0): + resolution: {integrity: sha512-c8TWjU67XHHBCpqj6+FXXhQUWGr2Pil1IKggX81pkedhWiJl3/7+WHJuZI0ivGnRjp3aISNOG8UNVlBEjS9E8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/collections@3.10.4(react@18.2.0): resolution: {integrity: sha512-OHhCrItGt4zB2bSrgObRo0H2SC7QlkH8ReGxo+NVIWchXRLRoiWBP7S+IwleewEo5gOqDVPY3hqA9n4iiI8twg==} peerDependencies: @@ -10628,6 +11382,16 @@ packages: react: 18.2.0 dev: false + /@react-stately/collections@3.10.9(react@18.2.0): + resolution: {integrity: sha512-plyrng6hOQMG8LrjArMA6ts/DgWyXln3g90/hFNbqe/hdVYF53sDVsj8Jb+5LtoYTpiAlV6eOvy1XR0vPZUf8w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/combobox@3.8.1(react@18.2.0): resolution: {integrity: sha512-FaWkqTXQdWg7ptaeU4iPcqF/kxbRg2ZNUcvW/hiL/enciV5tRCsddvfNqvDvy1L30z9AUwlp9MWqzm/DhBITCw==} peerDependencies: @@ -10645,6 +11409,23 @@ packages: react: 18.2.0 dev: false + /@react-stately/combobox@3.9.2(react@18.2.0): + resolution: {integrity: sha512-ZsbAcD58IvxZqwYxg9d2gOf8R/k5RUB2TPUiGKD6wgWfEKH6SDzY3bgRByHGOyMCyJB62cHjih/ZShizNTguqA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-stately/select': 3.6.7(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/combobox': 3.12.1(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/data@3.11.0(react@18.2.0): resolution: {integrity: sha512-0BlPT58WrAtUvpiEfUuyvIsGFTzp/9vA5y+pk53kGJhOdc5tqBGHi9cg40pYE/i1vdHJGMpyHGRD9nkQb8wN3Q==} peerDependencies: @@ -10655,6 +11436,22 @@ packages: react: 18.2.0 dev: false + /@react-stately/datepicker@3.10.2(react@18.2.0): + resolution: {integrity: sha512-pa5IZUw+49AyOnddwu4XwU2kI5eo/1thbiIVNHP8uDpbbBrBkquSk3zVFDAGX1cu/I1U2VUkt64U/dxgkwaMQw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@internationalized/string': 3.2.3 + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/datepicker': 3.8.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/datepicker@3.9.1(react@18.2.0): resolution: {integrity: sha512-o5xLvlZGJyAbTev2yruGlV2fzQyIDuYTgL19TTt0W0WCfjGGr/AAA9GjGXXmyoRA7sZMxqIPnnv7lNrdA38ofA==} peerDependencies: @@ -10682,12 +11479,29 @@ packages: react: 18.2.0 dev: false + /@react-stately/dnd@3.4.2(react@18.2.0): + resolution: {integrity: sha512-VrHmNoNdVGrx5JHdz/zewmN+N8rlZe+vL/iAOLmvQ74RRLEz8KDFnHdlhgKg1AZqaSg3JJ18BlHEkS7oL1n+tA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/flags@3.0.0: resolution: {integrity: sha512-e3i2ItHbIa0eEwmSXAnPdD7K8syW76JjGe8ENxwFJPW/H1Pu9RJfjkCb/Mq0WSPN/TpxBb54+I9TgrGhbCoZ9w==} dependencies: '@swc/helpers': 0.4.14 dev: false + /@react-stately/flags@3.0.3: + resolution: {integrity: sha512-/ha7XFA0RZTQsbzSPwu3KkbNMgbvuM0GuMTYLTBWpgBrovBNTM+QqI/PfZTdHg8PwCYF4H5Y8gjdSpdulCvJFw==} + dependencies: + '@swc/helpers': 0.5.2 + dev: false + /@react-stately/form@3.0.0(react@18.2.0): resolution: {integrity: sha512-C8wkfFmtx1escizibhdka5JvTy9/Vp173CS9cakjvWTmnjYYC1nOlzwp7BsYWTgerCFbRY/BU/Cf/bJDxPiUKQ==} peerDependencies: @@ -10698,6 +11512,16 @@ packages: react: 18.2.0 dev: false + /@react-stately/form@3.0.5(react@18.2.0): + resolution: {integrity: sha512-J3plwJ63HQz109OdmaTqTA8Qhvl3gcYYK7DtgKyNP6mc/Me2Q4tl2avkWoA+22NRuv5m+J8TpBk4AVHUEOwqeQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/grid@3.8.4(react@18.2.0): resolution: {integrity: sha512-rwqV1K4lVhaiaqJkt4TfYqdJoVIyqvSm98rKAYfCNzrKcivVpoiCMJ2EMt6WlYCjDVBdEOQ7fMV1I60IV0pntA==} peerDependencies: @@ -10711,6 +11535,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/grid@3.9.2(react@18.2.0): + resolution: {integrity: sha512-2gK//sqAqg2Xaq6UITTFQwFUJnBRgcW+cKBVbFt+F8d152xB6UwwTS/K79E5PUkOotwqZgTEpkrSFs/aVxCLpw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/list@3.10.2(react@18.2.0): resolution: {integrity: sha512-INt+zofkIg2KN8B95xPi9pJG7ZFWAm30oIm/lCPBqM3K1Nm03/QaAbiQj2QeJcOsG3lb7oqI6D6iwTolwJkjIQ==} peerDependencies: @@ -10724,6 +11561,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/list@3.10.8(react@18.2.0): + resolution: {integrity: sha512-rHCiPLXd+Ry3ztR9DkLA5FPQeH4Zd4/oJAEDWJ77W3oBBOdiMp3ZdHDLP7KBRh17XGNLO/QruYoHWAQTPiMF4g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/menu@3.6.0(react@18.2.0): resolution: {integrity: sha512-OB6CjNyfOkAuirqx1oTL8z8epS9WDzLyrXjmRnxdiCU9EgRXLGAQNECuO7VIpl58oDry8tgRJiJ8fn8FivWSQA==} peerDependencies: @@ -10736,6 +11586,18 @@ packages: react: 18.2.0 dev: false + /@react-stately/menu@3.8.2(react@18.2.0): + resolution: {integrity: sha512-lt6hIHmSixMzkKx1rKJf3lbAf01EmEvvIlENL20GLiU9cRbpPnPJ1aJMZ5Ad5ygglA7wAemAx+daPhlTQfF2rg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-types/menu': 3.9.11(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/numberfield@3.8.0(react@18.2.0): resolution: {integrity: sha512-1XvB8tDOvZKcFnMM6qNLEaTVJcIc0jRFS/9jtS8MzalZvh8DbKi0Ucm1bGU7S5rkCx2QWqZ0rGOIm2h/RlcpkA==} peerDependencies: @@ -10749,6 +11611,30 @@ packages: react: 18.2.0 dev: false + /@react-stately/numberfield@3.9.6(react@18.2.0): + resolution: {integrity: sha512-p2R9admGLI439qZzB39dyANhkruprJJtZwuoGVtxW/VD0ficw6BrPVqAaKG25iwKPkmveleh9p8o+yRqjGedcQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/number': 3.5.3 + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/numberfield': 3.8.5(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-stately/overlays@3.6.10(react@18.2.0): + resolution: {integrity: sha512-XxZ2qScT5JPwGk9qiVJE4dtVh3AXTcYwGRA5RsHzC26oyVVsegPqY2PmNJGblAh6Q57VyodoVUyebE0Eo5CzRw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/overlays@3.6.4(react@18.2.0): resolution: {integrity: sha512-tHEaoAGpE9dSnsskqLPVKum59yGteoSqsniTopodM+miQozbpPlSjdiQnzGLroy5Afx5OZYClE616muNHUILXA==} peerDependencies: @@ -10773,6 +11659,19 @@ packages: react: 18.2.0 dev: false + /@react-stately/radio@3.10.7(react@18.2.0): + resolution: {integrity: sha512-ZwGzFR+sGd42DxRlDTp3G2vLZyhMVtgHkwv2BxazPHxPMvLO9yYl7+3PPNxAmhMB4tg2u9CrzffpGX2rmEJEXA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/radio': 3.8.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/searchfield@3.5.0(react@18.2.0): resolution: {integrity: sha512-SStjChkn/33pEn40slKQPnBnmQYyxVazVwPjiBkdeVejC42lUVairUTrGJgF0PNoZTbxn0so2/XzjqTC9T8iCw==} peerDependencies: @@ -10784,6 +11683,17 @@ packages: react: 18.2.0 dev: false + /@react-stately/searchfield@3.5.6(react@18.2.0): + resolution: {integrity: sha512-gVzU0FeWiLYD8VOYRgWlk79Qn7b2eirqOnWhtI5VNuGN8WyNaCIuBp6SkXTW2dY8hs2Hzn8HlMbgy1MIc7130Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/searchfield': 3.5.8(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/select@3.6.1(react@18.2.0): resolution: {integrity: sha512-e5ixtLiYLlFWM8z1msDqXWhflF9esIRfroptZsltMn1lt2iImUlDRlOTZlMtPQzUrDWoiHXRX88sSKUM/jXjQQ==} peerDependencies: @@ -10798,6 +11708,20 @@ packages: react: 18.2.0 dev: false + /@react-stately/select@3.6.7(react@18.2.0): + resolution: {integrity: sha512-hCUIddw0mPxVy1OH6jhyaDwgNea9wESjf+MYdnnTG/abRB+OZv/dWScd87OjzVsHTHWcw7CN4ZzlJoXm0FJbKQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/form': 3.0.5(react@18.2.0) + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-types/select': 3.9.6(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/selection@3.14.2(react@18.2.0): resolution: {integrity: sha512-mL7OoiUgVWaaF7ks5XSxgbXeShijYmD4G3bkBHhqkpugU600QH6BM2hloCq8KOUupk1y8oTljPtF9EmCv375DA==} peerDependencies: @@ -10810,6 +11734,18 @@ packages: react: 18.2.0 dev: false + /@react-stately/selection@3.16.2(react@18.2.0): + resolution: {integrity: sha512-C4eSKw7BIZHJLPzwqGqCnsyFHiUIEyryVQZTJDt6d0wYBOHU6k1pW+Q4VhrZuzSv+IMiI2RkiXeJKc55f0ZXrg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/slider@3.5.0(react@18.2.0): resolution: {integrity: sha512-dOVpIxb7XKuiRxgpHt1bUSlsklciFki100tKIyBPR+Okar9iC/CwLYROYgVfLkGe77jEBNkor9tDLjDGEWcc1w==} peerDependencies: @@ -10822,6 +11758,18 @@ packages: react: 18.2.0 dev: false + /@react-stately/slider@3.5.7(react@18.2.0): + resolution: {integrity: sha512-gEIGTcpBLcXixd8LYiLc8HKrBiGQJltrrEGoOvvTP8KVItXQxmeL+JiSsh8qgOoUdRRpzmAoFNUKGEg2/gtN8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/slider': 3.7.5(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/table@3.11.4(react@18.2.0): resolution: {integrity: sha512-dWINJIEOKQl4qq3moq+S8xCD3m+yJqBj0dahr+rOkS+t2uqORwzsusTM35D2T/ZHZi49S2GpE7QuDa+edCynPw==} peerDependencies: @@ -10839,6 +11787,23 @@ packages: react: 18.2.0 dev: false + /@react-stately/table@3.12.2(react@18.2.0): + resolution: {integrity: sha512-dUcsrdALylhWz6exqIoqtR/dnrzjIAptMyAUPT378Y/mCYs4PxKkHSvtPEQrZhdQS1ALIIgfeg9KUVIempoXPw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/flags': 3.0.3 + '@react-stately/grid': 3.9.2(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/table': 3.10.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/tabs@3.6.3(react@18.2.0): resolution: {integrity: sha512-Nj+Gacwa2SIzYIvHW40GsyX4Q6c8kF7GOuXESeQswbCjnwqhrSbDBp+ngPcUPUJxqFh6JhDCVwAS3wMhUoyUwA==} peerDependencies: @@ -10851,6 +11816,18 @@ packages: react: 18.2.0 dev: false + /@react-stately/tabs@3.6.9(react@18.2.0): + resolution: {integrity: sha512-YZDqZng3HrRX+uXmg6u78x73Oi24G5ICpiXVqDKKDkO333XCA5H8MWItiuPZkYB2h3SbaCaLqSobLkvCoWYpNQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/list': 3.10.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/tabs': 3.3.9(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/toggle@3.7.0(react@18.2.0): resolution: {integrity: sha512-TRksHkCJk/Xogq4181g3CYgJf+EfsJCqX5UZDSw1Z1Kgpvonjmdf6FAfQfCh9QR2OuXUL6hOLUDVLte5OPI+5g==} peerDependencies: @@ -10862,6 +11839,28 @@ packages: react: 18.2.0 dev: false + /@react-stately/toggle@3.7.7(react@18.2.0): + resolution: {integrity: sha512-AS+xB4+hHWa3wzYkbS6pwBkovPfIE02B9SnuYTe0stKcuejpWKo5L3QMptW0ftFYsW3ZPCXuneImfObEw2T01A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/checkbox': 3.8.3(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-stately/tooltip@3.4.12(react@18.2.0): + resolution: {integrity: sha512-QKYT/cze7n9qaBsk7o5ais3jRfhYCzcVRfps+iys/W+/9FFbbhjfQG995Lwi6b+vGOHWfXxXpwmyIO2tzM1Iog==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/overlays': 3.6.10(react@18.2.0) + '@react-types/tooltip': 3.4.11(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/tooltip@3.4.6(react@18.2.0): resolution: {integrity: sha512-uL93bmsXf+OOgpKLPEKfpDH4z+MK2CuqlqVxx7rshN0vjWOSoezE5nzwgee90+RpDrLNNNWTNa7n+NkDRpI1jA==} peerDependencies: @@ -10886,6 +11885,28 @@ packages: react: 18.2.0 dev: false + /@react-stately/tree@3.8.4(react@18.2.0): + resolution: {integrity: sha512-HFNclIXJ/3QdGQWxXbj+tdlmIX/XwCfzAMB5m26xpJ6HtJhia6dtx3GLfcdyHNjmuRbAsTBsAAnnVKBmNRUdIQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-stately/collections': 3.10.9(react@18.2.0) + '@react-stately/selection': 3.16.2(react@18.2.0) + '@react-stately/utils': 3.10.3(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + + /@react-stately/utils@3.10.3(react@18.2.0): + resolution: {integrity: sha512-moClv7MlVSHpbYtQIkm0Cx+on8Pgt1XqtPx6fy9rQFb2DNc9u1G3AUVnqA17buOkH1vLxAtX4MedlxMWyRCYYA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@swc/helpers': 0.5.2 + react: 18.2.0 + dev: false + /@react-stately/utils@3.9.0(react@18.2.0): resolution: {integrity: sha512-yPKFY1F88HxuZ15BG2qwAYxtpE4HnIU0Ofi4CuBE0xC6I8mwo4OQjDzi+DZjxQngM9D6AeTTD6F1V8gkozA0Gw==} peerDependencies: @@ -10916,6 +11937,16 @@ packages: react: 18.2.0 dev: false + /@react-types/breadcrumbs@3.7.7(react@18.2.0): + resolution: {integrity: sha512-ZmhXwD2LLzfEA2OvOCp/QvXu8A/Edsrn5q0qUDGsmOZj9SCVeT82bIv8P+mQnATM13mi2gyoik6102Jc1OscJA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/link': 3.5.7(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/button@3.9.1(react@18.2.0): resolution: {integrity: sha512-bf9iTar3PtqnyV9rA+wyFyrskZKhwmOuOd/ifYIjPs56YNVXWH5Wfqj6Dx3xdFBgtKx8mEVQxVhoX+WkHX+rtw==} peerDependencies: @@ -10925,6 +11956,15 @@ packages: react: 18.2.0 dev: false + /@react-types/button@3.9.6(react@18.2.0): + resolution: {integrity: sha512-8lA+D5JLbNyQikf8M/cPP2cji91aVTcqjrGpDqI7sQnaLFikM8eFR6l1ZWGtZS5MCcbfooko77ha35SYplSQvw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/calendar@3.4.3(react@18.2.0): resolution: {integrity: sha512-96x57ctX5wNEl+8et3sc2NQm8neOJayEeqOQQpyPtI7jyvst/xBrKCwysf9W/dhgPlUC+KeBAYFWfjd5hFVHYA==} peerDependencies: @@ -10935,6 +11975,16 @@ packages: react: 18.2.0 dev: false + /@react-types/calendar@3.4.9(react@18.2.0): + resolution: {integrity: sha512-O/PS9c21HgO9qzxOyZ7/dTccxabFZdF6tj3UED4DrBw7AN3KZ7JMzwzYbwHinOcO7nUcklGgNoAIHk45UAKR9g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/checkbox@3.6.0(react@18.2.0): resolution: {integrity: sha512-vgbuJzQpVCNT5AZWV0OozXCnihqrXxoZKfJFIw0xro47pT2sn3t5UC4RA9wfjDGMoK4frw1K/4HQLsQIOsPBkw==} peerDependencies: @@ -10944,6 +11994,15 @@ packages: react: 18.2.0 dev: false + /@react-types/checkbox@3.8.3(react@18.2.0): + resolution: {integrity: sha512-f4c1mnLEt0iS1NMkyZXgT3q3AgcxzDk7w6MSONOKydcnh0xG5L2oefY14DhVDLkAuQS7jThlUFwiAs+MxiO3MA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/combobox@3.10.0(react@18.2.0): resolution: {integrity: sha512-1IXSNS02TPbguyYopaW2snU6sZusbClHrEyVr4zPeexTV4kpUUBNXOzFQ+eSQRR0r2XW57Z0yRW4GJ6FGU0yCA==} peerDependencies: @@ -10953,6 +12012,15 @@ packages: react: 18.2.0 dev: false + /@react-types/combobox@3.12.1(react@18.2.0): + resolution: {integrity: sha512-bd5YwHZWtgnJx4jGbplWbYzXj7IbO5w3IY5suNR7r891rx6IktquZ8GQwyYH0pQ/x+X5LdK2xI59i6+QC2PmlA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/datepicker@3.7.1(react@18.2.0): resolution: {integrity: sha512-5juVDULOytNzkotqX8j5mYKJckeIpkgbHqVSGkPgLw0++FceIaSZ6RH56cqLup0pO45paqIt9zHh+QXBYX+syg==} peerDependencies: @@ -10965,6 +12033,28 @@ packages: react: 18.2.0 dev: false + /@react-types/datepicker@3.8.2(react@18.2.0): + resolution: {integrity: sha512-Ih4F0bNVGrEuwCD8XmmBAspuuOBsj/Svn/pDFtC2RyAZjXfWh+sI+n4XLz/sYKjvARh5TUI8GNy9smYS4vYXug==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/date': 3.5.5 + '@react-types/calendar': 3.4.9(react@18.2.0) + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + + /@react-types/dialog@3.5.12(react@18.2.0): + resolution: {integrity: sha512-JmpQbSpXltqEyYfEwoqDolABIiojeExkqolHNdQlayIsfFuSxZxNwXZPOpz58Ri/iwv21JP7K3QF0Gb2Ohxl9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/dialog@3.5.7(react@18.2.0): resolution: {integrity: sha512-geYoqAyQaTLG43AaXdMUVqZXYgkSifrD9cF7lR2kPAT0uGFv0YREi6ieU+aui8XJ83EW0xcxP+EPWd2YkN4D4w==} peerDependencies: @@ -10984,6 +12074,15 @@ packages: react: 18.2.0 dev: false + /@react-types/grid@3.2.8(react@18.2.0): + resolution: {integrity: sha512-6PJrpukwMqlv3IhJSDkJuVbhHM8Oe6hd2supWqd9adMXrlSP7QHt9a8SgFcFblCCTx8JzUaA0PvY5sTudcEtOQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/link@3.5.2(react@18.2.0): resolution: {integrity: sha512-/s51/WejmpLiyxOgP89s4txgxYoGaPe8pVDItVo1h4+BhU1Puyvgv/Jx8t9dPvo6LUXbraaN+SgKk/QDxaiirw==} peerDependencies: @@ -10993,6 +12092,15 @@ packages: react: 18.2.0 dev: false + /@react-types/link@3.5.7(react@18.2.0): + resolution: {integrity: sha512-2WyaVmm1qr9UrSG3Dq6iz+2ziuVp+DH8CsYZ9CA6aNNb6U18Hxju3LTPb4a5gM0eC7W0mQGNBmrgGlAdDZEJOw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/listbox@3.4.6(react@18.2.0): resolution: {integrity: sha512-XOQvrTqNh5WIPDvKiWiep8T07RAsMfjAXTjDbnjxVlKACUXkcwpts9kFaLnJ9LJRFt6DwItfP+WMkzvmx63/NQ==} peerDependencies: @@ -11002,6 +12110,25 @@ packages: react: 18.2.0 dev: false + /@react-types/listbox@3.5.1(react@18.2.0): + resolution: {integrity: sha512-n5bOgD9lgfK1qaLtag9WPnu151SwXBCNn/OgGY/Br9mWRl+nPUEYtFcPX+2VCld7uThf54kwrTmzlFnaraIlcw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + + /@react-types/menu@3.9.11(react@18.2.0): + resolution: {integrity: sha512-IguQVF70d7aHXgWB1Rd2a/PiIuLZ2Nt7lyayJshLcy/NLOYmgpTmTyn2WCtlA5lTfQwmQrNFf4EvnWkeljJXdA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/menu@3.9.6(react@18.2.0): resolution: {integrity: sha512-w/RbFInOf4nNayQDv5c2L8IMJbcFOkBhsT3xvvpTy+CHvJcQdjggwaV1sRiw7eF/PwB81k2CwigmidUzHJhKDg==} peerDependencies: @@ -11021,6 +12148,15 @@ packages: react: 18.2.0 dev: false + /@react-types/meter@3.4.3(react@18.2.0): + resolution: {integrity: sha512-Y2fX5CTAPGRKxVSeepbeyN6/K+wlF9pMRcNxTSU2qDwdoFqNCtTWMcWuCsU/Y2L/zU0jFWu4x0Vo7WkrcsgcMA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/progress': 3.5.6(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/numberfield@3.7.0(react@18.2.0): resolution: {integrity: sha512-gaGi+vqm1Y8LCWRsWYUjcGftPIzl+8W2VOfkgKMLM8y76nnwTPtmAqs+Ap1cg7sEJSfsiKMq93e9yvP3udrC2w==} peerDependencies: @@ -11030,6 +12166,15 @@ packages: react: 18.2.0 dev: false + /@react-types/numberfield@3.8.5(react@18.2.0): + resolution: {integrity: sha512-LVWggkxwd1nyVZomXBPfQA1E4I4/i4PBifjcDs2AfcV7q5RE9D+DVIDXsYucVOBxPlDOxiAq/T9ypobspWSwHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/overlays@3.8.4(react@18.2.0): resolution: {integrity: sha512-pfgNlQnbF6RB/R2oSxyqAP3Uzz0xE/k5q4n5gUeCDNLjY5qxFHGE8xniZZ503nZYw6VBa9XMN1efDOKQyeiO0w==} peerDependencies: @@ -11039,6 +12184,15 @@ packages: react: 18.2.0 dev: false + /@react-types/overlays@3.8.9(react@18.2.0): + resolution: {integrity: sha512-9ni9upQgXPnR+K9cWmbYWvm3ll9gH8P/XsEZprqIV5zNLMF334jADK48h4jafb1X9RFnj0WbHo6BqcSObzjTig==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/progress@3.5.1(react@18.2.0): resolution: {integrity: sha512-CqsUjczUK/SfuFzDcajBBaXRTW0D3G9S/yqLDj9e8E0ii+lGDLt1PHj24t1J7E88U2rVYqmM9VL4NHTt8o3IYA==} peerDependencies: @@ -11048,6 +12202,15 @@ packages: react: 18.2.0 dev: false + /@react-types/progress@3.5.6(react@18.2.0): + resolution: {integrity: sha512-Nh43sjQ5adyN1bTHBPRaIPhXUdBqP0miYeJpeMY3V/KUl4qmouJLwDnccwFG4xLm6gBfYe22lgbbV7nAfNnuTQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/radio@3.7.0(react@18.2.0): resolution: {integrity: sha512-EcwGAXzSHjSqpFZha7xn3IUrhPiJLj+0yb1Ip0qPmhWz0VVw2DwrkY7q/jfaKroVvQhTo2TbfGhcsAQrt0fRqg==} peerDependencies: @@ -11057,6 +12220,15 @@ packages: react: 18.2.0 dev: false + /@react-types/radio@3.8.3(react@18.2.0): + resolution: {integrity: sha512-fUVJt4Bb6jOReFqnhHVNxWXH7t6c60uSFfoPKuXt/xI9LL1i2jhpur0ggpTfIn3qLIAmNBU6bKBCWAdr4KjeVQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/searchfield@3.5.2(react@18.2.0): resolution: {integrity: sha512-JAK2/Kg4Dr393FYfbRw0TlXKnJPX77sq1x/ZBxtO6p64+MuuIYKqw0i9PwDlo1PViw2QI5u8GFhKA2TgemY9uA==} peerDependencies: @@ -11067,6 +12239,16 @@ packages: react: 18.2.0 dev: false + /@react-types/searchfield@3.5.8(react@18.2.0): + resolution: {integrity: sha512-EcdqalHNIC6BJoRfmqUhAvXRd3aHkWlV1cFCz57JJKgUEFYyXPNrXd1b73TKLzTXEk+X/D6LKV15ILYpEaxu8w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + '@react-types/textfield': 3.9.6(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/select@3.9.1(react@18.2.0): resolution: {integrity: sha512-EpKSxrnh8HdZvOF9dHQkjivAcdIp1K81FaxmvosH8Lygqh0iYXxAdZGtKLMyBoPI8YFhA+rotIzTcOqgCCnqWA==} peerDependencies: @@ -11076,6 +12258,15 @@ packages: react: 18.2.0 dev: false + /@react-types/select@3.9.6(react@18.2.0): + resolution: {integrity: sha512-cVSFR0eJLup/ht1Uto+y8uyLmHO89J6wNh65SIHb3jeVz9oLBAedP3YNI2qB+F9qFMUcA8PBSLXIIuT6gXzLgQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/shared@3.22.0(react@18.2.0): resolution: {integrity: sha512-yVOekZWbtSmmiThGEIARbBpnmUIuePFlLyctjvCbgJgGhz8JnEJOipLQ/a4anaWfzAgzSceQP8j/K+VOOePleA==} peerDependencies: @@ -11084,6 +12275,14 @@ packages: react: 18.2.0 dev: false + /@react-types/shared@3.24.1(react@18.2.0): + resolution: {integrity: sha512-AUQeGYEm/zDTN6zLzdXolDxz3Jk5dDL7f506F07U8tBwxNNI3WRdhU84G0/AaFikOZzDXhOZDr3MhQMzyE7Ydw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + react: 18.2.0 + dev: false + /@react-types/slider@3.7.0(react@18.2.0): resolution: {integrity: sha512-uyQXUVFfqc9SPUW0LZLMan2n232F/OflRafiHXz9viLFa9tVOupVa7GhASRAoHojwkjoJ1LjFlPih7g5dOZ0/Q==} peerDependencies: @@ -11093,6 +12292,15 @@ packages: react: 18.2.0 dev: false + /@react-types/slider@3.7.5(react@18.2.0): + resolution: {integrity: sha512-bRitwQRQjQoOcKEdPMljnvm474dwrmsc6pdsVQDh/qynzr+KO9IHuYc3qPW53WVE2hMQJDohlqtCAWQXWQ5Vcg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/switch@3.5.0(react@18.2.0): resolution: {integrity: sha512-/wNmUGjk69bP6t5k2QkAdrNN5Eb9Rz4dOyp0pCPmoeE+5haW6sV5NmtkvWX1NSc4DQz1xL/a5b+A0vxPCP22Jw==} peerDependencies: @@ -11102,6 +12310,25 @@ packages: react: 18.2.0 dev: false + /@react-types/switch@3.5.5(react@18.2.0): + resolution: {integrity: sha512-SZx1Bd+COhAOs/RTifbZG+uq/llwba7VAKx7XBeX4LeIz1dtguy5bigOBgFTMQi4qsIVCpybSWEEl+daj4XFPw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + + /@react-types/table@3.10.1(react@18.2.0): + resolution: {integrity: sha512-xsNh0Gm4GtNeSknZqkMsfGvc94fycmfhspGO+FzQKim2hB5k4yILwd+lHYQ2UKW6New9GVH/zN2Pd3v67IeZ2g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/grid': 3.2.8(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/table@3.9.2(react@18.2.0): resolution: {integrity: sha512-brw5JUANOzBa2rYNpN8AIl9nDZ9RwRZC6G/wTM/JhtirjC1S42oCtf8Ap5rWJBdmMG/5KOfcGNcAl/huyqb3gg==} peerDependencies: @@ -11121,6 +12348,15 @@ packages: react: 18.2.0 dev: false + /@react-types/tabs@3.3.9(react@18.2.0): + resolution: {integrity: sha512-3Q9kRVvg/qDyeJR/W1+C2z2OyvDWQrSLvOCvAezX5UKzww4rBEAA8OqBlyDwn7q3fiwrh/m64l6p+dbln+RdxQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/textfield@3.9.0(react@18.2.0): resolution: {integrity: sha512-D/DiwzsfkwlAg3uv8hoIfwju+zhB/hWDEdTvxQbPkntDr0kmN/QfI17NMSzbOBCInC4ABX87ViXLGxr940ykGA==} peerDependencies: @@ -11130,6 +12366,25 @@ packages: react: 18.2.0 dev: false + /@react-types/textfield@3.9.6(react@18.2.0): + resolution: {integrity: sha512-0uPqjJh4lYp1aL1HL9IlV8Cgp8eT0PcsNfdoCktfkLytvvBPmox2Pfm57W/d0xTtzZu2CjxhYNTob+JtGAOeXA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + + /@react-types/tooltip@3.4.11(react@18.2.0): + resolution: {integrity: sha512-WPikHQxeT5Lb09yJEaW6Ja3ecE0g1YM6ukWYS2v/iZLUPn5YlYrGytspuCYQNSh/u7suCz4zRLEHYCl7OCigjw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@react-types/overlays': 3.8.9(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + dev: false + /@react-types/tooltip@3.4.6(react@18.2.0): resolution: {integrity: sha512-RaZewdER7ZcsNL99RhVHs8kSLyzIBkwc0W6eFZrxST2MD9J5GzkVWRhIiqtFOd5U1aYnxdJ6woq72Ef+le6Vfw==} peerDependencies: @@ -12374,6 +13629,20 @@ packages: pretty-format: 27.5.1 dev: true + /@testing-library/jest-dom@6.4.8: + resolution: {integrity: sha512-JD0G+Zc38f5MBHA4NgxQMR5XtO5Jx9g86jqturNTt2WUfRmLDIY7iKkWHDCCTiDuFMre6nxAD5wHw9W5kI4rGw==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + dependencies: + '@adobe/css-tools': 4.4.0 + '@babel/runtime': 7.24.5 + aria-query: 5.3.0 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + dev: false + /@tootallnate/quickjs-emscripten@0.23.0: resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} dev: false @@ -12507,7 +13776,6 @@ packages: /@types/cookie@0.6.0: resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - dev: false /@types/cors@2.8.17: resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} @@ -12634,6 +13902,10 @@ packages: '@types/node': 18.19.20 dev: false + /@types/invariant@2.2.37: + resolution: {integrity: sha512-IwpIMieE55oGWiXkQPSBY1nw1nFs6bsKXTFskNY8sdS17K24vyEBRQZEwlRS7ZmXCWnJcQtbxWzly+cODWGs2A==} + dev: false + /@types/is-ci@3.0.0: resolution: {integrity: sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==} dependencies: @@ -13465,10 +14737,38 @@ packages: tslib: 2.6.2 dev: false + /@window-splitter/state@0.4.0: + resolution: {integrity: sha512-fZOGk1m2lLhLWGC7Y8Qxhwlh59xH4zmTrRYebQ/iom9yehIitZcpalbViSLDA00Izvx9CrSEFAdjTlMjVIMvpg==} + engines: {node: '>=18.0.0'} + dependencies: + '@react-spring/rafz': 9.7.4 + '@types/invariant': 2.2.37 + big.js: 6.2.1 + invariant: 2.2.4 + xstate: 5.17.4 + dev: false + /@xobotyi/scrollbar-width@1.9.5: resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} dev: false + /@xstate/react@4.1.1(@types/react@18.2.69)(react@18.2.0)(xstate@5.17.4): + resolution: {integrity: sha512-pFp/Y+bnczfaZ0V8B4LOhx3d6Gd71YKAPbzerGqydC2nsYN/mp7RZu3q/w6/kvI2hwR/jeDeetM7xc3JFZH2NA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + xstate: ^5.11.0 + peerDependenciesMeta: + xstate: + optional: true + dependencies: + react: 18.2.0 + use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.69)(react@18.2.0) + use-sync-external-store: 1.2.2(react@18.2.0) + xstate: 5.17.4 + transitivePeerDependencies: + - '@types/react' + dev: false + /@xtuc/ieee754@1.2.0: resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -13762,7 +15062,6 @@ packages: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} dependencies: dequal: 2.0.3 - dev: true /array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} @@ -14200,6 +15499,10 @@ packages: is-windows: 1.0.2 dev: false + /big.js@6.2.1: + resolution: {integrity: sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==} + dev: false + /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} @@ -14553,6 +15856,14 @@ packages: escape-string-regexp: 1.0.5 supports-color: 5.5.0 + /chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: false + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -14959,6 +16270,11 @@ packages: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + /cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + dev: false + /copy-anything@3.0.5: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} engines: {node: '>=12.13'} @@ -15181,6 +16497,10 @@ packages: engines: {node: '>= 6'} dev: true + /css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + dev: false + /cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -15558,7 +16878,6 @@ packages: /dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - dev: true /destr@2.0.3: resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} @@ -15642,6 +16961,10 @@ packages: resolution: {integrity: sha512-8o+oVqLQZoruQPYy3uAAQtc6YbtSiRq5aPJBhJ82YTJRHvI6ofhYAkC81WmjFTnfUbqg6T3aCglIpU9p/5e7Cw==} dev: true + /dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + dev: false + /dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dependencies: @@ -21244,6 +22567,10 @@ packages: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: false + /performant-array-to-tree@1.11.0: + resolution: {integrity: sha512-YwCqIDvnaebXaKuKQhI5yJD6ryDc3FxvoeX/5ougXTKDUWb7s5S2BuBgIyftCa4sBe1+ZU5Kmi4RJy+pjjjrpw==} + dev: false + /periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} dependencies: @@ -22303,6 +23630,53 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /react-aria@3.34.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-wSprEI5EojDFCm357MxnKAxJZN68OYIt6UH6N0KCo6MEUAVZMbhMSmGYjw/kLK4rI7KrbJDqGqUMQkwc93W9Ng==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0 + dependencies: + '@internationalized/string': 3.2.3 + '@react-aria/breadcrumbs': 3.5.16(react@18.2.0) + '@react-aria/button': 3.9.8(react@18.2.0) + '@react-aria/calendar': 3.5.11(react-dom@18.2.0)(react@18.2.0) + '@react-aria/checkbox': 3.14.6(react@18.2.0) + '@react-aria/combobox': 3.10.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/datepicker': 3.11.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/dialog': 3.5.17(react-dom@18.2.0)(react@18.2.0) + '@react-aria/dnd': 3.7.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/focus': 3.18.2(react@18.2.0) + '@react-aria/gridlist': 3.9.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/i18n': 3.12.2(react@18.2.0) + '@react-aria/interactions': 3.22.2(react@18.2.0) + '@react-aria/label': 3.7.11(react@18.2.0) + '@react-aria/link': 3.7.4(react@18.2.0) + '@react-aria/listbox': 3.13.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/menu': 3.15.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/meter': 3.4.16(react@18.2.0) + '@react-aria/numberfield': 3.11.6(react-dom@18.2.0)(react@18.2.0) + '@react-aria/overlays': 3.23.2(react-dom@18.2.0)(react@18.2.0) + '@react-aria/progress': 3.4.16(react@18.2.0) + '@react-aria/radio': 3.10.7(react@18.2.0) + '@react-aria/searchfield': 3.7.8(react@18.2.0) + '@react-aria/select': 3.14.9(react-dom@18.2.0)(react@18.2.0) + '@react-aria/selection': 3.19.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/separator': 3.4.2(react@18.2.0) + '@react-aria/slider': 3.7.11(react@18.2.0) + '@react-aria/ssr': 3.9.5(react@18.2.0) + '@react-aria/switch': 3.6.7(react@18.2.0) + '@react-aria/table': 3.15.3(react-dom@18.2.0)(react@18.2.0) + '@react-aria/tabs': 3.9.5(react-dom@18.2.0)(react@18.2.0) + '@react-aria/tag': 3.4.5(react-dom@18.2.0)(react@18.2.0) + '@react-aria/textfield': 3.14.8(react@18.2.0) + '@react-aria/tooltip': 3.7.7(react@18.2.0) + '@react-aria/utils': 3.25.2(react@18.2.0) + '@react-aria/visually-hidden': 3.8.15(react@18.2.0) + '@react-types/shared': 3.24.1(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /react-collapse@5.1.1(react@18.2.0): resolution: {integrity: sha512-k6cd7csF1o9LBhQ4AGBIdxB60SUEUMQDAnL2z1YvYNr9KoKr+nDkhN6FK7uGaBd/rYrYfrMpzpmJEIeHRYogBw==} peerDependencies: @@ -22679,6 +24053,29 @@ packages: tslib: 2.5.0 dev: false + /react-window-splitter@0.4.0(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yO9QjQ5WrJhnmxS78vEcdti6jNRtCKfDAt16O8fGT5/iz1OwfBJI6fYRW6o7tBUwRheELlQDWSw2s86v8wq4BA==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: '>=16' + react-dom: '>=16' + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.69)(react@18.2.0) + '@testing-library/jest-dom': 6.4.8 + '@window-splitter/state': 0.4.0 + '@xstate/react': 4.1.1(@types/react@18.2.69)(react@18.2.0)(xstate@5.17.4) + invariant: 2.2.4 + react: 18.2.0 + react-aria: 3.34.3(react-dom@18.2.0)(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) + reforest: 0.13.0(@types/react@18.2.69)(react@18.2.0) + universal-cookie: 7.2.0 + xstate: 5.17.4 + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + /react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -22820,6 +24217,19 @@ packages: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} dev: false + /reforest@0.13.0(@types/react@18.2.69)(react@18.2.0): + resolution: {integrity: sha512-f0It/s51f1UWCCCni0viULALDBhxWBPFnLmZRYtKcz4zYeNWqeNTdcnU/OpBry9tk+jyMQcH3MLK8UdzsAvA5w==} + peerDependencies: + react: '>=16.8' + dependencies: + performant-array-to-tree: 1.11.0 + react: 18.2.0 + zustand: 4.5.5(@types/react@18.2.69)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + dev: false + /regenerate-unicode-properties@10.1.0: resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} engines: {node: '>=4'} @@ -25386,6 +26796,13 @@ packages: unist-util-visit-parents: 5.1.1 dev: true + /universal-cookie@7.2.0: + resolution: {integrity: sha512-PvcyflJAYACJKr28HABxkGemML5vafHmiL4ICe3e+BEKXRMt0GaFLZhAwgv637kFFnnfiSJ8e6jknrKkMrU+PQ==} + dependencies: + '@types/cookie': 0.6.0 + cookie: 0.6.0 + dev: false + /universal-user-agent@6.0.1: resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} dev: false @@ -26585,6 +28002,10 @@ packages: engines: {node: '>=0.4.0'} dev: false + /xstate@5.17.4: + resolution: {integrity: sha512-KM2FYVOUJ04HlOO4TY3wEXqoYPR/XsDu+ewm+IWw0vilXqND0jVfvv04tEFwp8Mkk7I/oHXM8t1Ex9xJyUS4ZA==} + dev: false + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -26720,6 +28141,26 @@ packages: /zod@3.22.3: resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} + /zustand@4.5.5(@types/react@18.2.69)(react@18.2.0): + resolution: {integrity: sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0.6' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + dependencies: + '@types/react': 18.2.69 + react: 18.2.0 + use-sync-external-store: 1.2.2(react@18.2.0) + dev: false + /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: true From bb93adca35e762df207958f9af3913db06279ae2 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Fri, 23 Aug 2024 16:33:08 +0100 Subject: [PATCH 27/33] =?UTF-8?q?Callout=20if=20runs=20don=E2=80=99t=20sta?= =?UTF-8?q?rt=20right=20away=20now=20has=20some=20top=20margin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../route.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx index 71d91afa5..a59d43144 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx @@ -1142,7 +1142,7 @@ function ConnectedDevWarning() { return (
From 1e684852986f3b1e664c0b10ef95bdf6b8c5d7b7 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Fri, 23 Aug 2024 16:38:17 +0100 Subject: [PATCH 28/33] Small padding fix --- .../route.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx index a59d43144..06b99b81b 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx @@ -650,7 +650,7 @@ function TasksTreeView({ /> -
+
Date: Fri, 23 Aug 2024 17:47:06 +0100 Subject: [PATCH 29/33] styled the handle focus state --- apps/webapp/app/components/primitives/Resizable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/webapp/app/components/primitives/Resizable.tsx b/apps/webapp/app/components/primitives/Resizable.tsx index a03447fef..12d3d44e4 100644 --- a/apps/webapp/app/components/primitives/Resizable.tsx +++ b/apps/webapp/app/components/primitives/Resizable.tsx @@ -23,7 +23,7 @@ const ResizableHandle = ({ }) => ( div]:rotate-90", + "focus-visible:ring-ring group relative flex w-0.75 items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 hover:w-0.75 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-secondary/50 focus-visible:ring-offset-0 [&[data-panel-group-direction=vertical]>div]:rotate-90", className )} size="3px" From 1d3cd1d8e9e6e1e4c30436a0378e5683105a4e73 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Fri, 23 Aug 2024 17:47:24 +0100 Subject: [PATCH 30/33] Added isStaticAtRest prop to resizable panel --- .../route.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx index 06b99b81b..42ab57450 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx @@ -332,6 +332,7 @@ function TraceView({ run, trace, maximumLiveReloadingSetting, resizable }: Loade id={resizableSettings.parent.inspector.id} default={resizableSettings.parent.inspector.default} min={resizableSettings.parent.inspector.min} + isStaticAtRest > From 3952421f4a5f70d81ab64f4e73e61c552bfe1aee Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Fri, 23 Aug 2024 18:08:06 +0100 Subject: [PATCH 31/33] Updated resizable storybook --- apps/webapp/app/routes/storybook.resizable/route.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/webapp/app/routes/storybook.resizable/route.tsx b/apps/webapp/app/routes/storybook.resizable/route.tsx index f3f430f89..109b7b5af 100644 --- a/apps/webapp/app/routes/storybook.resizable/route.tsx +++ b/apps/webapp/app/routes/storybook.resizable/route.tsx @@ -12,10 +12,11 @@ export default function Story() {
From 4510fc0ed00e2ac753ef06cf0d46b8e043af2771 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Sat, 24 Aug 2024 12:10:08 +0100 Subject: [PATCH 32/33] Inline code blocks behave nicer when text wraps --- apps/webapp/app/components/code/InlineCode.tsx | 2 +- .../route.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/webapp/app/components/code/InlineCode.tsx b/apps/webapp/app/components/code/InlineCode.tsx index 8ff5b9916..120e86425 100644 --- a/apps/webapp/app/components/code/InlineCode.tsx +++ b/apps/webapp/app/components/code/InlineCode.tsx @@ -1,7 +1,7 @@ import { cn } from "~/utils/cn"; const inlineCode = - "px-1 py-0.5 rounded border border-charcoal-700 bg-charcoal-800 text-charcoal-200 font-mono"; + "px-1 py-0.5 rounded border border-charcoal-700 bg-charcoal-800 text-charcoal-200 font-mono text-wrap"; const variants = { "extra-extra-small": "text-xxs", diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx index 42ab57450..a8c4bafdb 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.runs.$runParam/route.tsx @@ -1148,7 +1148,7 @@ function ConnectedDevWarning() { isVisible ? "opacity-100" : "h-0 opacity-0" )} > - +
Runs usually start within 1 second in{" "} From 1d58ef97bced9e8c64847a0d1f80e721daf34040 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Thu, 29 Aug 2024 17:47:04 +0100 Subject: [PATCH 33/33] Min size for resizable panel on test page --- .../route.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.test/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.test/route.tsx index 7b1f7e43e..b16d11416 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.test/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.test/route.tsx @@ -117,7 +117,7 @@ export default function Page() {
) : hasSelectedEnvironment ? ( -
+
Select a task
@@ -136,7 +136,7 @@ export default function Page() {
- + @@ -157,7 +157,7 @@ function TaskSelector({ return (
-
+