From ea0108650b84feab7035c13c56c8d5c32871f062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 7 Jun 2026 14:51:18 +0200 Subject: [PATCH 01/61] Add tests --- bun.lock | 279 +++++++++++++++++++-- packages/effect-fc/package.json | 6 +- packages/effect-fc/test/Component.test.tsx | 133 ++++++++++ packages/effect-fc/vitest.config.ts | 9 + 4 files changed, 411 insertions(+), 16 deletions(-) create mode 100644 packages/effect-fc/test/Component.test.tsx create mode 100644 packages/effect-fc/vitest.config.ts diff --git a/bun.lock b/bun.lock index 2fb16f8..ccc7b94 100644 --- a/bun.lock +++ b/bun.lock @@ -36,12 +36,15 @@ }, "packages/effect-fc": { "name": "effect-fc", - "version": "0.2.6", + "version": "0.3.0", "dependencies": { "effect-lens": "^0.2.0", }, "devDependencies": { "@effect/platform-browser": "^0.76.0", + "@testing-library/react": "^16.3.0", + "jsdom": "^26.1.0", + "vitest": "^3.2.4", }, "peerDependencies": { "@types/react": "^19.2.0", @@ -113,6 +116,8 @@ "@algolia/requester-node-http": ["@algolia/requester-node-http@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0" } }, "sha512-xpwefe4fCOWnZgXCbkGpqQY6jgBSCf2hmgnySbyzZIccrv3SoashHKGPE4x6vVG+gdHrGciMTAcDo9HOZwH22Q=="], + "@asamuzakjp/css-color": ["@asamuzakjp/css-color@3.2.0", "", { "dependencies": { "@csstools/css-calc": "^2.1.3", "@csstools/css-color-parser": "^3.0.9", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw=="], + "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], "@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="], @@ -515,6 +520,58 @@ "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.27.7", "", { "os": "android", "cpu": "arm" }, "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.7", "", { "os": "android", "cpu": "arm64" }, "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.27.7", "", { "os": "android", "cpu": "x64" }, "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.7", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.7", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.7", "", { "os": "linux", "cpu": "arm" }, "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.7", "", { "os": "linux", "cpu": "ia32" }, "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.7", "", { "os": "linux", "cpu": "ppc64" }, "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.7", "", { "os": "linux", "cpu": "s390x" }, "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.7", "", { "os": "none", "cpu": "x64" }, "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.7", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.7", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.7", "", { "os": "sunos", "cpu": "x64" }, "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.7", "", { "os": "win32", "cpu": "ia32" }, "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="], + "@floating-ui/core": ["@floating-ui/core@1.7.5", "", { "dependencies": { "@floating-ui/utils": "^0.2.11" } }, "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ=="], "@floating-ui/dom": ["@floating-ui/dom@1.7.6", "", { "dependencies": { "@floating-ui/core": "^1.7.5", "@floating-ui/utils": "^0.2.11" } }, "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ=="], @@ -799,6 +856,56 @@ "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.61.1", "", { "os": "android", "cpu": "arm" }, "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.61.1", "", { "os": "android", "cpu": "arm64" }, "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.61.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.61.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.61.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.61.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.61.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.61.1", "", { "os": "linux", "cpu": "arm" }, "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.61.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.61.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.61.1", "", { "os": "linux", "cpu": "none" }, "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.61.1", "", { "os": "linux", "cpu": "none" }, "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.61.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.61.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.61.1", "", { "os": "linux", "cpu": "none" }, "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.61.1", "", { "os": "linux", "cpu": "none" }, "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.61.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.61.1", "", { "os": "linux", "cpu": "x64" }, "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.61.1", "", { "os": "linux", "cpu": "x64" }, "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.61.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.61.1", "", { "os": "none", "cpu": "arm64" }, "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.61.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.61.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.61.1", "", { "os": "win32", "cpu": "x64" }, "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.61.1", "", { "os": "win32", "cpu": "x64" }, "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw=="], + "@rspack/binding": ["@rspack/binding@1.7.11", "", { "optionalDependencies": { "@rspack/binding-darwin-arm64": "1.7.11", "@rspack/binding-darwin-x64": "1.7.11", "@rspack/binding-linux-arm64-gnu": "1.7.11", "@rspack/binding-linux-arm64-musl": "1.7.11", "@rspack/binding-linux-x64-gnu": "1.7.11", "@rspack/binding-linux-x64-musl": "1.7.11", "@rspack/binding-wasm32-wasi": "1.7.11", "@rspack/binding-win32-arm64-msvc": "1.7.11", "@rspack/binding-win32-ia32-msvc": "1.7.11", "@rspack/binding-win32-x64-msvc": "1.7.11" } }, "sha512-2MGdy2s2HimsDT444Bp5XnALzNRxuBNc7y0JzyuqKbHBywd4x2NeXyhWXXoxufaCFu5PBc9Qq9jyfjW2Aeh06Q=="], "@rspack/binding-darwin-arm64": ["@rspack/binding-darwin-arm64@1.7.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oduECiZVqbO5zlVw+q7Vy65sJFth99fWPTyucwvLJJtJkPL5n17Uiql2cYP6Ijn0pkqtf1SXgK8WjiKLG5bIig=="], @@ -947,6 +1054,10 @@ "@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.162.0", "", {}, "sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA=="], + "@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "picocolors": "1.1.1", "pretty-format": "^27.0.2" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="], + + "@testing-library/react": ["@testing-library/react@16.3.2", "", { "dependencies": { "@babel/runtime": "^7.12.5" }, "peerDependencies": { "@testing-library/dom": "^10.0.0", "@types/react": "^18.0.0 || ^19.0.0", "@types/react-dom": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g=="], + "@turbo/darwin-64": ["@turbo/darwin-64@2.9.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-jLjApWTSNd7JZ5JaLYfelW1ytnGQOvB7ivl+2RD1xQvJTbi8I9gBjzcga7tDZVPyaxpl10YTfJt3BrYXR18KDw=="], "@turbo/darwin-arm64": ["@turbo/darwin-arm64@2.9.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YPgrn+5HIGzrx0O2a631SV4MBQUe4W/DafMFUuBVgaU32PW9/OTT0ehviF0QSxTXuRJlHvW2eUTemddF5/spmw=="], @@ -963,18 +1074,24 @@ "@typed/id": ["@typed/id@0.17.2", "", { "peerDependencies": { "effect": "^3.14.7" } }, "sha512-z/Z14/moeu9x45IpkGaRwuvb+CQ3s3UCc/agcpZibTz1yPb3RgSDXx4rOHIuyb6hG6oNzqe9yY4GbbMq3Hb5Ug=="], + "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="], + "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="], "@types/bonjour": ["@types/bonjour@3.5.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ=="], "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], + "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], + "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="], "@types/connect-history-api-fallback": ["@types/connect-history-api-fallback@1.5.4", "", { "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" } }, "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw=="], "@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="], + "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + "@types/eslint": ["@types/eslint@9.6.1", "", { "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag=="], "@types/eslint-scope": ["@types/eslint-scope@3.7.7", "", { "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg=="], @@ -1059,6 +1176,20 @@ "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.2", "", { "dependencies": { "@rolldown/pluginutils": "^1.0.0" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg=="], + "@vitest/expect": ["@vitest/expect@3.2.6", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.6", "@vitest/utils": "3.2.6", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ=="], + + "@vitest/mocker": ["@vitest/mocker@3.2.6", "", { "dependencies": { "@vitest/spy": "3.2.6", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw=="], + + "@vitest/pretty-format": ["@vitest/pretty-format@3.2.6", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA=="], + + "@vitest/runner": ["@vitest/runner@3.2.6", "", { "dependencies": { "@vitest/utils": "3.2.6", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-HYcoSj1w5tcgUnzoF0HcyaAQjpA1gj9ftUJ7iSJSuipc02jW9gKkigwZbjFldAfYHA1fa8UZVRftdMY5msWM9Q=="], + + "@vitest/snapshot": ["@vitest/snapshot@3.2.6", "", { "dependencies": { "@vitest/pretty-format": "3.2.6", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw=="], + + "@vitest/spy": ["@vitest/spy@3.2.6", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg=="], + + "@vitest/utils": ["@vitest/utils@3.2.6", "", { "dependencies": { "@vitest/pretty-format": "3.2.6", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg=="], + "@webassemblyjs/ast": ["@webassemblyjs/ast@1.14.1", "", { "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ=="], "@webassemblyjs/floating-point-hex-parser": ["@webassemblyjs/floating-point-hex-parser@1.13.2", "", {}, "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA=="], @@ -1105,6 +1236,8 @@ "address": ["address@1.2.2", "", {}, "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA=="], + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], "ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], @@ -1121,7 +1254,7 @@ "ansi-html-community": ["ansi-html-community@0.0.8", "", { "bin": { "ansi-html": "bin/ansi-html" } }, "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw=="], - "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], @@ -1135,12 +1268,16 @@ "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], + "aria-query": ["aria-query@5.3.0", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="], + "array-flatten": ["array-flatten@1.1.1", "", {}, "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="], "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], "asn1js": ["asn1js@3.0.7", "", { "dependencies": { "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" } }, "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ=="], + "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], "autoprefixer": ["autoprefixer@10.4.27", "", { "dependencies": { "browserslist": "^4.28.1", "caniuse-lite": "^1.0.30001774", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA=="], @@ -1193,6 +1330,8 @@ "bytestreamjs": ["bytestreamjs@2.0.1", "", {}, "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ=="], + "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], + "cacheable-lookup": ["cacheable-lookup@7.0.0", "", {}, "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w=="], "cacheable-request": ["cacheable-request@10.2.14", "", { "dependencies": { "@types/http-cache-semantics": "^4.0.2", "get-stream": "^6.0.1", "http-cache-semantics": "^4.1.1", "keyv": "^4.5.3", "mimic-response": "^4.0.0", "normalize-url": "^8.0.0", "responselike": "^3.0.0" } }, "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ=="], @@ -1215,6 +1354,8 @@ "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], + "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], @@ -1227,6 +1368,8 @@ "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], + "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], + "cheerio": ["cheerio@1.0.0-rc.12", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "htmlparser2": "^8.0.1", "parse5": "^7.0.0", "parse5-htmlparser2-tree-adapter": "^7.0.0" } }, "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q=="], "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], @@ -1343,16 +1486,24 @@ "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="], + "cssstyle": ["cssstyle@4.6.0", "", { "dependencies": { "@asamuzakjp/css-color": "^3.2.0", "rrweb-cssom": "^0.8.0" } }, "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg=="], + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + "data-urls": ["data-urls@5.0.0", "", { "dependencies": { "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0" } }, "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg=="], + "debounce": ["debounce@1.2.1", "", {}, "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="], "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="], + "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], + "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], + "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], @@ -1393,6 +1544,8 @@ "docs": ["docs@workspace:packages/docs"], + "dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="], + "dom-converter": ["dom-converter@0.2.0", "", { "dependencies": { "utila": "~0.4" } }, "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA=="], "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], @@ -1435,7 +1588,7 @@ "enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="], - "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], @@ -1451,6 +1604,8 @@ "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], + "esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], "escape-goat": ["escape-goat@4.0.0", "", {}, "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg=="], @@ -1497,6 +1652,8 @@ "execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], + "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], + "express": ["express@4.22.1", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.3", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g=="], "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], @@ -1629,6 +1786,8 @@ "hpack.js": ["hpack.js@2.1.6", "", { "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", "readable-stream": "^2.0.1", "wbuf": "^1.1.0" } }, "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ=="], + "html-encoding-sniffer": ["html-encoding-sniffer@4.0.0", "", { "dependencies": { "whatwg-encoding": "^3.1.1" } }, "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ=="], + "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], "html-minifier-terser": ["html-minifier-terser@7.2.0", "", { "dependencies": { "camel-case": "^4.1.2", "clean-css": "~5.3.2", "commander": "^10.0.0", "entities": "^4.4.0", "param-case": "^3.0.4", "relateurl": "^0.2.7", "terser": "^5.15.1" }, "bin": { "html-minifier-terser": "cli.js" } }, "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA=="], @@ -1651,15 +1810,19 @@ "http-proxy": ["http-proxy@1.18.1", "", { "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", "requires-port": "^1.0.0" } }, "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ=="], + "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + "http-proxy-middleware": ["http-proxy-middleware@2.0.9", "", { "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", "is-glob": "^4.0.1", "is-plain-obj": "^3.0.0", "micromatch": "^4.0.2" }, "peerDependencies": { "@types/express": "^4.17.13" }, "optionalPeers": ["@types/express"] }, "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q=="], "http2-wrapper": ["http2-wrapper@2.2.1", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" } }, "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ=="], + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + "human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="], "hyperdyperid": ["hyperdyperid@1.2.0", "", {}, "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A=="], - "iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], "icss-utils": ["icss-utils@5.1.0", "", { "peerDependencies": { "postcss": "^8.1.0" } }, "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA=="], @@ -1731,6 +1894,8 @@ "is-plain-object": ["is-plain-object@2.0.4", "", { "dependencies": { "isobject": "^3.0.1" } }, "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og=="], + "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="], + "is-regexp": ["is-regexp@1.0.0", "", {}, "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA=="], "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], @@ -1761,6 +1926,8 @@ "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "jsdom": ["jsdom@26.1.0", "", { "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", "decimal.js": "^10.5.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.6", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.16", "parse5": "^7.2.1", "rrweb-cssom": "^0.8.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^5.1.1", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.1.1", "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg=="], + "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], @@ -1831,12 +1998,16 @@ "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], + "loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="], + "lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="], "lowercase-keys": ["lowercase-keys@3.0.0", "", {}, "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ=="], "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], "markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="], @@ -2031,6 +2202,8 @@ "null-loader": ["null-loader@4.0.1", "", { "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" }, "peerDependencies": { "webpack": "^4.0.0 || ^5.0.0" } }, "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg=="], + "nwsapi": ["nwsapi@2.2.24", "", {}, "sha512-7YRhZ3jS45LwmSCT4b2sVFHt/WuovaktDU07QrtOBY2PXskss5a9jfmR9jptyumwXST+rFjrmppMY1KT/yn35A=="], + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], @@ -2101,6 +2274,8 @@ "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + "pathval": ["pathval@2.0.1", "", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="], + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], @@ -2245,6 +2420,8 @@ "pretty-error": ["pretty-error@4.0.0", "", { "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" } }, "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw=="], + "pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], + "pretty-time": ["pretty-time@1.1.0", "", {}, "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA=="], "prism-react-renderer": ["prism-react-renderer@2.4.1", "", { "dependencies": { "@types/prismjs": "^1.26.0", "clsx": "^2.0.0" }, "peerDependencies": { "react": ">=16.0.0" } }, "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig=="], @@ -2393,6 +2570,10 @@ "rolldown": ["rolldown@1.0.3", "", { "dependencies": { "@oxc-project/types": "=0.133.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.3", "@rolldown/binding-darwin-arm64": "1.0.3", "@rolldown/binding-darwin-x64": "1.0.3", "@rolldown/binding-freebsd-x64": "1.0.3", "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", "@rolldown/binding-linux-arm64-gnu": "1.0.3", "@rolldown/binding-linux-arm64-musl": "1.0.3", "@rolldown/binding-linux-ppc64-gnu": "1.0.3", "@rolldown/binding-linux-s390x-gnu": "1.0.3", "@rolldown/binding-linux-x64-gnu": "1.0.3", "@rolldown/binding-linux-x64-musl": "1.0.3", "@rolldown/binding-openharmony-arm64": "1.0.3", "@rolldown/binding-wasm32-wasi": "1.0.3", "@rolldown/binding-win32-arm64-msvc": "1.0.3", "@rolldown/binding-win32-x64-msvc": "1.0.3" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g=="], + "rollup": ["rollup@4.61.1", "", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.61.1", "@rollup/rollup-android-arm64": "4.61.1", "@rollup/rollup-darwin-arm64": "4.61.1", "@rollup/rollup-darwin-x64": "4.61.1", "@rollup/rollup-freebsd-arm64": "4.61.1", "@rollup/rollup-freebsd-x64": "4.61.1", "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", "@rollup/rollup-linux-arm-musleabihf": "4.61.1", "@rollup/rollup-linux-arm64-gnu": "4.61.1", "@rollup/rollup-linux-arm64-musl": "4.61.1", "@rollup/rollup-linux-loong64-gnu": "4.61.1", "@rollup/rollup-linux-loong64-musl": "4.61.1", "@rollup/rollup-linux-ppc64-gnu": "4.61.1", "@rollup/rollup-linux-ppc64-musl": "4.61.1", "@rollup/rollup-linux-riscv64-gnu": "4.61.1", "@rollup/rollup-linux-riscv64-musl": "4.61.1", "@rollup/rollup-linux-s390x-gnu": "4.61.1", "@rollup/rollup-linux-x64-gnu": "4.61.1", "@rollup/rollup-linux-x64-musl": "4.61.1", "@rollup/rollup-openbsd-x64": "4.61.1", "@rollup/rollup-openharmony-arm64": "4.61.1", "@rollup/rollup-win32-arm64-msvc": "4.61.1", "@rollup/rollup-win32-ia32-msvc": "4.61.1", "@rollup/rollup-win32-x64-gnu": "4.61.1", "@rollup/rollup-win32-x64-msvc": "4.61.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA=="], + + "rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="], + "rtlcss": ["rtlcss@4.3.0", "", { "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0", "postcss": "^8.4.21", "strip-json-comments": "^3.1.1" }, "bin": { "rtlcss": "bin/rtlcss.js" } }, "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig=="], "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="], @@ -2405,6 +2586,8 @@ "sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], + "saxes": ["saxes@6.0.0", "", { "dependencies": { "xmlchars": "^2.2.0" } }, "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA=="], + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], "schema-dts": ["schema-dts@1.1.5", "", {}, "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg=="], @@ -2459,6 +2642,8 @@ "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], "sirv": ["sirv@2.0.4", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ=="], @@ -2493,6 +2678,8 @@ "srcset": ["srcset@4.0.0", "", {}, "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw=="], + "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], @@ -2513,6 +2700,8 @@ "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + "strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="], + "style-to-js": ["style-to-js@1.1.21", "", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="], "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], @@ -2529,6 +2718,8 @@ "swc-loader": ["swc-loader@0.2.7", "", { "dependencies": { "@swc/counter": "^0.1.3" }, "peerDependencies": { "@swc/core": "^1.2.147", "webpack": ">=2" } }, "sha512-nwYWw3Fh9ame3Rtm7StS9SBLpHRRnYcK7bnpF3UKZmesAK0gw2/ADvlURFAINmPvKtDLzp+GBiP9yLoEjg6S9w=="], + "symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="], + "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="], "tapable": ["tapable@2.3.2", "", {}, "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA=="], @@ -2545,16 +2736,32 @@ "tiny-warning": ["tiny-warning@1.0.3", "", {}, "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="], + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + + "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], "tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="], + "tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], + + "tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="], + + "tldts": ["tldts@6.1.86", "", { "dependencies": { "tldts-core": "^6.1.86" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ=="], + + "tldts-core": ["tldts-core@6.1.86", "", {}, "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA=="], + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], + "tough-cookie": ["tough-cookie@5.1.2", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A=="], + + "tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="], + "tree-dump": ["tree-dump@1.1.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA=="], "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], @@ -2645,12 +2852,20 @@ "vite": ["vite@8.0.16", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", "rolldown": "1.0.3", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.18", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw=="], + "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], + + "vitest": ["vitest@3.2.6", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.6", "@vitest/mocker": "3.2.6", "@vitest/pretty-format": "^3.2.6", "@vitest/runner": "3.2.6", "@vitest/snapshot": "3.2.6", "@vitest/spy": "3.2.6", "@vitest/utils": "3.2.6", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.6", "@vitest/ui": "3.2.6", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw=="], + + "w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="], + "watchpack": ["watchpack@2.5.1", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg=="], "wbuf": ["wbuf@1.7.3", "", { "dependencies": { "minimalistic-assert": "^1.0.0" } }, "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA=="], "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], + "webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], + "webpack": ["webpack@5.105.4", "", { "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.20.0", "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "terser-webpack-plugin": "^5.3.17", "watchpack": "^2.5.1", "webpack-sources": "^3.3.4" }, "bin": { "webpack": "bin/webpack.js" } }, "sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw=="], "webpack-bundle-analyzer": ["webpack-bundle-analyzer@4.10.2", "", { "dependencies": { "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", "commander": "^7.2.0", "debounce": "^1.2.1", "escape-string-regexp": "^4.0.0", "gzip-size": "^6.0.0", "html-escaper": "^2.0.2", "opener": "^1.5.2", "picocolors": "^1.0.0", "sirv": "^2.0.3", "ws": "^7.3.1" }, "bin": { "webpack-bundle-analyzer": "lib/bin/analyzer.js" } }, "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw=="], @@ -2671,8 +2886,16 @@ "websocket-extensions": ["websocket-extensions@0.1.4", "", {}, "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="], + "whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="], + + "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], + + "whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="], + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + "widest-line": ["widest-line@4.0.1", "", { "dependencies": { "string-width": "^5.0.1" } }, "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig=="], "wildcard": ["wildcard@2.0.1", "", {}, "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ=="], @@ -2681,7 +2904,7 @@ "write-file-atomic": ["write-file-atomic@3.0.3", "", { "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q=="], - "ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], + "ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], @@ -2689,6 +2912,10 @@ "xml-js": ["xml-js@1.6.11", "", { "dependencies": { "sax": "^1.2.4" }, "bin": { "xml-js": "./bin/cli.js" } }, "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g=="], + "xml-name-validator": ["xml-name-validator@5.0.0", "", {}, "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg=="], + + "xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="], + "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], @@ -2697,6 +2924,8 @@ "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + "@asamuzakjp/css-color/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], @@ -2741,6 +2970,8 @@ "@rspack/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" } }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="], + "@svgr/hast-util-to-babel-ast/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "@types/react-router/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], "@types/react-router-config/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], @@ -2759,6 +2990,8 @@ "body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], + "boxen/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], "cheerio-select/css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], @@ -2799,6 +3032,8 @@ "docs/react-dom": ["react-dom@19.2.5", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.5" } }, "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag=="], + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "dot-prop/is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], "esrecurse/estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], @@ -2823,8 +3058,12 @@ "html-minifier-terser/commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="], + "html-minifier-terser/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "html-webpack-plugin/html-minifier-terser": ["html-minifier-terser@6.1.0", "", { "dependencies": { "camel-case": "^4.1.2", "clean-css": "^5.2.2", "commander": "^8.3.0", "he": "^1.2.0", "param-case": "^3.0.4", "relateurl": "^0.2.7", "terser": "^5.10.0" }, "bin": { "html-minifier-terser": "cli.js" } }, "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw=="], + "htmlparser2/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "http-proxy-middleware/is-plain-obj": ["is-plain-obj@3.0.0", "", {}, "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA=="], "is-inside-container/is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], @@ -2961,8 +3200,6 @@ "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], - "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], - "postcss-calc/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], "postcss-discard-unused/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], @@ -2975,10 +3212,16 @@ "postcss-unique-selectors/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + + "pretty-format/react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="], + "proxy-addr/ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], "raw-body/bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + "raw-body/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], + "rc/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], @@ -2989,6 +3232,8 @@ "renderkid/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "rollup/@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], + "rtlcss/postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -3007,6 +3252,10 @@ "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], + "stylehacks/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], "svgo/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], @@ -3023,8 +3272,16 @@ "url-loader/schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="], + "vite-node/es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + + "vite-node/vite": ["vite@7.3.5", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww=="], + + "vitest/vite": ["vite@7.3.5", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww=="], + "webpack-bundle-analyzer/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], + "webpack-bundle-analyzer/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], + "webpack-dev-middleware/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], "webpack-dev-middleware/range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], @@ -3033,8 +3290,6 @@ "webpack-dev-server/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], - "webpack-dev-server/ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], - "webpackbar/ansis": ["ansis@3.17.0", "", {}, "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg=="], "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], @@ -3111,8 +3366,6 @@ "renderkid/htmlparser2/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="], - "renderkid/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "rtlcss/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], @@ -3141,10 +3394,6 @@ "@docusaurus/core/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - - "cli-table3/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "css-select/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="], "file-loader/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], diff --git a/packages/effect-fc/package.json b/packages/effect-fc/package.json index 27d6a09..f729dad 100644 --- a/packages/effect-fc/package.json +++ b/packages/effect-fc/package.json @@ -32,13 +32,17 @@ "build": "tsc", "lint:tsc": "tsc --noEmit", "lint:biome": "biome lint", + "test": "vitest run", "pack": "npm pack", "clean:cache": "rm -rf .turbo tsconfig.tsbuildinfo", "clean:dist": "rm -rf dist", "clean:modules": "rm -rf node_modules" }, "devDependencies": { - "@effect/platform-browser": "^0.76.0" + "@effect/platform-browser": "^0.76.0", + "@testing-library/react": "^16.3.0", + "jsdom": "^26.1.0", + "vitest": "^3.2.4" }, "peerDependencies": { "@types/react": "^19.2.0", diff --git a/packages/effect-fc/test/Component.test.tsx b/packages/effect-fc/test/Component.test.tsx new file mode 100644 index 0000000..7a7658b --- /dev/null +++ b/packages/effect-fc/test/Component.test.tsx @@ -0,0 +1,133 @@ +import { render, screen, waitFor } from "@testing-library/react" +import { Effect, Layer } from "effect" +import { describe, expect, it, vi } from "vitest" +import * as Component from "../src/Component.js" +import * as ReactRuntime from "../src/ReactRuntime.js" + + +describe("Component", () => { + it("runs useOnMount only once across rerenders", async () => { + const onMount = vi.fn(() => Effect.succeed("mounted")) + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await Effect.runPromise(runtime.runtime.runtimeEffect) + + const Probe = Component.makeUntraced("UseOnMountProbe")(function*() { + const value = yield* Component.useOnMount(onMount) + return
{value}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("mounted") + expect(onMount).toHaveBeenCalledTimes(1) + + view.rerender( + + + + ) + expect(await screen.findByText("mounted")).toBeTruthy() + expect(onMount).toHaveBeenCalledTimes(1) + + view.unmount() + await Effect.runPromise(runtime.runtime.disposeEffect) + }) + + it("recomputes useOnChange only when dependencies change", async () => { + const onChange = vi.fn((value: number) => Effect.succeed(`value:${value}`)) + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await Effect.runPromise(runtime.runtime.runtimeEffect) + + const Probe = Component.makeUntraced("UseOnChangeProbe")(function*(props: { readonly value: number }) { + const result = yield* Component.useOnChange(() => onChange(props.value), [props.value], { + finalizerExecutionDebounce: 0, + }) + + return
{result}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("value:1") + expect(onChange).toHaveBeenCalledTimes(1) + + view.rerender( + + + + ) + + expect(await screen.findByText("value:1")).toBeTruthy() + expect(onChange).toHaveBeenCalledTimes(1) + + view.rerender( + + + + ) + + await screen.findByText("value:2") + expect(onChange).toHaveBeenCalledTimes(2) + + view.unmount() + await Effect.runPromise(runtime.runtime.disposeEffect) + }) + + it("closes the previous scope on dependency changes and unmount", async () => { + const cleanup = vi.fn() + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await Effect.runPromise(runtime.runtime.runtimeEffect) + + const Probe = Component.makeUntraced("ScopeCleanupProbe")(function*(props: { readonly value: string }) { + const result = yield* Component.useOnChange( + () => Effect.gen(function*() { + yield* Effect.addFinalizer(() => Effect.sync(() => cleanup(props.value))) + return props.value + }), + [props.value], + { finalizerExecutionDebounce: 0 }, + ) + + return
{result}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + expect(cleanup).not.toHaveBeenCalled() + + view.rerender( + + + + ) + + await screen.findByText("second") + await waitFor(() => expect(cleanup).toHaveBeenCalledWith("first")) + expect(cleanup).toHaveBeenCalledTimes(1) + + view.unmount() + + await waitFor(() => expect(cleanup).toHaveBeenCalledWith("second")) + expect(cleanup).toHaveBeenCalledTimes(2) + await Effect.runPromise(runtime.runtime.disposeEffect) + }) +}) diff --git a/packages/effect-fc/vitest.config.ts b/packages/effect-fc/vitest.config.ts new file mode 100644 index 0000000..cec0e39 --- /dev/null +++ b/packages/effect-fc/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config" + + +export default defineConfig({ + test: { + environment: "jsdom", + include: ["test/**/*.test.ts?(x)"], + }, +}) -- 2.52.0 From fcb29c0d76508b89bda60f04a72592e102e77df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 7 Jun 2026 15:01:07 +0200 Subject: [PATCH 02/61] Add tests --- packages/effect-fc/test/Component.test.tsx | 225 ++++++++++++++++++++- 1 file changed, 223 insertions(+), 2 deletions(-) diff --git a/packages/effect-fc/test/Component.test.tsx b/packages/effect-fc/test/Component.test.tsx index 7a7658b..eb846d9 100644 --- a/packages/effect-fc/test/Component.test.tsx +++ b/packages/effect-fc/test/Component.test.tsx @@ -1,10 +1,17 @@ import { render, screen, waitFor } from "@testing-library/react" -import { Effect, Layer } from "effect" -import { describe, expect, it, vi } from "vitest" +import { Context, Effect, Layer } from "effect" +import * as React from "react" +import { afterEach, describe, expect, it, vi } from "vitest" import * as Component from "../src/Component.js" import * as ReactRuntime from "../src/ReactRuntime.js" +class ValueService extends Context.Tag("ValueService")() {} + +afterEach(() => { + vi.useRealTimers() +}) + describe("Component", () => { it("runs useOnMount only once across rerenders", async () => { const onMount = vi.fn(() => Effect.succeed("mounted")) @@ -130,4 +137,218 @@ describe("Component", () => { expect(cleanup).toHaveBeenCalledTimes(2) await Effect.runPromise(runtime.runtime.disposeEffect) }) + + it("runs useReactEffect setup and cleanup when dependencies change", async () => { + const lifecycle = vi.fn<(message: string) => void>() + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await Effect.runPromise(runtime.runtime.runtimeEffect) + + const Probe = Component.makeUntraced("UseReactEffectProbe")(function*(props: { readonly value: string }) { + yield* Component.useReactEffect(() => + Effect.gen(function*() { + yield* Effect.sync(() => lifecycle(`mount:${props.value}`)) + yield* Effect.addFinalizer(() => Effect.sync(() => lifecycle(`cleanup:${props.value}`))) + }), + [props.value]) + + return
{props.value}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + await waitFor(() => expect(lifecycle).toHaveBeenCalledWith("mount:first")) + + view.rerender( + + + + ) + + await screen.findByText("second") + await waitFor(() => expect(lifecycle).toHaveBeenCalledWith("cleanup:first")) + await waitFor(() => expect(lifecycle).toHaveBeenCalledWith("mount:second")) + + view.unmount() + + await waitFor(() => expect(lifecycle).toHaveBeenCalledWith("cleanup:second")) + expect(lifecycle.mock.calls.map(([message]) => message)).toEqual([ + "mount:first", + "cleanup:first", + "mount:second", + "cleanup:second", + ]) + await Effect.runPromise(runtime.runtime.disposeEffect) + }) + + it("keeps useCallbackSync stable until dependencies change", async () => { + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await Effect.runPromise(runtime.runtime.runtimeEffect) + const seenCallbacks: Array<(value: number) => string> = [] + + const Probe = Component.makeUntraced("UseCallbackSyncProbe")(function*(props: { readonly prefix: string }) { + const callback = yield* Component.useCallbackSync( + (value: number) => Effect.succeed(`${props.prefix}:${value}`), + [props.prefix], + ) + + yield* Component.useOnMount(() => Effect.sync(() => { + seenCallbacks.push(callback) + })) + + React.useEffect(() => { + seenCallbacks.push(callback) + }, [callback]) + + return
{callback(1)}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("a:1") + expect(seenCallbacks).toHaveLength(2) + expect(seenCallbacks[0]).toBe(seenCallbacks[1]) + expect(seenCallbacks[0]?.(2)).toBe("a:2") + + view.rerender( + + + + ) + + await screen.findByText("a:1") + expect(seenCallbacks).toHaveLength(2) + + view.rerender( + + + + ) + + await screen.findByText("b:1") + await waitFor(() => expect(seenCallbacks).toHaveLength(3)) + expect(seenCallbacks[2]).not.toBe(seenCallbacks[1]) + expect(seenCallbacks[2]?.(2)).toBe("b:2") + + view.unmount() + await Effect.runPromise(runtime.runtime.disposeEffect) + }) + + it("delays cleanup according to finalizerExecutionDebounce", async () => { + const cleanup = vi.fn() + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await Effect.runPromise(runtime.runtime.runtimeEffect) + + const Probe = Component.makeUntraced("DebouncedCleanupProbe")(function*(props: { readonly value: string }) { + const result = yield* Component.useOnChange( + () => Effect.gen(function*() { + yield* Effect.addFinalizer(() => Effect.sync(() => cleanup(props.value))) + return props.value + }), + [props.value], + { finalizerExecutionDebounce: "20 millis" }, + ) + + return
{result}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + + view.rerender( + + + + ) + + await screen.findByText("second") + expect(cleanup).not.toHaveBeenCalled() + + await new Promise(resolve => setTimeout(resolve, 5)) + expect(cleanup).not.toHaveBeenCalled() + + await waitFor(() => expect(cleanup).toHaveBeenCalledWith("first"), { timeout: 100 }) + + view.unmount() + await waitFor(() => expect(cleanup).toHaveBeenCalledWith("second"), { timeout: 100 }) + await Effect.runPromise(runtime.runtime.disposeEffect) + }) + + it("does not remount a component when only nonReactiveTags change", async () => { + const mounts = vi.fn() + const unmounts = vi.fn() + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await Effect.runPromise(runtime.runtime.runtimeEffect) + + const SubComponent = Component.makeUntraced("NonReactiveSubComponent")(function*() { + const service = yield* ValueService + + yield* Component.useOnMount(() => Effect.gen(function*() { + yield* Effect.sync(() => mounts()) + yield* Effect.addFinalizer(() => Effect.sync(() => unmounts())) + })) + + return
{service.value}
+ }).pipe( + Component.withOptions({ nonReactiveTags: [ValueService] }) + ) + + const Parent = Component.makeUntraced("NonReactiveParent")(function*(props: { readonly value: string }) { + const serviceLayer = React.useMemo( + () => Layer.succeed(ValueService, { value: props.value }), + [props.value], + ) + const context = yield* Component.useContextFromLayer(serviceLayer, { + finalizerExecutionDebounce: 0, + }) + const Child = yield* Effect.provide(SubComponent.use, context) + + return + }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + expect(mounts).toHaveBeenCalledTimes(1) + expect(unmounts).not.toHaveBeenCalled() + + view.rerender( + + + + ) + + await screen.findByText("second") + expect(mounts).toHaveBeenCalledTimes(1) + expect(unmounts).not.toHaveBeenCalled() + + view.unmount() + await waitFor(() => expect(unmounts).toHaveBeenCalledTimes(1)) + await Effect.runPromise(runtime.runtime.disposeEffect) + }) }) -- 2.52.0 From 7638324f2f8046eeb5b274a51ba3edf5f77140b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 7 Jun 2026 15:10:26 +0200 Subject: [PATCH 03/61] Add tests --- packages/effect-fc/test/Lens.test.tsx | 166 ++++++++++++++++++ packages/effect-fc/test/Subscribable.test.tsx | 130 ++++++++++++++ 2 files changed, 296 insertions(+) create mode 100644 packages/effect-fc/test/Lens.test.tsx create mode 100644 packages/effect-fc/test/Subscribable.test.tsx diff --git a/packages/effect-fc/test/Lens.test.tsx b/packages/effect-fc/test/Lens.test.tsx new file mode 100644 index 0000000..4728bfc --- /dev/null +++ b/packages/effect-fc/test/Lens.test.tsx @@ -0,0 +1,166 @@ +import { fireEvent, render, screen, waitFor } from "@testing-library/react" +import { Effect, Layer, SubscriptionRef } from "effect" +import { Lens } from "effect-lens" +import * as React from "react" +import { describe, expect, it } from "vitest" +import * as Component from "../src/Component.js" +import * as LensModule from "../src/Lens.js" +import * as ReactRuntime from "../src/ReactRuntime.js" + + +const makeRuntime = async () => { + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await Effect.runPromise(runtime.runtime.runtimeEffect) + + return { + runtime, + effectRuntime, + dispose: () => Effect.runPromise(runtime.runtime.disposeEffect), + } +} + +describe("Lens", () => { + it("useState stays in sync with lens updates in both directions", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + const ref = await Effect.runPromise(SubscriptionRef.make(0)) + const lens = Lens.fromSubscriptionRef(ref) + + const Probe = Component.makeUntraced("LensUseStateProbe")(function*() { + const [value, setValue] = yield* LensModule.useState(lens) + + return ( + <> +
{value}
+ + + ) + }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("0") + + await Effect.runPromise(Lens.set(lens, 5)) + await screen.findByText("5") + + fireEvent.click(screen.getByRole("button", { name: "increment" })) + await screen.findByText("6") + expect(await Effect.runPromise(Lens.get(lens))).toBe(6) + + view.unmount() + await dispose() + }) + + it("useState respects the provided equivalence when subscribing to lens changes", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + const ref = await Effect.runPromise(SubscriptionRef.make({ id: 1, label: "first" })) + const lens = Lens.fromSubscriptionRef(ref) + + const Probe = Component.makeUntraced("LensUseStateEquivalenceProbe")(function*() { + const [value] = yield* LensModule.useState(lens, { + equivalence: (self, that) => self.id === that.id, + }) + + return
{value.label}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + + await Effect.runPromise(Lens.set(lens, { id: 1, label: "ignored" })) + await waitFor(() => expect(screen.getByText("first")).toBeTruthy()) + expect(screen.queryByText("ignored")).toBeNull() + + await Effect.runPromise(Lens.set(lens, { id: 2, label: "updated" })) + await screen.findByText("updated") + + view.unmount() + await dispose() + }) + + it("useFromReactState writes React state changes into the returned lens", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + let lens: Lens.Lens | undefined + + const Probe = Component.makeUntraced("LensUseFromReactStateProbe")(function*() { + const [value, setValue] = React.useState("hello") + const reactLens = yield* LensModule.useFromReactState([value, setValue]) + + yield* Component.useOnMount(() => Effect.sync(() => { + lens = reactLens + })) + + return + }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("hello") + await waitFor(() => expect(lens).toBeDefined()) + + fireEvent.click(screen.getByRole("button", { name: "hello" })) + await screen.findByText("hello!") + await waitFor(async () => expect(await Effect.runPromise(Lens.get(lens!))).toBe("hello!")) + + view.unmount() + await dispose() + }) + + it("useFromReactState respects equivalence when lens updates flow back into React state", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + let lens: Lens.Lens<{ readonly id: number; readonly label: string }, never, never, never, never> | undefined + + const Probe = Component.makeUntraced("LensUseFromReactStateEquivalenceProbe")(function*() { + const [value, setValue] = React.useState({ id: 1, label: "first" }) + const reactLens = yield* LensModule.useFromReactState([value, setValue], { + equivalence: (self, that) => self.id === that.id, + }) + + yield* Component.useOnMount(() => Effect.sync(() => { + lens = reactLens + })) + + return
{value.label}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + await waitFor(() => expect(lens).toBeDefined()) + + await Effect.runPromise(Lens.set(lens!, { id: 1, label: "ignored" })) + await waitFor(() => expect(screen.getByText("first")).toBeTruthy()) + expect(screen.queryByText("ignored")).toBeNull() + + await Effect.runPromise(Lens.set(lens!, { id: 2, label: "updated" })) + await screen.findByText("updated") + + view.unmount() + await dispose() + }) +}) diff --git a/packages/effect-fc/test/Subscribable.test.tsx b/packages/effect-fc/test/Subscribable.test.tsx new file mode 100644 index 0000000..eec6289 --- /dev/null +++ b/packages/effect-fc/test/Subscribable.test.tsx @@ -0,0 +1,130 @@ +import { render, screen, waitFor } from "@testing-library/react" +import { Effect, Fiber, Layer, Stream, SubscriptionRef } from "effect" +import { Lens } from "effect-lens" +import * as React from "react" +import { describe, expect, it } from "vitest" +import * as Component from "../src/Component.js" +import * as ReactRuntime from "../src/ReactRuntime.js" +import * as SubscribableModule from "../src/Subscribable.js" + + +const makeRuntime = async () => { + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await Effect.runPromise(runtime.runtime.runtimeEffect) + + return { + runtime, + effectRuntime, + dispose: () => Effect.runPromise(runtime.runtime.disposeEffect), + } +} + +describe("Subscribable", () => { + it("zipLatestAll reads current values from all inputs", async () => { + const leftRef = await Effect.runPromise(SubscriptionRef.make(1)) + const rightRef = await Effect.runPromise(SubscriptionRef.make("a")) + const left = Lens.fromSubscriptionRef(leftRef) + const right = Lens.fromSubscriptionRef(rightRef) + + const zipped = SubscribableModule.zipLatestAll(left, right) + + expect(await Effect.runPromise(zipped.get)).toEqual([1, "a"]) + }) + + it("zipLatestAll emits updates when any input changes", async () => { + const leftRef = await Effect.runPromise(SubscriptionRef.make(1)) + const rightRef = await Effect.runPromise(SubscriptionRef.make("a")) + const left = Lens.fromSubscriptionRef(leftRef) + const right = Lens.fromSubscriptionRef(rightRef) + + const zipped = SubscribableModule.zipLatestAll(left, right) + const values: Array = [] + + const collector = Effect.runFork(Effect.scoped(zipped.changes.pipe( + Stream.runForEach(value => Effect.sync(() => { + values.push(value as readonly [number, string]) + })), + ))) + + await Effect.runPromise(Lens.set(left, 2)) + await waitFor(() => expect(values).toContainEqual([2, "a"])) + + await Effect.runPromise(Lens.set(right, "b")) + await waitFor(() => expect(values).toContainEqual([2, "b"])) + + Fiber.interruptFork(collector) + }) + + it("useAll returns the latest values and rerenders when any input changes", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + const countRef = await Effect.runPromise(SubscriptionRef.make(1)) + const labelRef = await Effect.runPromise(SubscriptionRef.make("a")) + const count = Lens.fromSubscriptionRef(countRef) + const label = Lens.fromSubscriptionRef(labelRef) + + const Probe = Component.makeUntraced("SubscribableUseAllProbe")(function*() { + const [currentCount, currentLabel] = yield* SubscribableModule.useAll([count, label]) + + return
{`${currentCount}:${currentLabel}`}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("1:a") + + await Effect.runPromise(Lens.set(count, 2)) + await screen.findByText("2:a") + + await Effect.runPromise(Lens.set(label, "b")) + await screen.findByText("2:b") + + view.unmount() + await dispose() + }) + + it("useAll respects the provided equivalence when processing updates", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + const itemRef = await Effect.runPromise(SubscriptionRef.make({ id: 1, label: "first" })) + const flagRef = await Effect.runPromise(SubscriptionRef.make(true)) + const item = Lens.fromSubscriptionRef(itemRef) + const flag = Lens.fromSubscriptionRef(flagRef) + + const Probe = Component.makeUntraced("SubscribableUseAllEquivalenceProbe")(function*() { + const [currentItem, currentFlag] = yield* SubscribableModule.useAll([item, flag], { + equivalence: ([selfItem, selfFlag], [thatItem, thatFlag]) => + selfItem.id === thatItem.id && selfFlag === thatFlag, + }) + + return
{`${currentItem.label}:${currentFlag ? "on" : "off"}`}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first:on") + + await Effect.runPromise(Lens.set(item, { id: 1, label: "ignored" })) + await waitFor(() => expect(screen.getByText("first:on")).toBeTruthy()) + expect(screen.queryByText("ignored:on")).toBeNull() + + await Effect.runPromise(Lens.set(flag, false)) + await screen.findByText("ignored:off") + + await Effect.runPromise(Lens.set(item, { id: 2, label: "updated" })) + await screen.findByText("updated:off") + + view.unmount() + await dispose() + }) +}) -- 2.52.0 From 658e6bb8ea6ccf37e763b9cc9a2cae2b9f75d00d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 7 Jun 2026 15:15:57 +0200 Subject: [PATCH 04/61] Fix tests --- packages/effect-fc/test/Lens.test.tsx | 11 +++++------ packages/effect-fc/test/Subscribable.test.tsx | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/effect-fc/test/Lens.test.tsx b/packages/effect-fc/test/Lens.test.tsx index 4728bfc..9bf6233 100644 --- a/packages/effect-fc/test/Lens.test.tsx +++ b/packages/effect-fc/test/Lens.test.tsx @@ -1,10 +1,9 @@ import { fireEvent, render, screen, waitFor } from "@testing-library/react" import { Effect, Layer, SubscriptionRef } from "effect" -import { Lens } from "effect-lens" import * as React from "react" import { describe, expect, it } from "vitest" import * as Component from "../src/Component.js" -import * as LensModule from "../src/Lens.js" +import * as Lens from "../src/Lens.js" import * as ReactRuntime from "../src/ReactRuntime.js" @@ -26,7 +25,7 @@ describe("Lens", () => { const lens = Lens.fromSubscriptionRef(ref) const Probe = Component.makeUntraced("LensUseStateProbe")(function*() { - const [value, setValue] = yield* LensModule.useState(lens) + const [value, setValue] = yield* Lens.useState(lens) return ( <> @@ -63,7 +62,7 @@ describe("Lens", () => { const lens = Lens.fromSubscriptionRef(ref) const Probe = Component.makeUntraced("LensUseStateEquivalenceProbe")(function*() { - const [value] = yield* LensModule.useState(lens, { + const [value] = yield* Lens.useState(lens, { equivalence: (self, that) => self.id === that.id, }) @@ -97,7 +96,7 @@ describe("Lens", () => { const Probe = Component.makeUntraced("LensUseFromReactStateProbe")(function*() { const [value, setValue] = React.useState("hello") - const reactLens = yield* LensModule.useFromReactState([value, setValue]) + const reactLens = yield* Lens.useFromReactState([value, setValue]) yield* Component.useOnMount(() => Effect.sync(() => { lens = reactLens @@ -131,7 +130,7 @@ describe("Lens", () => { const Probe = Component.makeUntraced("LensUseFromReactStateEquivalenceProbe")(function*() { const [value, setValue] = React.useState({ id: 1, label: "first" }) - const reactLens = yield* LensModule.useFromReactState([value, setValue], { + const reactLens = yield* Lens.useFromReactState([value, setValue], { equivalence: (self, that) => self.id === that.id, }) diff --git a/packages/effect-fc/test/Subscribable.test.tsx b/packages/effect-fc/test/Subscribable.test.tsx index eec6289..772d330 100644 --- a/packages/effect-fc/test/Subscribable.test.tsx +++ b/packages/effect-fc/test/Subscribable.test.tsx @@ -1,11 +1,10 @@ import { render, screen, waitFor } from "@testing-library/react" import { Effect, Fiber, Layer, Stream, SubscriptionRef } from "effect" import { Lens } from "effect-lens" -import * as React from "react" import { describe, expect, it } from "vitest" import * as Component from "../src/Component.js" import * as ReactRuntime from "../src/ReactRuntime.js" -import * as SubscribableModule from "../src/Subscribable.js" +import * as Subscribable from "../src/Subscribable.js" const makeRuntime = async () => { @@ -26,7 +25,7 @@ describe("Subscribable", () => { const left = Lens.fromSubscriptionRef(leftRef) const right = Lens.fromSubscriptionRef(rightRef) - const zipped = SubscribableModule.zipLatestAll(left, right) + const zipped = Subscribable.zipLatestAll(left, right) expect(await Effect.runPromise(zipped.get)).toEqual([1, "a"]) }) @@ -37,7 +36,7 @@ describe("Subscribable", () => { const left = Lens.fromSubscriptionRef(leftRef) const right = Lens.fromSubscriptionRef(rightRef) - const zipped = SubscribableModule.zipLatestAll(left, right) + const zipped = Subscribable.zipLatestAll(left, right) const values: Array = [] const collector = Effect.runFork(Effect.scoped(zipped.changes.pipe( @@ -63,7 +62,7 @@ describe("Subscribable", () => { const label = Lens.fromSubscriptionRef(labelRef) const Probe = Component.makeUntraced("SubscribableUseAllProbe")(function*() { - const [currentCount, currentLabel] = yield* SubscribableModule.useAll([count, label]) + const [currentCount, currentLabel] = yield* Subscribable.useAll([count, label]) return
{`${currentCount}:${currentLabel}`}
}).pipe( @@ -96,7 +95,7 @@ describe("Subscribable", () => { const flag = Lens.fromSubscriptionRef(flagRef) const Probe = Component.makeUntraced("SubscribableUseAllEquivalenceProbe")(function*() { - const [currentItem, currentFlag] = yield* SubscribableModule.useAll([item, flag], { + const [currentItem, currentFlag] = yield* Subscribable.useAll([item, flag], { equivalence: ([selfItem, selfFlag], [thatItem, thatFlag]) => selfItem.id === thatItem.id && selfFlag === thatFlag, }) -- 2.52.0 From 1292b9885a94a35d01777d8e2eedff8d2678fdde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 8 Jun 2026 11:14:31 +0200 Subject: [PATCH 05/61] Fix --- packages/effect-fc/test/Query.test.ts | 169 ++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 packages/effect-fc/test/Query.test.ts diff --git a/packages/effect-fc/test/Query.test.ts b/packages/effect-fc/test/Query.test.ts new file mode 100644 index 0000000..ee6544f --- /dev/null +++ b/packages/effect-fc/test/Query.test.ts @@ -0,0 +1,169 @@ +import { Effect, Option, type Scope, Stream } from "effect" +import { describe, expect, it } from "vitest" +import * as Query from "../src/Query.js" +import * as QueryClient from "../src/QueryClient.js" +import * as Result from "../src/Result.js" + + +const runQueryTest = (effect: Effect.Effect) => + Effect.runPromise(Effect.scoped(effect.pipe( + Effect.provide(QueryClient.QueryClient.Default), + ))) + +const expectSuccessValue = ( + result: Result.Result, +): A => { + expect(Result.isSuccess(result)).toBe(true) + + if (!Result.isSuccess(result)) + throw new Error(`Expected Success result, received ${result._tag}`) + + return result.value +} + +const expectSomeValue = (option: Option.Option): A => { + expect(Option.isSome(option)).toBe(true) + + if (!Option.isSome(option)) + throw new Error("Expected Some option, received None") + + return option.value +} + +describe("Query", () => { + it("fetch caches successful results until they are invalidated or stale", async () => { + let calls = 0 + const key = Stream.empty as Stream.Stream + + const result = await runQueryTest(Effect.gen(function*() { + const query = yield* Query.make({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "1 minute", + }) + + const first = yield* query.fetch([1]) + const second = yield* query.fetch([1]) + + return [first, second] as const + })) + + expect(calls).toBe(1) + expect(result[0]._tag).toBe("Success") + expect(result[1]._tag).toBe("Success") + expect(expectSuccessValue(result[0])).toBe("value:1:1") + expect(expectSuccessValue(result[1])).toBe("value:1:1") + }) + + it("refresh reruns the latest query key", async () => { + let calls = 0 + const key = Stream.empty as Stream.Stream + + const result = await runQueryTest(Effect.gen(function*() { + const query = yield* Query.make({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "0 millis", + }) + + const first = yield* query.fetch([1]) + yield* Effect.sleep("1 millis") + const refreshed = yield* query.refresh + + return [first, refreshed] as const + })) + + expect(calls).toBe(2) + expect(expectSuccessValue(result[0])).toBe("value:1:1") + expect(expectSuccessValue(result[1])).toBe("value:1:2") + }) + + it("invalidateCacheEntry forces the next fetch for that key to rerun", async () => { + let calls = 0 + const key = Stream.empty as Stream.Stream + + const result = await runQueryTest(Effect.gen(function*() { + const query = yield* Query.make({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "1 minute", + }) + + const first = yield* query.fetch([1]) + yield* query.invalidateCacheEntry([1]) + const second = yield* query.fetch([1]) + + return [first, second] as const + })) + + expect(calls).toBe(2) + expect(expectSuccessValue(result[0])).toBe("value:1:1") + expect(expectSuccessValue(result[1])).toBe("value:1:2") + }) + + it("invalidateCache clears cached entries for the query function", async () => { + let calls = 0 + const key = Stream.empty as Stream.Stream + + const result = await runQueryTest(Effect.gen(function*() { + const query = yield* Query.make({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "1 minute", + }) + + const first = yield* query.fetch([1]) + yield* query.invalidateCache + const second = yield* query.fetch([1]) + + return [first, second] as const + })) + + expect(calls).toBe(2) + expect(expectSuccessValue(result[0])).toBe("value:1:1") + expect(expectSuccessValue(result[1])).toBe("value:1:2") + }) + + it("service starts the key stream automatically and updates latest state", async () => { + let calls = 0 + const key = Stream.make([1] as const) as Stream.Stream + + const effect = Effect.gen(function*() { + const query = yield* Query.service({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "1 minute", + }) + + yield* Effect.sleep("10 millis") + + return { + final: yield* query.result.get, + latestKey: yield* query.latestKey.get, + latestFinalResult: yield* query.latestFinalResult.get, + } + }) + + const result = await runQueryTest(effect) + + expect(calls).toBe(1) + expect(expectSuccessValue(result.final)).toBe("value:1:1") + expect(expectSomeValue(result.latestKey)).toEqual([1]) + expect(expectSuccessValue(expectSomeValue(result.latestFinalResult))).toBe("value:1:1") + }) +}) -- 2.52.0 From 845aa193ba4e85b01c1f9e1f6eb429a571f6fd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 8 Jun 2026 13:55:16 +0200 Subject: [PATCH 06/61] Add getting started docs --- bun.lock | 6 +- packages/docs/README.md | 34 +-- .../docs/blog/2019-05-28-first-blog-post.md | 10 - .../docs/blog/2019-05-29-long-blog-post.md | 42 ---- .../docs/blog/2021-08-01-mdx-blog-post.mdx | 24 -- .../docusaurus-plushie-banner.jpeg | Bin 96122 -> 0 bytes .../docs/blog/2021-08-26-welcome/index.md | 27 --- packages/docs/blog/authors.yml | 25 --- packages/docs/blog/tags.yml | 19 -- packages/docs/docs/getting-started.md | 208 ++++++++++++++++++ packages/docs/docs/intro.md | 108 --------- .../docs/docs/tutorial-basics/_category_.json | 8 - .../docs/tutorial-basics/congratulations.md | 23 -- .../tutorial-basics/create-a-blog-post.md | 34 --- .../docs/tutorial-basics/create-a-document.md | 57 ----- .../docs/tutorial-basics/create-a-page.md | 43 ---- .../docs/tutorial-basics/deploy-your-site.md | 31 --- .../tutorial-basics/markdown-features.mdx | 152 ------------- .../docs/docs/tutorial-extras/_category_.json | 7 - .../img/docsVersionDropdown.png | Bin 25427 -> 0 bytes .../tutorial-extras/img/localeDropdown.png | Bin 27841 -> 0 bytes .../tutorial-extras/manage-docs-versions.md | 55 ----- .../tutorial-extras/translate-your-site.md | 88 -------- packages/docs/docusaurus.config.ts | 112 ++++------ packages/docs/package.json | 2 + packages/docs/sidebars.ts | 32 +-- .../src/components/HomepageFeatures/index.tsx | 71 ------ .../HomepageFeatures/styles.module.css | 11 - packages/docs/src/css/custom.css | 57 ++--- packages/docs/src/pages/index.module.css | 91 ++++++-- packages/docs/src/pages/index.tsx | 90 +++++--- packages/docs/src/pages/markdown-page.md | 7 - .../static/img/docusaurus-social-card.jpg | Bin 55746 -> 0 bytes packages/docs/static/img/docusaurus.png | Bin 5142 -> 0 bytes packages/docs/static/img/logo.svg | 7 +- .../static/img/undraw_docusaurus_mountain.svg | 171 -------------- .../static/img/undraw_docusaurus_react.svg | 170 -------------- .../static/img/undraw_docusaurus_tree.svg | 40 ---- packages/docs/tsconfig.json | 3 +- 39 files changed, 434 insertions(+), 1431 deletions(-) delete mode 100644 packages/docs/blog/2019-05-28-first-blog-post.md delete mode 100644 packages/docs/blog/2019-05-29-long-blog-post.md delete mode 100644 packages/docs/blog/2021-08-01-mdx-blog-post.mdx delete mode 100644 packages/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg delete mode 100644 packages/docs/blog/2021-08-26-welcome/index.md delete mode 100644 packages/docs/blog/authors.yml delete mode 100644 packages/docs/blog/tags.yml create mode 100644 packages/docs/docs/getting-started.md delete mode 100644 packages/docs/docs/intro.md delete mode 100644 packages/docs/docs/tutorial-basics/_category_.json delete mode 100644 packages/docs/docs/tutorial-basics/congratulations.md delete mode 100644 packages/docs/docs/tutorial-basics/create-a-blog-post.md delete mode 100644 packages/docs/docs/tutorial-basics/create-a-document.md delete mode 100644 packages/docs/docs/tutorial-basics/create-a-page.md delete mode 100644 packages/docs/docs/tutorial-basics/deploy-your-site.md delete mode 100644 packages/docs/docs/tutorial-basics/markdown-features.mdx delete mode 100644 packages/docs/docs/tutorial-extras/_category_.json delete mode 100644 packages/docs/docs/tutorial-extras/img/docsVersionDropdown.png delete mode 100644 packages/docs/docs/tutorial-extras/img/localeDropdown.png delete mode 100644 packages/docs/docs/tutorial-extras/manage-docs-versions.md delete mode 100644 packages/docs/docs/tutorial-extras/translate-your-site.md delete mode 100644 packages/docs/src/components/HomepageFeatures/index.tsx delete mode 100644 packages/docs/src/components/HomepageFeatures/styles.module.css delete mode 100644 packages/docs/src/pages/markdown-page.md delete mode 100644 packages/docs/static/img/docusaurus-social-card.jpg delete mode 100644 packages/docs/static/img/docusaurus.png delete mode 100644 packages/docs/static/img/undraw_docusaurus_mountain.svg delete mode 100644 packages/docs/static/img/undraw_docusaurus_react.svg delete mode 100644 packages/docs/static/img/undraw_docusaurus_tree.svg diff --git a/bun.lock b/bun.lock index ccc7b94..bc1bfa4 100644 --- a/bun.lock +++ b/bun.lock @@ -31,6 +31,8 @@ "@docusaurus/module-type-aliases": "3.10.1", "@docusaurus/tsconfig": "3.10.1", "@docusaurus/types": "3.10.1", + "@types/react": "^19.2.15", + "@types/react-dom": "^19.2.3", "typescript": "~6.0.3", }, }, @@ -3028,10 +3030,6 @@ "decompress-response/mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], - "docs/react": ["react@19.2.5", "", {}, "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA=="], - - "docs/react-dom": ["react-dom@19.2.5", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.5" } }, "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag=="], - "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], "dot-prop/is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], diff --git a/packages/docs/README.md b/packages/docs/README.md index b28211a..189dc20 100644 --- a/packages/docs/README.md +++ b/packages/docs/README.md @@ -1,41 +1,17 @@ -# Website +# effect-fc Docs -This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. - -## Installation - -```bash -yarn -``` +The documentation site is built with Docusaurus. ## Local Development ```bash -yarn start +bun run --cwd packages/docs start ``` -This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. - ## Build ```bash -yarn build +bun run --cwd packages/docs build ``` -This command generates static content into the `build` directory and can be served using any static contents hosting service. - -## Deployment - -Using SSH: - -```bash -USE_SSH=true yarn deploy -``` - -Not using SSH: - -```bash -GIT_USER= yarn deploy -``` - -If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. +The static site is written to `packages/docs/build`. diff --git a/packages/docs/blog/2019-05-28-first-blog-post.md b/packages/docs/blog/2019-05-28-first-blog-post.md deleted file mode 100644 index 8fc0194..0000000 --- a/packages/docs/blog/2019-05-28-first-blog-post.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -slug: first-blog-post -title: First Blog Post -authors: [slorber, yangshun] -tags: [hola, docusaurus] ---- - -Lorem ipsum dolor sit amet... - -...consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/packages/docs/blog/2019-05-29-long-blog-post.md b/packages/docs/blog/2019-05-29-long-blog-post.md deleted file mode 100644 index 0705713..0000000 --- a/packages/docs/blog/2019-05-29-long-blog-post.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -slug: long-blog-post -title: Long Blog Post -authors: yangshun -tags: [hello, docusaurus] ---- - -This is the summary of a very long blog post, - -Use a `` comment to limit blog post size in the list view. - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/packages/docs/blog/2021-08-01-mdx-blog-post.mdx b/packages/docs/blog/2021-08-01-mdx-blog-post.mdx deleted file mode 100644 index 0c4b4a4..0000000 --- a/packages/docs/blog/2021-08-01-mdx-blog-post.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -slug: mdx-blog-post -title: MDX Blog Post -authors: [slorber] -tags: [docusaurus] ---- - -Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). - -:::tip - -Use the power of React to create interactive blog posts. - -::: - -{/* truncate */} - -For example, use JSX to create an interactive button: - -```js - -``` - - diff --git a/packages/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg b/packages/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg deleted file mode 100644 index 11bda0928456b12f8e53d0ba5709212a4058d449..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96122 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 diff --git a/packages/docs/blog/2021-08-26-welcome/index.md b/packages/docs/blog/2021-08-26-welcome/index.md deleted file mode 100644 index 69ca7be..0000000 --- a/packages/docs/blog/2021-08-26-welcome/index.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -slug: welcome -title: Welcome -authors: [slorber, yangshun] -tags: [facebook, hello, docusaurus] ---- - -[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). - -Here are a few tips you might find useful. - -Simply add Markdown files (or folders) to the `blog` directory. - -Regular blog authors can be added to `authors.yml`. - -The blog post date can be extracted from filenames, such as: - -- `2019-05-30-welcome.md` -- `2019-05-30-welcome/index.md` - -A blog post folder can be convenient to co-locate blog post images: - -![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg) - -The blog supports tags as well! - -**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. diff --git a/packages/docs/blog/authors.yml b/packages/docs/blog/authors.yml deleted file mode 100644 index 0fd3987..0000000 --- a/packages/docs/blog/authors.yml +++ /dev/null @@ -1,25 +0,0 @@ -yangshun: - name: Yangshun Tay - title: Ex-Meta Staff Engineer, Co-founder GreatFrontEnd - url: https://linkedin.com/in/yangshun - image_url: https://github.com/yangshun.png - page: true - socials: - x: yangshunz - linkedin: yangshun - github: yangshun - newsletter: https://www.greatfrontend.com - -slorber: - name: Sébastien Lorber - title: Docusaurus maintainer - url: https://sebastienlorber.com - image_url: https://github.com/slorber.png - page: - # customize the url of the author page at /blog/authors/ - permalink: '/all-sebastien-lorber-articles' - socials: - x: sebastienlorber - linkedin: sebastienlorber - github: slorber - newsletter: https://thisweekinreact.com diff --git a/packages/docs/blog/tags.yml b/packages/docs/blog/tags.yml deleted file mode 100644 index bfaa778..0000000 --- a/packages/docs/blog/tags.yml +++ /dev/null @@ -1,19 +0,0 @@ -facebook: - label: Facebook - permalink: /facebook - description: Facebook tag description - -hello: - label: Hello - permalink: /hello - description: Hello tag description - -docusaurus: - label: Docusaurus - permalink: /docusaurus - description: Docusaurus tag description - -hola: - label: Hola - permalink: /hola - description: Hola tag description diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md new file mode 100644 index 0000000..0f3eecb --- /dev/null +++ b/packages/docs/docs/getting-started.md @@ -0,0 +1,208 @@ +--- +sidebar_position: 1 +title: Getting Started +--- + +# Getting Started + +`effect-fc` lets React components be written as Effect programs. Inside a +component body you can yield services, run Effects, subscribe to Effect-powered +state, and still export a normal React function component at the edge of your +app. + +This guide starts with the smallest useful setup: + +1. Install `effect-fc` with its peer dependencies. +2. Create a React runtime from an Effect `Layer`. +3. Wrap your React app with `ReactRuntime.Provider`. +4. Write a component with `Component.make`. +5. Convert it to a React component with `Component.withRuntime`. + +## Install + +Install `effect-fc` alongside `effect` and React 19.2 or newer: + +```bash npm2yarn +npm install effect-fc effect react react-dom +``` + +If your project uses TypeScript, also install React's type packages: + +```bash npm2yarn +npm install --save-dev @types/react @types/react-dom +``` + +## Create A Runtime + +An Effect-FC app needs an Effect runtime. Build one from the services your UI +needs, then share it with React through `ReactRuntime.Provider`. + +For an empty app, `Layer.empty` is enough: + +```tsx title="src/runtime.ts" +import { Layer } from "effect" +import { ReactRuntime } from "effect-fc" + +export const runtime = ReactRuntime.make(Layer.empty) +``` + +As your app grows, add services to the layer: + +```tsx title="src/runtime.ts" +import { FetchHttpClient } from "@effect/platform" +import { Layer } from "effect" +import { ReactRuntime } from "effect-fc" + +const AppLive = Layer.empty.pipe( + Layer.provideMerge(FetchHttpClient.layer), +) + +export const runtime = ReactRuntime.make(AppLive) +``` + +## Provide The Runtime + +At the React root, wrap your app with `ReactRuntime.Provider`: + +```tsx title="src/main.tsx" +import { StrictMode } from "react" +import { createRoot } from "react-dom/client" +import { ReactRuntime } from "effect-fc" +import { App } from "./App" +import { runtime } from "./runtime" + +createRoot(document.getElementById("root")!).render( + + + + + , +) +``` + +`ReactRuntime.Provider` also works with routers. Keep it above your router +provider so route components can be converted with the same runtime context. + +## Write Your First Component + +Use `Component.make` when you want automatic tracing spans, or +`Component.makeUntraced` when you only want the component behavior. + +```tsx title="src/Hello.tsx" +import { Effect } from "effect" +import { Component } from "effect-fc" +import { runtime } from "./runtime" + +const HelloEffect = Component.make("HelloEffect")(function* (props: { + readonly name: string +}) { + const message = yield* Effect.succeed(`Hello, ${props.name}`) + + return

{message}

+}) + +export const Hello = HelloEffect.pipe( + Component.withRuntime(runtime.context), +) +``` + +`Hello` is now a regular React component: + +```tsx title="src/App.tsx" +import { Hello } from "./Hello" + +export function App() { + return +} +``` + +## Use Services + +Components can yield Effect services directly. Define services with Effect, +provide them in your runtime layer, then consume them from the component body. + +```ts title="src/services.ts" +import { Effect } from "effect" + +export class GreetingService extends Effect.Service()( + "GreetingService", + { + succeed: { + greet: (name: string) => `Welcome, ${name}`, + }, + }, +) {} +``` + +Provide the service in your runtime: + +```tsx title="src/runtime.ts" +import { Layer } from "effect" +import { ReactRuntime } from "effect-fc" +import { GreetingService } from "./services" + +const AppLive = Layer.empty.pipe( + Layer.provideMerge(GreetingService.Default), +) + +export const runtime = ReactRuntime.make(AppLive) +``` + +Then read it inside a component: + +```tsx title="src/Greeting.tsx" +import { Component } from "effect-fc" +import { runtime } from "./runtime" +import { GreetingService } from "./services" + +const GreetingEffect = Component.make("Greeting")(function* (props: { + readonly name: string +}) { + const greeting = yield* GreetingService + + return

{greeting.greet(props.name)}

+}) + +export const Greeting = GreetingEffect.pipe( + Component.withRuntime(runtime.context), +) +``` + +## Mount And Cleanup Effects + +Use `Component.useOnMount` for scoped work that should start when the component +mounts and finalize when it unmounts. + +```tsx +import { Console, Effect } from "effect" +import { Component } from "effect-fc" + +const Mounted = Component.make("Mounted")(function* () { + yield* Component.useOnMount(() => + Effect.gen(function* () { + yield* Console.log("Mounted") + yield* Effect.addFinalizer(() => Console.log("Unmounted")) + }), + ) + + return

Open the console, then unmount me.

+}) +``` + +Finalizers are tied to the component scope, so this is the right place for +subscriptions, resources, and other lifecycle-bound Effects. + +## Where To Go Next + +Once the runtime and component boundary are in place, the rest of the library +builds on the same idea: + +- `Subscribable.useAll` reads Effect subscribables and rerenders when they + change. +- `Lens` connects React state and Effect `SubscriptionRef` values. +- `Query` and `Mutation` model async data and user-triggered operations. +- `Form`, `SubmittableForm`, and `SynchronizedForm` help build Effect-backed + forms. + +The important pattern is small and repeatable: write Effect-FC components inside +the runtime, then use `Component.withRuntime` at React boundaries. diff --git a/packages/docs/docs/intro.md b/packages/docs/docs/intro.md deleted file mode 100644 index 9c3cd3d..0000000 --- a/packages/docs/docs/intro.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Effect FC - -Welcome to **Effect FC** (as in: Effect **F**unction **C**omponent) – a powerful integration of [Effect](https://effect.website/) with React 19.2+ that enables you to write React function components using Effect generators. - -## What is Effect FC? - -Effect FC allows you to harness the full power of Effect-TS within your React components. Instead of writing traditional React hooks, you can use Effect generators to compose complex, type-safe component logic with built-in error handling, resource management, and dependency injection. - -### Key Features - -- **Effect Integration**: Write your function component logic using Effect. -- **Type Safety**: Full TypeScript support with Effect's comprehensive type system -- **Dependency Injection**: Built-in support for providing dependencies to components using Effect services. -- **Resource Management**: Automatic cleanup and finalization of component resources using the `Scope` API. - -## Quick Example - -Here's what writing an Effect FC component looks like: - -```typescript -export class TodosView extends Component.make("TodosView")(function*() { - const state = yield* TodosState - const [todos] = yield* Component.useSubscribables([state.subscriptionRef]) - - yield* Component.useOnMount(() => Effect.andThen( - Console.log("Todos mounted"), - Effect.addFinalizer(() => Console.log("Todos unmounted")), - )) - - const Todo = yield* TodoView.use - - return ( - - Todos - - - - - {Chunk.map(todos, todo => - - )} - - - ) -}) {} - -const Index = Component.make("IndexView")(function*() { - const context = yield* Component.useContextFromLayer(TodosState.Default) - const Todos = yield* Effect.provide(TodosView.use, context) - - return -}).pipe( - Component.withRuntime(runtime.context) -) - -export const Route = createFileRoute("/")({ - component: Index -}) -``` - -## Getting Started - -### Prerequisites - -Before using Effect FC, make sure you have: - -- **Node.js** version 20.0 or above -- **React** 19.2 or higher -- **Effect** 3.19 or higher - -### Installation - -Install Effect FC and its peer dependencies: - -```bash -npm install effect-fc effect react -``` - -Or with your preferred package manager: - -```bash -yarn add effect-fc effect react -bun add effect-fc effect react -pnpm add effect-fc effect react -``` - -### Next Steps - -- Explore the [Tutorial Basics](./tutorial-basics/create-a-document.md) to learn the fundamentals -- Check out the [Example Project](https://github.com/your-repo/packages/example) for a complete working application - -## Important Notes - -:::info Early Development -This library is in early development. While it is mostly feature-complete and usable, expect bugs and quirks. Things are still being ironed out, so ideas and criticisms are welcome! -::: - -:::warning Known Issues -- React Refresh doesn't work for Effect FC components yet. Page reload is required to view changes. Regular React components are unaffected. -::: - -## Community & Support - -Have questions or want to contribute? We'd love to hear from you! Check out the project repository and feel free to open issues or discussions. diff --git a/packages/docs/docs/tutorial-basics/_category_.json b/packages/docs/docs/tutorial-basics/_category_.json deleted file mode 100644 index 2e6db55..0000000 --- a/packages/docs/docs/tutorial-basics/_category_.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "label": "Tutorial - Basics", - "position": 2, - "link": { - "type": "generated-index", - "description": "5 minutes to learn the most important Docusaurus concepts." - } -} diff --git a/packages/docs/docs/tutorial-basics/congratulations.md b/packages/docs/docs/tutorial-basics/congratulations.md deleted file mode 100644 index 04771a0..0000000 --- a/packages/docs/docs/tutorial-basics/congratulations.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar_position: 6 ---- - -# Congratulations! - -You have just learned the **basics of Docusaurus** and made some changes to the **initial template**. - -Docusaurus has **much more to offer**! - -Have **5 more minutes**? Take a look at **[versioning](../tutorial-extras/manage-docs-versions.md)** and **[i18n](../tutorial-extras/translate-your-site.md)**. - -Anything **unclear** or **buggy** in this tutorial? [Please report it!](https://github.com/facebook/docusaurus/discussions/4610) - -## What's next? - -- Read the [official documentation](https://docusaurus.io/) -- Modify your site configuration with [`docusaurus.config.js`](https://docusaurus.io/docs/api/docusaurus-config) -- Add navbar and footer items with [`themeConfig`](https://docusaurus.io/docs/api/themes/configuration) -- Add a custom [Design and Layout](https://docusaurus.io/docs/styling-layout) -- Add a [search bar](https://docusaurus.io/docs/search) -- Find inspirations in the [Docusaurus showcase](https://docusaurus.io/showcase) -- Get involved in the [Docusaurus Community](https://docusaurus.io/community/support) diff --git a/packages/docs/docs/tutorial-basics/create-a-blog-post.md b/packages/docs/docs/tutorial-basics/create-a-blog-post.md deleted file mode 100644 index 550ae17..0000000 --- a/packages/docs/docs/tutorial-basics/create-a-blog-post.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Create a Blog Post - -Docusaurus creates a **page for each blog post**, but also a **blog index page**, a **tag system**, an **RSS** feed... - -## Create your first Post - -Create a file at `blog/2021-02-28-greetings.md`: - -```md title="blog/2021-02-28-greetings.md" ---- -slug: greetings -title: Greetings! -authors: - - name: Joel Marcey - title: Co-creator of Docusaurus 1 - url: https://github.com/JoelMarcey - image_url: https://github.com/JoelMarcey.png - - name: Sébastien Lorber - title: Docusaurus maintainer - url: https://sebastienlorber.com - image_url: https://github.com/slorber.png -tags: [greetings] ---- - -Congratulations, you have made your first post! - -Feel free to play around and edit this post as much as you like. -``` - -A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings). diff --git a/packages/docs/docs/tutorial-basics/create-a-document.md b/packages/docs/docs/tutorial-basics/create-a-document.md deleted file mode 100644 index c22fe29..0000000 --- a/packages/docs/docs/tutorial-basics/create-a-document.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Create a Document - -Documents are **groups of pages** connected through: - -- a **sidebar** -- **previous/next navigation** -- **versioning** - -## Create your first Doc - -Create a Markdown file at `docs/hello.md`: - -```md title="docs/hello.md" -# Hello - -This is my **first Docusaurus document**! -``` - -A new document is now available at [http://localhost:3000/docs/hello](http://localhost:3000/docs/hello). - -## Configure the Sidebar - -Docusaurus automatically **creates a sidebar** from the `docs` folder. - -Add metadata to customize the sidebar label and position: - -```md title="docs/hello.md" {1-4} ---- -sidebar_label: 'Hi!' -sidebar_position: 3 ---- - -# Hello - -This is my **first Docusaurus document**! -``` - -It is also possible to create your sidebar explicitly in `sidebars.js`: - -```js title="sidebars.js" -export default { - tutorialSidebar: [ - 'intro', - // highlight-next-line - 'hello', - { - type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], - }, - ], -}; -``` diff --git a/packages/docs/docs/tutorial-basics/create-a-page.md b/packages/docs/docs/tutorial-basics/create-a-page.md deleted file mode 100644 index 20e2ac3..0000000 --- a/packages/docs/docs/tutorial-basics/create-a-page.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Create a Page - -Add **Markdown or React** files to `src/pages` to create a **standalone page**: - -- `src/pages/index.js` → `localhost:3000/` -- `src/pages/foo.md` → `localhost:3000/foo` -- `src/pages/foo/bar.js` → `localhost:3000/foo/bar` - -## Create your first React Page - -Create a file at `src/pages/my-react-page.js`: - -```jsx title="src/pages/my-react-page.js" -import React from 'react'; -import Layout from '@theme/Layout'; - -export default function MyReactPage() { - return ( - -

My React page

-

This is a React page

-
- ); -} -``` - -A new page is now available at [http://localhost:3000/my-react-page](http://localhost:3000/my-react-page). - -## Create your first Markdown Page - -Create a file at `src/pages/my-markdown-page.md`: - -```mdx title="src/pages/my-markdown-page.md" -# My Markdown page - -This is a Markdown page -``` - -A new page is now available at [http://localhost:3000/my-markdown-page](http://localhost:3000/my-markdown-page). diff --git a/packages/docs/docs/tutorial-basics/deploy-your-site.md b/packages/docs/docs/tutorial-basics/deploy-your-site.md deleted file mode 100644 index 1c50ee0..0000000 --- a/packages/docs/docs/tutorial-basics/deploy-your-site.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Deploy your site - -Docusaurus is a **static-site-generator** (also called **[Jamstack](https://jamstack.org/)**). - -It builds your site as simple **static HTML, JavaScript and CSS files**. - -## Build your site - -Build your site **for production**: - -```bash -npm run build -``` - -The static files are generated in the `build` folder. - -## Deploy your site - -Test your production build locally: - -```bash -npm run serve -``` - -The `build` folder is now served at [http://localhost:3000/](http://localhost:3000/). - -You can now deploy the `build` folder **almost anywhere** easily, **for free** or very small cost (read the **[Deployment Guide](https://docusaurus.io/docs/deployment)**). diff --git a/packages/docs/docs/tutorial-basics/markdown-features.mdx b/packages/docs/docs/tutorial-basics/markdown-features.mdx deleted file mode 100644 index 35e0082..0000000 --- a/packages/docs/docs/tutorial-basics/markdown-features.mdx +++ /dev/null @@ -1,152 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Markdown Features - -Docusaurus supports **[Markdown](https://daringfireball.net/projects/markdown/syntax)** and a few **additional features**. - -## Front Matter - -Markdown documents have metadata at the top called [Front Matter](https://jekyllrb.com/docs/front-matter/): - -```text title="my-doc.md" -// highlight-start ---- -id: my-doc-id -title: My document title -description: My document description -slug: /my-custom-url ---- -// highlight-end - -## Markdown heading - -Markdown text with [links](./hello.md) -``` - -## Links - -Regular Markdown links are supported, using url paths or relative file paths. - -```md -Let's see how to [Create a page](/create-a-page). -``` - -```md -Let's see how to [Create a page](./create-a-page.md). -``` - -**Result:** Let's see how to [Create a page](./create-a-page.md). - -## Images - -Regular Markdown images are supported. - -You can use absolute paths to reference images in the static directory (`static/img/docusaurus.png`): - -```md -![Docusaurus logo](/img/docusaurus.png) -``` - -![Docusaurus logo](/img/docusaurus.png) - -You can reference images relative to the current file as well. This is particularly useful to colocate images close to the Markdown files using them: - -```md -![Docusaurus logo](./img/docusaurus.png) -``` - -## Code Blocks - -Markdown code blocks are supported with Syntax highlighting. - -````md -```jsx title="src/components/HelloDocusaurus.js" -function HelloDocusaurus() { - return

Hello, Docusaurus!

; -} -``` -```` - -```jsx title="src/components/HelloDocusaurus.js" -function HelloDocusaurus() { - return

Hello, Docusaurus!

; -} -``` - -## Admonitions - -Docusaurus has a special syntax to create admonitions and callouts: - -```md -:::tip My tip - -Use this awesome feature option - -::: - -:::danger Take care - -This action is dangerous - -::: -``` - -:::tip My tip - -Use this awesome feature option - -::: - -:::danger Take care - -This action is dangerous - -::: - -## MDX and React Components - -[MDX](https://mdxjs.com/) can make your documentation more **interactive** and allows using any **React components inside Markdown**: - -```jsx -export const Highlight = ({children, color}) => ( - { - alert(`You clicked the color ${color} with label ${children}`) - }}> - {children} - -); - -This is Docusaurus green ! - -This is Facebook blue ! -``` - -export const Highlight = ({children, color}) => ( - { - alert(`You clicked the color ${color} with label ${children}`); - }}> - {children} - -); - -This is Docusaurus green ! - -This is Facebook blue ! diff --git a/packages/docs/docs/tutorial-extras/_category_.json b/packages/docs/docs/tutorial-extras/_category_.json deleted file mode 100644 index a8ffcc1..0000000 --- a/packages/docs/docs/tutorial-extras/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Tutorial - Extras", - "position": 3, - "link": { - "type": "generated-index" - } -} diff --git a/packages/docs/docs/tutorial-extras/img/docsVersionDropdown.png b/packages/docs/docs/tutorial-extras/img/docsVersionDropdown.png deleted file mode 100644 index 97e4164618b5f8beda34cfa699720aba0ad2e342..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25427 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 diff --git a/packages/docs/docs/tutorial-extras/img/localeDropdown.png b/packages/docs/docs/tutorial-extras/img/localeDropdown.png deleted file mode 100644 index e257edc1f932985396bf59584c7ccfaddf955779..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27841 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 JrC|B>e*nH7H{}2T diff --git a/packages/docs/docs/tutorial-extras/manage-docs-versions.md b/packages/docs/docs/tutorial-extras/manage-docs-versions.md deleted file mode 100644 index ccda0b9..0000000 --- a/packages/docs/docs/tutorial-extras/manage-docs-versions.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Manage Docs Versions - -Docusaurus can manage multiple versions of your docs. - -## Create a docs version - -Release a version 1.0 of your project: - -```bash -npm run docusaurus docs:version 1.0 -``` - -The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created. - -Your docs now have 2 versions: - -- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs -- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs** - -## Add a Version Dropdown - -To navigate seamlessly across versions, add a version dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -export default { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'docsVersionDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The docs version dropdown appears in your navbar: - -![Docs Version Dropdown](./img/docsVersionDropdown.png) - -## Update an existing version - -It is possible to edit versioned docs in their respective folder: - -- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello` -- `docs/hello.md` updates `http://localhost:3000/docs/next/hello` diff --git a/packages/docs/docs/tutorial-extras/translate-your-site.md b/packages/docs/docs/tutorial-extras/translate-your-site.md deleted file mode 100644 index b5a644a..0000000 --- a/packages/docs/docs/tutorial-extras/translate-your-site.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Translate your site - -Let's translate `docs/intro.md` to French. - -## Configure i18n - -Modify `docusaurus.config.js` to add support for the `fr` locale: - -```js title="docusaurus.config.js" -export default { - i18n: { - defaultLocale: 'en', - locales: ['en', 'fr'], - }, -}; -``` - -## Translate a doc - -Copy the `docs/intro.md` file to the `i18n/fr` folder: - -```bash -mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/ - -cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md -``` - -Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French. - -## Start your localized site - -Start your site on the French locale: - -```bash -npm run start -- --locale fr -``` - -Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated. - -:::caution - -In development, you can only use one locale at a time. - -::: - -## Add a Locale Dropdown - -To navigate seamlessly across languages, add a locale dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -export default { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'localeDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The locale dropdown now appears in your navbar: - -![Locale Dropdown](./img/localeDropdown.png) - -## Build your localized site - -Build your site for a specific locale: - -```bash -npm run build -- --locale fr -``` - -Or build your site to include all the locales at once: - -```bash -npm run build -``` diff --git a/packages/docs/docusaurus.config.ts b/packages/docs/docusaurus.config.ts index dc37f1d..b8e2078 100644 --- a/packages/docs/docusaurus.config.ts +++ b/packages/docs/docusaurus.config.ts @@ -1,13 +1,13 @@ -import type * as Preset from '@docusaurus/preset-classic'; -import type {Config} from '@docusaurus/types'; -import {themes as prismThemes} from 'prism-react-renderer'; +import type * as Preset from "@docusaurus/preset-classic" +import type { Config } from "@docusaurus/types" +import { themes as prismThemes } from "prism-react-renderer" // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const config: Config = { - title: 'My Site', - tagline: 'Dinosaurs are cool', - favicon: 'img/favicon.ico', + title: "effect-fc", + tagline: "Write React function components with Effect", + favicon: "img/favicon.ico", // Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future future: { @@ -15,54 +15,38 @@ const config: Config = { }, // Set the production url of your site here - url: 'https://your-docusaurus-site.example.com', + url: "https://thiladev.github.io", // Set the // pathname under which your site is served // For GitHub pages deployment, it is often '//' - baseUrl: '/', + baseUrl: "/effect-fc/", // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. - organizationName: 'facebook', // Usually your GitHub org/user name. - projectName: 'docusaurus', // Usually your repo name. + organizationName: "Thiladev", // Usually your GitHub org/user name. + projectName: "effect-fc", // Usually your repo name. - onBrokenLinks: 'throw', + onBrokenLinks: "throw", // Even if you don't use internationalization, you can use this field to set // useful metadata like html lang. For example, if your site is Chinese, you // may want to replace "en" with "zh-Hans". i18n: { - defaultLocale: 'en', - locales: ['en'], + defaultLocale: "en", + locales: ["en"], }, presets: [ [ - 'classic', + "classic", { docs: { - sidebarPath: './sidebars.ts', - // Please change this to your repo. - // Remove this to remove the "edit this page" links. + sidebarPath: "./sidebars.ts", editUrl: - 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', - }, - blog: { - showReadingTime: true, - feedOptions: { - type: ['rss', 'atom'], - xslt: true, - }, - // Please change this to your repo. - // Remove this to remove the "edit this page" links. - editUrl: - 'https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/', - // Useful options to enforce blogging best practices - onInlineTags: 'warn', - onInlineAuthors: 'warn', - onUntruncatedBlogPosts: 'warn', + "https://github.com/Thiladev/effect-fc/tree/main/packages/docs/", }, + blog: false, theme: { - customCss: './src/css/custom.css', + customCss: "./src/css/custom.css", }, } satisfies Preset.Options, ], @@ -70,81 +54,75 @@ const config: Config = { themeConfig: { // Replace with your project's social card - image: 'img/docusaurus-social-card.jpg', colorMode: { respectPrefersColorScheme: true, }, navbar: { - title: 'My Site', + title: "effect-fc", logo: { - alt: 'My Site Logo', - src: 'img/logo.svg', + alt: "effect-fc logo", + src: "img/logo.svg", }, items: [ { - type: 'docSidebar', - sidebarId: 'tutorialSidebar', - position: 'left', - label: 'Tutorial', + type: "docSidebar", + sidebarId: "docsSidebar", + position: "left", + label: "Docs", }, - {to: '/blog', label: 'Blog', position: 'left'}, { - href: 'https://github.com/facebook/docusaurus', - label: 'GitHub', - position: 'right', + href: "https://github.com/Thiladev/effect-fc", + label: "GitHub", + position: "right", }, ], }, footer: { - style: 'dark', + style: "dark", links: [ { - title: 'Docs', + title: "Docs", items: [ { - label: 'Tutorial', - to: '/docs/intro', + label: "Getting Started", + to: "/docs/getting-started", }, ], }, { - title: 'Community', + title: "Project", items: [ { - label: 'Stack Overflow', - href: 'https://stackoverflow.com/questions/tagged/docusaurus', + label: "GitHub", + href: "https://github.com/Thiladev/effect-fc", }, { - label: 'Discord', - href: 'https://discordapp.com/invite/docusaurus', - }, - { - label: 'X', - href: 'https://x.com/docusaurus', + label: "Example App", + href: "https://github.com/Thiladev/effect-fc/tree/main/packages/example", }, ], }, { - title: 'More', + title: "Ecosystem", items: [ { - label: 'Blog', - to: '/blog', + label: "Effect", + href: "https://effect.website/", }, { - label: 'GitHub', - href: 'https://github.com/facebook/docusaurus', + label: "React", + href: "https://react.dev/", }, ], }, ], - copyright: `Copyright © ${new Date().getFullYear()} My Project, Inc. Built with Docusaurus.`, + copyright: `Copyright © ${new Date().getFullYear()} effect-fc contributors. Built with Docusaurus.`, }, prism: { theme: prismThemes.github, darkTheme: prismThemes.dracula, }, } satisfies Preset.ThemeConfig, -}; +} -export default config; +export default config diff --git a/packages/docs/package.json b/packages/docs/package.json index c7a516c..52feaa1 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -28,6 +28,8 @@ "@docusaurus/module-type-aliases": "3.10.1", "@docusaurus/tsconfig": "3.10.1", "@docusaurus/types": "3.10.1", + "@types/react": "^19.2.15", + "@types/react-dom": "^19.2.3", "typescript": "~6.0.3" }, "browserslist": { diff --git a/packages/docs/sidebars.ts b/packages/docs/sidebars.ts index 2897139..7efd336 100644 --- a/packages/docs/sidebars.ts +++ b/packages/docs/sidebars.ts @@ -1,33 +1,9 @@ -import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; +import type { SidebarsConfig } from "@docusaurus/plugin-content-docs" // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) -/** - * Creating a sidebar enables you to: - - create an ordered group of docs - - render a sidebar for each doc of that group - - provide next/previous navigation - - The sidebars can be generated from the filesystem, or explicitly defined here. - - Create as many sidebars as you want. - */ const sidebars: SidebarsConfig = { - // By default, Docusaurus generates a sidebar from the docs folder structure - tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], + docsSidebar: ["getting-started"], +} - // But you can create a sidebar manually - /* - tutorialSidebar: [ - 'intro', - 'hello', - { - type: 'category', - label: 'Tutorial', - items: ['tutorial-basics/create-a-document'], - }, - ], - */ -}; - -export default sidebars; +export default sidebars diff --git a/packages/docs/src/components/HomepageFeatures/index.tsx b/packages/docs/src/components/HomepageFeatures/index.tsx deleted file mode 100644 index c2551fb..0000000 --- a/packages/docs/src/components/HomepageFeatures/index.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import type {ReactNode} from 'react'; -import clsx from 'clsx'; -import Heading from '@theme/Heading'; -import styles from './styles.module.css'; - -type FeatureItem = { - title: string; - Svg: React.ComponentType>; - description: ReactNode; -}; - -const FeatureList: FeatureItem[] = [ - { - title: 'Easy to Use', - Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, - description: ( - <> - Docusaurus was designed from the ground up to be easily installed and - used to get your website up and running quickly. - - ), - }, - { - title: 'Focus on What Matters', - Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, - description: ( - <> - Docusaurus lets you focus on your docs, and we'll do the chores. Go - ahead and move your docs into the docs directory. - - ), - }, - { - title: 'Powered by React', - Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, - description: ( - <> - Extend or customize your website layout by reusing React. Docusaurus can - be extended while reusing the same header and footer. - - ), - }, -]; - -function Feature({title, Svg, description}: FeatureItem) { - return ( -
-
- -
-
- {title} -

{description}

-
-
- ); -} - -export default function HomepageFeatures(): ReactNode { - return ( -
-
-
- {FeatureList.map((props, idx) => ( - - ))} -
-
-
- ); -} diff --git a/packages/docs/src/components/HomepageFeatures/styles.module.css b/packages/docs/src/components/HomepageFeatures/styles.module.css deleted file mode 100644 index b248eb2..0000000 --- a/packages/docs/src/components/HomepageFeatures/styles.module.css +++ /dev/null @@ -1,11 +0,0 @@ -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureSvg { - height: 200px; - width: 200px; -} diff --git a/packages/docs/src/css/custom.css b/packages/docs/src/css/custom.css index 2bc6a4c..aa3946b 100644 --- a/packages/docs/src/css/custom.css +++ b/packages/docs/src/css/custom.css @@ -1,30 +1,37 @@ -/** - * Any CSS included here will be global. The classic template - * bundles Infima by default. Infima is a CSS framework designed to - * work well for content-centric websites. - */ - -/* You can override the default Infima variables here. */ :root { - --ifm-color-primary: #2e8555; - --ifm-color-primary-dark: #29784c; - --ifm-color-primary-darker: #277148; - --ifm-color-primary-darkest: #205d3b; - --ifm-color-primary-light: #33925d; - --ifm-color-primary-lighter: #359962; - --ifm-color-primary-lightest: #3cad6e; + --ifm-color-primary: #0b6f74; + --ifm-color-primary-dark: #096469; + --ifm-color-primary-darker: #085e63; + --ifm-color-primary-darkest: #074d51; + --ifm-color-primary-light: #0d7a7f; + --ifm-color-primary-lighter: #0e8085; + --ifm-color-primary-lightest: #109096; + --ifm-background-color: #fffaf1; --ifm-code-font-size: 95%; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); + --ifm-font-family-base: + "Avenir Next", "Segoe UI", "Helvetica Neue", sans-serif; + --docusaurus-highlighted-code-line-bg: rgba(11, 111, 116, 0.1); } -/* For readability concerns, you should choose a lighter palette in dark mode. */ -[data-theme='dark'] { - --ifm-color-primary: #25c2a0; - --ifm-color-primary-dark: #21af90; - --ifm-color-primary-darker: #1fa588; - --ifm-color-primary-darkest: #1a8870; - --ifm-color-primary-light: #29d5b0; - --ifm-color-primary-lighter: #32d8b4; - --ifm-color-primary-lightest: #4fddbf; - --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +.button--primary { + --ifm-button-background-color: #0b6f74; + --ifm-button-border-color: #0b6f74; +} + +.button--secondary { + --ifm-button-background-color: #f4a636; + --ifm-button-border-color: #f4a636; + --ifm-button-color: #1f2526; +} + +[data-theme="dark"] { + --ifm-color-primary: #7ad6d4; + --ifm-color-primary-dark: #5cccca; + --ifm-color-primary-darker: #4cc6c4; + --ifm-color-primary-darkest: #34aaa8; + --ifm-color-primary-light: #98e0de; + --ifm-color-primary-lighter: #a8e6e4; + --ifm-color-primary-lightest: #d5f4f3; + --ifm-background-color: #111c1f; + --docusaurus-highlighted-code-line-bg: rgba(122, 214, 212, 0.18); } diff --git a/packages/docs/src/pages/index.module.css b/packages/docs/src/pages/index.module.css index 9f71a5d..8d4db16 100644 --- a/packages/docs/src/pages/index.module.css +++ b/packages/docs/src/pages/index.module.css @@ -1,23 +1,80 @@ -/** - * CSS files with the .module.css suffix will be treated as CSS modules - * and scoped locally. - */ +.page { + min-height: calc(100vh - var(--ifm-navbar-height)); + background: + radial-gradient(circle at top left, rgba(11, 111, 116, 0.22), transparent 32rem), + radial-gradient(circle at 85% 20%, rgba(244, 166, 54, 0.18), transparent 28rem), + linear-gradient(135deg, #f8f4ea 0%, #eef8f7 48%, #fffaf1 100%); +} -.heroBanner { - padding: 4rem 0; - text-align: center; - position: relative; - overflow: hidden; +.hero { + padding: 8rem 1rem 5rem; +} + +.eyebrow { + color: #0b6f74; + font-size: 0.85rem; + font-weight: 800; + letter-spacing: 0.16em; + margin-bottom: 1.25rem; + text-transform: uppercase; +} + +.hero h1 { + color: #132c2f; + font-size: clamp(3rem, 9vw, 6.75rem); + letter-spacing: -0.08em; + line-height: 0.9; + margin: 0; + max-width: 880px; +} + +.lede { + color: #385256; + font-size: clamp(1.15rem, 2vw, 1.45rem); + line-height: 1.65; + margin: 2rem 0 0; + max-width: 720px; +} + +.actions { + display: flex; + flex-wrap: wrap; + gap: 1rem; + margin-top: 2.5rem; +} + +.cards { + display: grid; + gap: 1.25rem; + grid-template-columns: repeat(3, minmax(0, 1fr)); + padding: 0 1rem 6rem; +} + +.cards article { + background: rgba(255, 255, 255, 0.74); + border: 1px solid rgba(19, 44, 47, 0.12); + border-radius: 1.5rem; + box-shadow: 0 24px 80px rgba(19, 44, 47, 0.08); + padding: 1.5rem; +} + +.cards h2 { + color: #132c2f; + font-size: 1.2rem; + margin-bottom: 0.75rem; +} + +.cards p { + color: #486267; + margin: 0; } @media screen and (max-width: 996px) { - .heroBanner { - padding: 2rem; + .hero { + padding-top: 5rem; + } + + .cards { + grid-template-columns: 1fr; } } - -.buttons { - display: flex; - align-items: center; - justify-content: center; -} diff --git a/packages/docs/src/pages/index.tsx b/packages/docs/src/pages/index.tsx index 0a49f5d..90d003f 100644 --- a/packages/docs/src/pages/index.tsx +++ b/packages/docs/src/pages/index.tsx @@ -1,44 +1,62 @@ -import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import HomepageFeatures from '@site/src/components/HomepageFeatures'; -import Heading from '@theme/Heading'; -import Layout from '@theme/Layout'; -import clsx from 'clsx'; -import type {ReactNode} from 'react'; +import Link from "@docusaurus/Link" +import Layout from "@theme/Layout" +import clsx from "clsx" +import type { ReactNode } from "react" -import styles from './index.module.css'; - -function HomepageHeader() { - const {siteConfig} = useDocusaurusContext(); - return ( -
-
- - {siteConfig.title} - -

{siteConfig.tagline}

-
- - Docusaurus Tutorial - 5min ⏱️ - -
-
-
- ); -} +import styles from "./index.module.css" export default function Home(): ReactNode { - const {siteConfig} = useDocusaurusContext(); return ( - -
- + title="effect-fc" + description="Write React function components with Effect" + > +
+
+

Effect for React function components

+

Write components as Effect programs.

+

+ effect-fc gives React 19 components access to Effect services, + scopes, subscriptions, and async workflows without giving up normal + React boundaries. +

+
+ + Get Started + + + GitHub + +
+
+ +
+
+

Generator components

+

+ Use Component.make to yield Effects and return JSX + from the same component body. +

+
+
+

Runtime at the edge

+

+ Provide your app layer once with ReactRuntime.Provider + and convert Effect-FC components at React boundaries. +

+
+
+

Scoped lifecycles

+

+ Tie subscriptions and resources to component scopes so finalizers + run when React unmounts. +

+
+
- ); + ) } diff --git a/packages/docs/src/pages/markdown-page.md b/packages/docs/src/pages/markdown-page.md deleted file mode 100644 index 9756c5b..0000000 --- a/packages/docs/src/pages/markdown-page.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Markdown page example ---- - -# Markdown page example - -You don't need React to write simple standalone pages. diff --git a/packages/docs/static/img/docusaurus-social-card.jpg b/packages/docs/static/img/docusaurus-social-card.jpg deleted file mode 100644 index ffcb448210e1a456cb3588ae8b396a597501f187..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55746 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
sH`pxVp$E*LSx0bY$^ho1gZ(Ce+BX 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 fgzs%Vr*-jYG(YMS<ttdtee# diff --git a/packages/docs/static/img/docusaurus.png b/packages/docs/static/img/docusaurus.png deleted file mode 100644 index f458149e3c8f53335f28fbc162ae67f55575c881..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5142 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 F{0H{b<4^zq diff --git a/packages/docs/static/img/logo.svg b/packages/docs/static/img/logo.svg index 9db6d0d..9fb9b2b 100644 --- a/packages/docs/static/img/logo.svg +++ b/packages/docs/static/img/logo.svg @@ -1 +1,6 @@ - \ No newline at end of file + + + + + + diff --git a/packages/docs/static/img/undraw_docusaurus_mountain.svg b/packages/docs/static/img/undraw_docusaurus_mountain.svg deleted file mode 100644 index af961c4..0000000 --- a/packages/docs/static/img/undraw_docusaurus_mountain.svg +++ /dev/null @@ -1,171 +0,0 @@ - - Easy to Use - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/docs/static/img/undraw_docusaurus_react.svg b/packages/docs/static/img/undraw_docusaurus_react.svg deleted file mode 100644 index 94b5cf0..0000000 --- a/packages/docs/static/img/undraw_docusaurus_react.svg +++ /dev/null @@ -1,170 +0,0 @@ - - Powered by React - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/docs/static/img/undraw_docusaurus_tree.svg b/packages/docs/static/img/undraw_docusaurus_tree.svg deleted file mode 100644 index d9161d3..0000000 --- a/packages/docs/static/img/undraw_docusaurus_tree.svg +++ /dev/null @@ -1,40 +0,0 @@ - - Focus on What Matters - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/docs/tsconfig.json b/packages/docs/tsconfig.json index 920d7a6..ae701a6 100644 --- a/packages/docs/tsconfig.json +++ b/packages/docs/tsconfig.json @@ -2,7 +2,8 @@ // This file is not used in compilation. It is here just for a nice editor experience. "extends": "@docusaurus/tsconfig", "compilerOptions": { - "baseUrl": "." + "baseUrl": ".", + "ignoreDeprecations": "6.0" }, "exclude": [".docusaurus", "build"] } -- 2.52.0 From 25fac0ca328bfbcfeee49a5ba12da4d50d51c749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 8 Jun 2026 15:35:15 +0200 Subject: [PATCH 07/61] Fix --- bun.lock | 686 +++++++++++++++++++++++++++---------------------------- 1 file changed, 332 insertions(+), 354 deletions(-) diff --git a/bun.lock b/bun.lock index bc1bfa4..a30a084 100644 --- a/bun.lock +++ b/bun.lock @@ -82,247 +82,249 @@ }, }, "packages": { - "@algolia/abtesting": ["@algolia/abtesting@1.16.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-alHFZ68/i9qLC/muEB07VQ9r7cB8AvCcGX6dVQi2PNHhc/ZQRmmFAv8KK1ay4UiseGSFr7f0nXBKsZ/jRg7e4g=="], + "@algolia/abtesting": ["@algolia/abtesting@1.19.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-Lhnez3hhXHk25lfxLAMxvkP4fmN3+1RgADhD2ssMDBYuAsDVReeyP+3SGRx+ntq8ijMrLqUyfvO72TB6jsTteQ=="], - "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.19.2", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", "@algolia/autocomplete-shared": "1.19.2" } }, "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw=="], + "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.19.8", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.19.8", "@algolia/autocomplete-shared": "1.19.8" } }, "sha512-3YEorYg44niXcm7gkft3nXYItHd44e8tmh4D33CTszPgP0QWkaLEaFywiNyJBo7UL/mqObA/G9RYuU7R8tN1IA=="], - "@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.19.2", "", { "dependencies": { "@algolia/autocomplete-shared": "1.19.2" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg=="], + "@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.19.8", "", { "dependencies": { "@algolia/autocomplete-shared": "1.19.8" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-ZvJWO8ZZJDpc1LNM2TTBdmQsZBLMR4rU5iNR2OYvEeFBiaf/0ESnRSSLQbryarJY4SVxtoz6A2ZtDMNM+iQEAA=="], - "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.19.2", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w=="], + "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.19.8", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-h5hf2t8ejF6vlOgvLaZzQbWs5SyH2z4PAWygNAvvD/2RI29hdQ54ldUGwqVuj9Srs+n8XUKTPUqb7fvhBhQrnQ=="], - "@algolia/client-abtesting": ["@algolia/client-abtesting@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-mfgUdLQNxOAvCZUGzPQxjahEWEPuQkKlV0ZtGmePOa9ZxIQZlk31vRBNbM6ScU8jTH41SCYE77G/lCifDr1SVw=="], + "@algolia/client-abtesting": ["@algolia/client-abtesting@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-0ZjA5Hcmaoz5Lj6OG0zhfIyeqzJZnLW2CRJA1W17UwMFGRtZAJ9yJKRvPEDA6gkpsIoQxORTSW6sWFiuYncPNQ=="], - "@algolia/client-analytics": ["@algolia/client-analytics@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-5mjokeKYyPaP3Q8IYJEnutI+O4dW/Ixxx5IgsSxT04pCfGqPXxTOH311hTQxyNpcGGEOGrMv8n8Z+UMTPamioQ=="], + "@algolia/client-analytics": ["@algolia/client-analytics@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-kWNodP75iiEaOtemC9F/hlxNBG5E2QUjN1BusnE6m2b4l7Qh/BUO3fGCVsmKJI65VO4VKGGmT43ICvHtTcJ2JQ=="], - "@algolia/client-common": ["@algolia/client-common@5.50.0", "", {}, "sha512-emtOvR6dl3rX3sBJXXbofMNHU1qMQqQSWu319RMrNL5BWoBqyiq7y0Zn6cjJm7aGHV/Qbf+KCCYeWNKEMPI3BQ=="], + "@algolia/client-common": ["@algolia/client-common@5.53.0", "", {}, "sha512-YPN45TXD9Wrse185t/Ta7nktZsqpv97oOjCzp2sblHnCL6rBc9TDeJAg1IGl2UpdwnSD05Zu/5wLB4watOUMyg=="], - "@algolia/client-insights": ["@algolia/client-insights@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-IerGH2/hcj/6bwkpQg/HHRqmlGN1XwygQWythAk0gZFBrghs9danJaYuSS3ShzLSVoIVth4jY5GDPX9Lbw5cgg=="], + "@algolia/client-insights": ["@algolia/client-insights@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-qAcYTDJE6m924FDDUQvdD6vh7DYaqOeSpFS74IP37/JRV0v4cGBauyxTF2WzDnokUylQDbqreoFIJZfg0Fitmw=="], - "@algolia/client-personalization": ["@algolia/client-personalization@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-3idPJeXn5L0MmgP9jk9JJqblrQ/SguN93dNK9z9gfgyupBhHnJMOEjrRYcVgTIfvG13Y04wO+Q0FxE2Ut8PVbA=="], + "@algolia/client-personalization": ["@algolia/client-personalization@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-fQaY+DkSJOpuUVUe8MQTwrdiKAqkJGhpDarB08duBn/sUv7Bkib6MDRQauCcWTWTe4HIW+EbwQP9R4kci1V/Yw=="], - "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-q7qRoWrQK1a8m5EFQEmPlo7+pg9mVQ8X5jsChtChERre0uS2pdYEDixBBl0ydBSGkdGbLUDufcACIhH/077E4g=="], + "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-o72tsiEZGfeS/dxL9IADfzcZWGEwKDEe5CvtrBuT//3JR+SHuTtHRI2ZTf7D7bcKagcbojvO8hnkHdfoakSlYg=="], - "@algolia/client-search": ["@algolia/client-search@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-Jc360x4yqb3eEg4OY4KEIdGePBxZogivKI+OGIU8aLXgAYPTECvzeOBc90312yHA1hr3AeRlAFl0rIc8lQaIrQ=="], + "@algolia/client-search": ["@algolia/client-search@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-Ds16IyPm/dNJPCU8OzApo2gwGrgWT5BYHhE3NFwZbpCveqyvPDB9sZDDkJ5DsdOGT2aC+R3i0/M1OVXF2qdgPg=="], "@algolia/events": ["@algolia/events@4.0.1", "", {}, "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ=="], - "@algolia/ingestion": ["@algolia/ingestion@1.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-OS3/Viao+NPpyBbEY3tf6hLewppG+UclD+9i0ju56mq2DrdMJFCkEky6Sk9S5VPcbLzxzg3BqBX6u9Q35w19aQ=="], + "@algolia/ingestion": ["@algolia/ingestion@1.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-oNbT6z4NwD8Pou9VPINGlN/tlG1afESh2EbxqnP6rwl95xKVD/Zlciis1PpNeO/9U/rrajc1+7DcfKi03tX1KQ=="], - "@algolia/monitoring": ["@algolia/monitoring@1.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-/znwgSiGufpbJVIoDmeQaHtTq+OMdDawFRbMSJVv+12n79hW+qdQXS8/Uu3BD3yn0BzgVFJEvrsHrCsInZKdhw=="], + "@algolia/monitoring": ["@algolia/monitoring@1.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-G+KZb/yd+qAOFn/cEvTGeLxQm8aP3a0od50l3z/ylccY+/o4YG3TNcjU1tFQHW4mXC137GPyR7W70R0kRQDLnA=="], - "@algolia/recommend": ["@algolia/recommend@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-dHjUfu4jfjdQiKDpCpAnM7LP5yfG0oNShtfpF5rMCel6/4HIoqJ4DC4h5GKDzgrvJYtgAhblo0AYBmOM00T+lQ=="], + "@algolia/recommend": ["@algolia/recommend@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-6aVfYd55Un6IUgPLbo84WfgFZlS3L0vA1ttzXL5vahHewUJ8jYgd89TzlWRTeej7w70mb9RWsVlFYGmJ/diQww=="], - "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0" } }, "sha512-bffIbUljAWnh/Ctu5uScORajuUavqmZ0ACYd1fQQeSSYA9NNN83ynO26pSc2dZRXpSK0fkc1//qSSFXMKGu+aw=="], + "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0" } }, "sha512-ke27DqgzCOlt+RbeEdCxtXxMQOnAOi8ujr2wid0DmDKzR95Kw/f9sBsuhBxtjevCqJRJszfRTLY0B1pbO6IhkA=="], - "@algolia/requester-fetch": ["@algolia/requester-fetch@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0" } }, "sha512-y0EwNvPGvkM+yTAqqO6Gpt9wVGm3CLDtpLvNEiB3VGvN3WzfkjZGtLUsG/ru2kVJIIU7QcV0puuYgEpBeFxcJg=="], + "@algolia/requester-fetch": ["@algolia/requester-fetch@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0" } }, "sha512-GngiOqt2Gq4oLno6yXQVj9om+qSO9SWAoduoTOEg79dKZ62brB8OOIvSJG/vDNoanYi6a7Al9uDZwXvi+bcVTg=="], - "@algolia/requester-node-http": ["@algolia/requester-node-http@5.50.0", "", { "dependencies": { "@algolia/client-common": "5.50.0" } }, "sha512-xpwefe4fCOWnZgXCbkGpqQY6jgBSCf2hmgnySbyzZIccrv3SoashHKGPE4x6vVG+gdHrGciMTAcDo9HOZwH22Q=="], + "@algolia/requester-node-http": ["@algolia/requester-node-http@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0" } }, "sha512-6mF9LZMUk0QqWvrnxkxBqhswwz6Xfiwy6/gmTzL5HrlhdVG3ITAqGV2k3XmVThP1h0Ulc3VQwiNCD7/Nr4JNlQ=="], "@asamuzakjp/css-color": ["@asamuzakjp/css-color@3.2.0", "", { "dependencies": { "@csstools/css-calc": "^2.1.3", "@csstools/css-color-parser": "^3.0.9", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw=="], - "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], + "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], - "@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="], + "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="], - "@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="], + "@babel/core": ["@babel/core@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-module-transforms": "^7.29.7", "@babel/helpers": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/template": "^7.29.7", "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA=="], - "@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], + "@babel/generator": ["@babel/generator@7.29.7", "", { "dependencies": { "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ=="], - "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="], + "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" } }, "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw=="], - "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="], + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.29.7", "", { "dependencies": { "@babel/compat-data": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g=="], - "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.6", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow=="], + "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-member-expression-to-functions": "^7.29.7", "@babel/helper-optimise-call-expression": "^7.29.7", "@babel/helper-replace-supers": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", "@babel/traverse": "^7.29.7", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg=="], - "@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw=="], + "@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "regexpu-core": "^6.3.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg=="], "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.8", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "debug": "^4.4.3", "lodash.debounce": "^4.0.8", "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA=="], - "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], + "@babel/helper-globals": ["@babel/helper-globals@7.29.7", "", {}, "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA=="], - "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="], + "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg=="], - "@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="], + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g=="], - "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="], + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg=="], - "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="], + "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" } }, "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong=="], - "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.28.6", "", {}, "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug=="], + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.29.7", "", {}, "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw=="], - "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-wrap-function": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA=="], + "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-wrap-function": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og=="], - "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.28.6", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg=="], + "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.29.7", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.29.7", "@babel/helper-optimise-call-expression": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ=="], - "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="], + "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.29.7", "", { "dependencies": { "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ=="], - "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], - "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], + "@babel/helper-validator-option": ["@babel/helper-validator-option@7.29.7", "", {}, "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw=="], - "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ=="], + "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.29.7", "", { "dependencies": { "@babel/template": "^7.29.7", "@babel/traverse": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw=="], - "@babel/helpers": ["@babel/helpers@7.29.2", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.29.0" } }, "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw=="], + "@babel/helpers": ["@babel/helpers@7.29.7", "", { "dependencies": { "@babel/template": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg=="], - "@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], + "@babel/parser": ["@babel/parser@7.29.7", "", { "dependencies": { "@babel/types": "^7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="], - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q=="], + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-j8SrR0zLZrRsC09DlszEx8FpMiwukKffYXMK0d5LmOglO7vGG6sz/BR/20yHqWH+Lnn31JTt2PE3hIWNgM2J6w=="], - "@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA=="], + "@babel/plugin-bugfix-safari-class-field-initializer-scope": ["@babel/plugin-bugfix-safari-class-field-initializer-scope@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-r8j8escF+U2FUHo0KOhPUdMzUO+jp9fInva6+ACVAF3Y97Ev+5iNZwiqTghmzNeWwDkOPlYuTcfb1vDaoZKmAQ=="], - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA=="], + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ["@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-GE1TFSiuFeGsCxmYXZl8HwoPrVlwe4rHPFE8weieGKZqnDORK+Ar3vgWMgW+AOxQ6/2TgLSKx9p6W7O4rC6qgQ=="], - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-transform-optional-chaining": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw=="], + "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": ["@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-oBNVCvnO5tND+xSopWvV8WNGfpTfgP4Zr/YXXSj8zfmcPktp5Ku/aZlsIowgSD4fjmgHn6sGmB9APVsU5zOdhA=="], - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g=="], + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ["@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", "@babel/plugin-transform-optional-chaining": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.13.0" } }, "sha512-QQt9qKHZ2sg/kivaLr7lnQr8HVrQDdBNSfCsTjiDxRuX/K5ORyKq+Bu8Xr0cDE3Dfkv0cw28Ve0EKyKMvulkOw=="], + + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ["@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-pn6QacGLgvCcwc+syUhKE/qSjV2D1IHDB84RNxWYSt1mW3K/SCtjinZ2p0cETJxAWBjPy3K/1lHwG5BjjPxNlw=="], "@babel/plugin-proposal-private-property-in-object": ["@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2", "", { "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w=="], "@babel/plugin-syntax-dynamic-import": ["@babel/plugin-syntax-dynamic-import@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ=="], - "@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw=="], + "@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-/An1OCBN93thpBAGyfsK2pcf0jvju1SAtKkL2Ny++B5Sy6sqgzXDQH1cZxWbF96Wuk+bn41MDA9bLd4VVAw6rw=="], - "@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw=="], + "@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg=="], - "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w=="], + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A=="], - "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A=="], + "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA=="], "@babel/plugin-syntax-unicode-sets-regex": ["@babel/plugin-syntax-unicode-sets-regex@7.18.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg=="], - "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA=="], + "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ=="], - "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.29.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1", "@babel/traverse": "^7.29.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w=="], + "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-remap-async-to-generator": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA=="], - "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g=="], + "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-remap-async-to-generator": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w=="], - "@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg=="], + "@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-cUSmjh72N+rN4PrkFlN1dJwNCwjVp5d38/CQrEsFggkD10UiFlBFgdH3tv5dNsLuHY+3S8db2xCHjhZcv5WgvA=="], - "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw=="], + "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ=="], - "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.28.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw=="], + "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA=="], - "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.28.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ=="], + "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A=="], - "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-replace-supers": "^7.28.6", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q=="], + "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-globals": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-replace-supers": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g=="], - "@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/template": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ=="], + "@babel/plugin-transform-computed-properties": ["@babel/plugin-transform-computed-properties@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/template": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RK7/IyU5phpuCdBAuig5VkzG/EnbDaui5SQGdU9BFrHdV+mV4cUjLMQ9lJDjLNtWHsqtiefpGZUXQP2BiTYMsA=="], - "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw=="], + "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg=="], - "@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.28.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg=="], + "@babel/plugin-transform-dotall-regex": ["@babel/plugin-transform-dotall-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-3qc18hsD2RdZiyJNDNc7HQpv6xbncwh8FYtxNFFzclSyh/trPD9KkVR9BDECUjDLvb7yJVF15GfYUuC+LMkkiQ=="], - "@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q=="], + "@babel/plugin-transform-duplicate-keys": ["@babel/plugin-transform-duplicate-keys@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6IvRRriEMqnBwD6chtxdLpMYCHWEzN+oL5cyQtjykya19UgzbmKhxmhZgKC/LHxS2nYr9Q/qYPZ5Lr6jOL9+yQ=="], - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw=="], + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ["@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-2wiIyo2BjtgU7HufSeDnL9L2O7zr8jmhFKuSr65VpRkUiRKRNpb0mdlk56+XPPKoIrfHqzbMuglDvZun0RISsA=="], - "@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A=="], + "@babel/plugin-transform-dynamic-import": ["@babel/plugin-transform-dynamic-import@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-giOlEm/EFjfjr+te9NsdjkUo2v4f8rS/SXPumRVHAtbNcyNlvtREkU1dZzaIDclNpnaVhlCqRdFKhJBjBikzLg=="], - "@babel/plugin-transform-explicit-resource-management": ["@babel/plugin-transform-explicit-resource-management@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg=="], + "@babel/plugin-transform-explicit-resource-management": ["@babel/plugin-transform-explicit-resource-management@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/plugin-transform-destructuring": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Rstj7coNz8sE+7Ju7ihpHLI564lsK5pUpNNlvptCIC/16E/S5hbl6n3kESPKdNRmqEWlpn5xpS5Q2dvXBsySLw=="], - "@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw=="], + "@babel/plugin-transform-exponentiation-operator": ["@babel/plugin-transform-exponentiation-operator@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zFpMOTLZBdW5LfObqcSbL6kefg4R4eLdmvS0wbN9M6D5Mym/sKm9toOoWyVOa+xDjvCnuWcHls2YonXwHvH3CQ=="], - "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ=="], + "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA=="], - "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw=="], + "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ=="], - "@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.27.1", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ=="], + "@babel/plugin-transform-function-name": ["@babel/plugin-transform-function-name@7.29.7", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-otRWaHXE6fbAGkePvaj/kvs3HsqXfPhlnzwSOlnFgbqCPMd975dW+4wZ00WFBt+/YlBGcJwNrARQTOJOb4ZrIg=="], - "@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw=="], + "@babel/plugin-transform-json-strings": ["@babel/plugin-transform-json-strings@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RRnE2+eon1rJAq8MnoF1b5kTpY1vU88twHcvcKMrsqP/jxIRqDVs9iJB5fqPuqyeFAW0wJo4MlUIPpQCq/aRsg=="], - "@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA=="], + "@babel/plugin-transform-literals": ["@babel/plugin-transform-literals@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-DZ/oLP21ZuWx1vKqnoNv6/tvEK48AQOBRai40CX9dTjGluvT/YZCyY3rryDtyUqCEoyNroy5KKPwX2iQCiRvyw=="], - "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A=="], + "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q=="], - "@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ=="], + "@babel/plugin-transform-member-expression-literals": ["@babel/plugin-transform-member-expression-literals@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-hl1kwFZCCiDyfH25Xmco9jTrkPgnS9pmOzSG7W5I4SaGbLeqKv417hcU2RKmaxoPEgsoJh7ZPOrnPGq99bHoUg=="], - "@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA=="], + "@babel/plugin-transform-modules-amd": ["@babel/plugin-transform-modules-amd@7.29.7", "", { "dependencies": { "@babel/helper-module-transforms": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fxtQoH3m5ywUSIfaH0FGCzWu4McsYon5bD3K4XnskC7f+OyQMj7rsOMi4NvvmJ83WwBAg4UCe+ov4VZlqEvyew=="], - "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.28.6", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA=="], + "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.29.7", "", { "dependencies": { "@babel/helper-module-transforms": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ=="], - "@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.29.0", "", { "dependencies": { "@babel/helper-module-transforms": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.29.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ=="], + "@babel/plugin-transform-modules-systemjs": ["@babel/plugin-transform-modules-systemjs@7.29.7", "", { "dependencies": { "@babel/helper-module-transforms": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TM2ZcQLoG2/y4HODiStCo10DibYhWhGWAwVv+EQKmG/7GFl0N+AAmUiXOMKM+aiJ9XBJ9AHVZBvTzMnJ2sM3cQ=="], - "@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w=="], + "@babel/plugin-transform-modules-umd": ["@babel/plugin-transform-modules-umd@7.29.7", "", { "dependencies": { "@babel/helper-module-transforms": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-B4UkaTK3QpgCwJnrxKfMPKdo92CN7OKXAlpAAnM3UPu0Q0lCCk57ylA9AJbRy2v8dDKOPAAWcoR6CMyeoHwRCA=="], - "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.29.0", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ=="], + "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ=="], - "@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ=="], + "@babel/plugin-transform-new-target": ["@babel/plugin-transform-new-target@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fEo41GmsOUhOBlw8ioo6zvjX5Xc2Lqkzlyfqbpsk3eB6TReV18uhxZ0esfEokVbY2+PVJAQHNKxER6lGrzNd3A=="], - "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg=="], + "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg=="], - "@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w=="], + "@babel/plugin-transform-numeric-separator": ["@babel/plugin-transform-numeric-separator@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zR7fv/z14OjgHl4AgRtkDBvBMhIzCxqV/qN/2BCRC7LjFwvuzjYe7gDWxC4Wl/SNsLM6SE1IWvRPYMgSJaUvNw=="], - "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.28.6", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA=="], + "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.29.7", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/plugin-transform-destructuring": "^7.29.7", "@babel/plugin-transform-parameters": "^7.29.7", "@babel/traverse": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A=="], - "@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng=="], + "@babel/plugin-transform-object-super": ["@babel/plugin-transform-object-super@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-replace-supers": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ea/diGcw0twB5IlZPO5sgET6fJsLJqPABqTuFWIR+iMPGPZJkATEIWx0wa+aEQ5UY1CBQyP/gkAiLEqn1vBiQA=="], - "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ=="], + "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng=="], - "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w=="], + "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ=="], - "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.27.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg=="], + "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g=="], - "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.28.6", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg=="], + "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug=="], - "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA=="], + "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA=="], - "@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ=="], + "@babel/plugin-transform-property-literals": ["@babel/plugin-transform-property-literals@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bOMRLQuI0A5ZqHq3OWJ89/rXpJ/NJrbVhXiP4zwPGMs6kpcVsuTUNjwoE30K0Qm3mf48a/TnRYYD6vPNqcg6jA=="], - "@babel/plugin-transform-react-constant-elements": ["@babel/plugin-transform-react-constant-elements@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug=="], + "@babel/plugin-transform-react-constant-elements": ["@babel/plugin-transform-react-constant-elements@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-J0wGhKan+rIiE2OhfhRptySLrJ6SjQYM6b6N1FMlhyhCcw1Mig8vQjWchyB+bgHGDvaWo6Diu6CLRMra2uMtmg=="], - "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.28.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA=="], + "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q=="], - "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-module-imports": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/plugin-syntax-jsx": "^7.28.6", "@babel/types": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow=="], + "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-module-imports": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/plugin-syntax-jsx": "^7.29.7", "@babel/types": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A=="], - "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.27.1", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q=="], + "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.29.7", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g=="], - "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA=="], + "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA=="], - "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.29.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog=="], + "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw=="], - "@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.28.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg=="], + "@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-mB5Fs0VWrJ42ZCmc8114v60qetdaUVNkj9PmSZRmanCZM3S9hm0CFRLjRmYIsuXav14l2jvZ+4T8iiCGnhj3nQ=="], - "@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw=="], + "@babel/plugin-transform-reserved-words": ["@babel/plugin-transform-reserved-words@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5+YhdpVgmfSmwZyLMftfaiffLRMHjzIRHFHHLdibcSyJm2pasMrKHrO3Ptrt2DRshjvpgjEJJ1zVW14WPq/6QA=="], - "@babel/plugin-transform-runtime": ["@babel/plugin-transform-runtime@7.29.0", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jlaRT5dJtMaMCV6fAuLbsQMSwz/QkvaHOHOSXRitGGwSpR1blCY4KUKoyP2tYO8vJcqYe8cEj96cqSztv3uF9w=="], + "@babel/plugin-transform-runtime": ["@babel/plugin-transform-runtime@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "babel-plugin-polyfill-corejs2": "^0.4.14", "babel-plugin-polyfill-corejs3": "^0.13.0", "babel-plugin-polyfill-regenerator": "^0.6.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q=="], - "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ=="], + "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg=="], - "@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA=="], + "@babel/plugin-transform-spread": ["@babel/plugin-transform-spread@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-/u5K1QWada7tbYNqTjMh96718g9NTwh9tfPJMsSmVsQwGT447FskV+KcfeXkXq2GWki4EM/MuTdmBec+hOuVTQ=="], - "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g=="], + "@babel/plugin-transform-sticky-regex": ["@babel/plugin-transform-sticky-regex@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-BCHzNYJGe9l7EpwwDBN/ztlL2NYFFq8hp9ddjtUEM9f2O7S7kKV/lL6Fwo7IF7NSkYhPK2vO+86nIGltA90MsA=="], - "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg=="], + "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NCSEJ4sLFU2gqAub45HYh4fus2yQ36rr6ei6vpU7NdoJqCpxvEG8E6eJpscGyXP3VHD2Ny+fSXr04k1hoUrFqA=="], - "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw=="], + "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-223mNGoTkBiTEWFoK+Q6Go3tueMRclO8vxxxxquNCYuNI4jWOofFKJRRDu6SDrB8Sgo1UEGW9T4GAQ8ZyRso1A=="], - "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw=="], + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.29.7", "@babel/helper-create-class-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7", "@babel/plugin-syntax-typescript": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw=="], - "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg=="], + "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jCfXxSjf94lf4E0hKE0AByxF6F3/pVFqRdUUNkDJhsY0m1ZKjnN6ZYyMeHNpzflxb/0q5b7t3p+BE+SLF1WOtA=="], - "@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.28.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A=="], + "@babel/plugin-transform-unicode-property-regex": ["@babel/plugin-transform-unicode-property-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OgZ+zoAJgZLUCunsTRQ5LAjOywDv5zzZ2/hQ5aMw1pGXyY2rtE8/chXYUmu3AlVHKpm10KEdG9aMwbI/K76ZGw=="], - "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.27.1", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw=="], + "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA=="], - "@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.28.6", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q=="], + "@babel/plugin-transform-unicode-sets-regex": ["@babel/plugin-transform-unicode-sets-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-BLOhLht9DOJwIxlmp91wHvkXv1lguuHS3/FwUO8HL1H0u8s4hR1gASVFyilu9iGtcTRYqjTZmlsFFeQletntEg=="], - "@babel/preset-env": ["@babel/preset-env@7.29.2", "", { "dependencies": { "@babel/compat-data": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.28.6", "@babel/plugin-syntax-import-attributes": "^7.28.6", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", "@babel/plugin-transform-async-generator-functions": "^7.29.0", "@babel/plugin-transform-async-to-generator": "^7.28.6", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.6", "@babel/plugin-transform-class-properties": "^7.28.6", "@babel/plugin-transform-class-static-block": "^7.28.6", "@babel/plugin-transform-classes": "^7.28.6", "@babel/plugin-transform-computed-properties": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-dotall-regex": "^7.28.6", "@babel/plugin-transform-duplicate-keys": "^7.27.1", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-dynamic-import": "^7.27.1", "@babel/plugin-transform-explicit-resource-management": "^7.28.6", "@babel/plugin-transform-exponentiation-operator": "^7.28.6", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", "@babel/plugin-transform-json-strings": "^7.28.6", "@babel/plugin-transform-literals": "^7.27.1", "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.28.6", "@babel/plugin-transform-modules-systemjs": "^7.29.0", "@babel/plugin-transform-modules-umd": "^7.27.1", "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-new-target": "^7.27.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", "@babel/plugin-transform-numeric-separator": "^7.28.6", "@babel/plugin-transform-object-rest-spread": "^7.28.6", "@babel/plugin-transform-object-super": "^7.27.1", "@babel/plugin-transform-optional-catch-binding": "^7.28.6", "@babel/plugin-transform-optional-chaining": "^7.28.6", "@babel/plugin-transform-parameters": "^7.27.7", "@babel/plugin-transform-private-methods": "^7.28.6", "@babel/plugin-transform-private-property-in-object": "^7.28.6", "@babel/plugin-transform-property-literals": "^7.27.1", "@babel/plugin-transform-regenerator": "^7.29.0", "@babel/plugin-transform-regexp-modifiers": "^7.28.6", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", "@babel/plugin-transform-spread": "^7.28.6", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", "@babel/plugin-transform-unicode-property-regex": "^7.28.6", "@babel/plugin-transform-unicode-regex": "^7.27.1", "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.15", "babel-plugin-polyfill-corejs3": "^0.14.0", "babel-plugin-polyfill-regenerator": "^0.6.6", "core-js-compat": "^3.48.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw=="], + "@babel/preset-env": ["@babel/preset-env@7.29.7", "", { "dependencies": { "@babel/compat-data": "^7.29.7", "@babel/helper-compilation-targets": "^7.29.7", "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.29.7", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.29.7", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.29.7", "@babel/plugin-bugfix-safari-rest-destructuring-rhs-array": "^7.29.7", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.29.7", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.29.7", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.29.7", "@babel/plugin-syntax-import-attributes": "^7.29.7", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.29.7", "@babel/plugin-transform-async-generator-functions": "^7.29.7", "@babel/plugin-transform-async-to-generator": "^7.29.7", "@babel/plugin-transform-block-scoped-functions": "^7.29.7", "@babel/plugin-transform-block-scoping": "^7.29.7", "@babel/plugin-transform-class-properties": "^7.29.7", "@babel/plugin-transform-class-static-block": "^7.29.7", "@babel/plugin-transform-classes": "^7.29.7", "@babel/plugin-transform-computed-properties": "^7.29.7", "@babel/plugin-transform-destructuring": "^7.29.7", "@babel/plugin-transform-dotall-regex": "^7.29.7", "@babel/plugin-transform-duplicate-keys": "^7.29.7", "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.7", "@babel/plugin-transform-dynamic-import": "^7.29.7", "@babel/plugin-transform-explicit-resource-management": "^7.29.7", "@babel/plugin-transform-exponentiation-operator": "^7.29.7", "@babel/plugin-transform-export-namespace-from": "^7.29.7", "@babel/plugin-transform-for-of": "^7.29.7", "@babel/plugin-transform-function-name": "^7.29.7", "@babel/plugin-transform-json-strings": "^7.29.7", "@babel/plugin-transform-literals": "^7.29.7", "@babel/plugin-transform-logical-assignment-operators": "^7.29.7", "@babel/plugin-transform-member-expression-literals": "^7.29.7", "@babel/plugin-transform-modules-amd": "^7.29.7", "@babel/plugin-transform-modules-commonjs": "^7.29.7", "@babel/plugin-transform-modules-systemjs": "^7.29.7", "@babel/plugin-transform-modules-umd": "^7.29.7", "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.7", "@babel/plugin-transform-new-target": "^7.29.7", "@babel/plugin-transform-nullish-coalescing-operator": "^7.29.7", "@babel/plugin-transform-numeric-separator": "^7.29.7", "@babel/plugin-transform-object-rest-spread": "^7.29.7", "@babel/plugin-transform-object-super": "^7.29.7", "@babel/plugin-transform-optional-catch-binding": "^7.29.7", "@babel/plugin-transform-optional-chaining": "^7.29.7", "@babel/plugin-transform-parameters": "^7.29.7", "@babel/plugin-transform-private-methods": "^7.29.7", "@babel/plugin-transform-private-property-in-object": "^7.29.7", "@babel/plugin-transform-property-literals": "^7.29.7", "@babel/plugin-transform-regenerator": "^7.29.7", "@babel/plugin-transform-regexp-modifiers": "^7.29.7", "@babel/plugin-transform-reserved-words": "^7.29.7", "@babel/plugin-transform-shorthand-properties": "^7.29.7", "@babel/plugin-transform-spread": "^7.29.7", "@babel/plugin-transform-sticky-regex": "^7.29.7", "@babel/plugin-transform-template-literals": "^7.29.7", "@babel/plugin-transform-typeof-symbol": "^7.29.7", "@babel/plugin-transform-unicode-escapes": "^7.29.7", "@babel/plugin-transform-unicode-property-regex": "^7.29.7", "@babel/plugin-transform-unicode-regex": "^7.29.7", "@babel/plugin-transform-unicode-sets-regex": "^7.29.7", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.15", "babel-plugin-polyfill-corejs3": "^0.14.0", "babel-plugin-polyfill-regenerator": "^0.6.6", "core-js-compat": "^3.48.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GYzX36n1nsciIb0uyH0GHwxwtNwPQIcpxSeiVLDtG/B7jB5xXgchnmL1f/jCX5o+pwnaDBtO60ONSJhEBJfxYA=="], "@babel/preset-modules": ["@babel/preset-modules@0.1.6-no-external-plugins", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA=="], - "@babel/preset-react": ["@babel/preset-react@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-transform-react-display-name": "^7.28.0", "@babel/plugin-transform-react-jsx": "^7.27.1", "@babel/plugin-transform-react-jsx-development": "^7.27.1", "@babel/plugin-transform-react-pure-annotations": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ=="], + "@babel/preset-react": ["@babel/preset-react@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "@babel/plugin-transform-react-display-name": "^7.29.7", "@babel/plugin-transform-react-jsx": "^7.29.7", "@babel/plugin-transform-react-jsx-development": "^7.29.7", "@babel/plugin-transform-react-pure-annotations": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-C+PV1TFUPTmBQGoPBL8j2QmLpZ117YTCwxIZeJOM96GbYMFSc7/pOXU5lVykwnZxyTqQxRsvoRk6f2FktZgGHA=="], - "@babel/preset-typescript": ["@babel/preset-typescript@7.28.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.28.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g=="], + "@babel/preset-typescript": ["@babel/preset-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.29.7", "@babel/helper-validator-option": "^7.29.7", "@babel/plugin-syntax-jsx": "^7.29.7", "@babel/plugin-transform-modules-commonjs": "^7.29.7", "@babel/plugin-transform-typescript": "^7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ=="], - "@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="], + "@babel/runtime": ["@babel/runtime@7.29.7", "", {}, "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw=="], - "@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="], + "@babel/template": ["@babel/template@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/types": "^7.29.7" } }, "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg=="], - "@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="], + "@babel/traverse": ["@babel/traverse@7.29.7", "", { "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", "@babel/helper-globals": "^7.29.7", "@babel/parser": "^7.29.7", "@babel/template": "^7.29.7", "@babel/types": "^7.29.7", "debug": "^4.3.1" } }, "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw=="], - "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + "@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], "@biomejs/biome": ["@biomejs/biome@2.4.16", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.16", "@biomejs/cli-darwin-x64": "2.4.16", "@biomejs/cli-linux-arm64": "2.4.16", "@biomejs/cli-linux-arm64-musl": "2.4.16", "@biomejs/cli-linux-x64": "2.4.16", "@biomejs/cli-linux-x64-musl": "2.4.16", "@biomejs/cli-win32-arm64": "2.4.16", "@biomejs/cli-win32-x64": "2.4.16" }, "bin": { "biome": "bin/biome" } }, "sha512-x9ajFh1zChVybCiM3TN6OD4phAqLgtPZjFrZF+aTMYCPjwBO+k529TX7PPsAqtGNLeV4UgzwQnowEgS7bGmzcA=="], @@ -446,11 +448,11 @@ "@discoveryjs/json-ext": ["@discoveryjs/json-ext@0.5.7", "", {}, "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw=="], - "@docsearch/core": ["@docsearch/core@4.6.2", "", { "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", "react": ">= 16.8.0 < 20.0.0", "react-dom": ">= 16.8.0 < 20.0.0" }, "optionalPeers": ["@types/react", "react", "react-dom"] }, "sha512-/S0e6Dj7Zcm8m9Rru49YEX49dhU11be68c+S/BCyN8zQsTTgkKzXlhRbVL5mV6lOLC2+ZRRryaTdcm070Ug2oA=="], + "@docsearch/core": ["@docsearch/core@4.6.3", "", { "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", "react": ">= 16.8.0 < 20.0.0", "react-dom": ">= 16.8.0 < 20.0.0" }, "optionalPeers": ["@types/react", "react", "react-dom"] }, "sha512-rUOujwIpxJRgD7+kicVsI3D5sqBvdiRTquzWBpTEXZs8ZXfGbfzpus5HqumaNYTppN2HvH8E2yNuRwYdHJeOlA=="], - "@docsearch/css": ["@docsearch/css@4.6.2", "", {}, "sha512-fH/cn8BjEEdM2nJdjNMHIvOVYupG6AIDtFVDgIZrNzdCSj4KXr9kd+hsehqsNGYjpUjObeKYKvgy/IwCb1jZYQ=="], + "@docsearch/css": ["@docsearch/css@4.6.3", "", {}, "sha512-nlOwcXcsNAptQl4vlL4MA78qNJKO0Qlds5GuBjCoePgkebTXLSf8Qt1oyZ3YBshYupKXG9VRGEsk1zr23d+bzQ=="], - "@docsearch/react": ["@docsearch/react@4.6.2", "", { "dependencies": { "@algolia/autocomplete-core": "1.19.2", "@docsearch/core": "4.6.2", "@docsearch/css": "4.6.2" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", "react": ">= 16.8.0 < 20.0.0", "react-dom": ">= 16.8.0 < 20.0.0", "search-insights": ">= 1 < 3" }, "optionalPeers": ["@types/react", "react", "react-dom", "search-insights"] }, "sha512-/BbtGFtqVOGwZx0dw/UfhN/0/DmMQYnulY4iv0tPRhC2JCXv0ka/+izwt3Jzo1ZxXS/2eMvv9zHsBJOK1I9f/w=="], + "@docsearch/react": ["@docsearch/react@4.6.3", "", { "dependencies": { "@algolia/autocomplete-core": "1.19.2", "@docsearch/core": "4.6.3", "@docsearch/css": "4.6.3" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", "react": ">= 16.8.0 < 20.0.0", "react-dom": ">= 16.8.0 < 20.0.0", "search-insights": ">= 1 < 3" }, "optionalPeers": ["@types/react", "react", "react-dom", "search-insights"] }, "sha512-Bg2wdDsoQVlNCcEKuEJAU04tvHCqgx8rIu+uIoM4pRtcx3TBKJuXutJik3LTA8LRc9YEyHkrYUrmcC0D7BYf+g=="], "@docusaurus/babel": ["@docusaurus/babel@3.10.1", "", { "dependencies": { "@babel/core": "^7.25.9", "@babel/generator": "^7.25.9", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-transform-runtime": "^7.25.9", "@babel/preset-env": "^7.25.9", "@babel/preset-react": "^7.25.9", "@babel/preset-typescript": "^7.25.9", "@babel/runtime": "^7.25.9", "@babel/traverse": "^7.25.9", "@docusaurus/logger": "3.10.1", "@docusaurus/utils": "3.10.1", "babel-plugin-dynamic-import-node": "^2.3.3", "fs-extra": "^11.1.1", "tslib": "^2.6.0" } }, "sha512-DZzFO1K3v/GoEt1fx1DiYHF4en+PuhtQf1AkQJa5zu3CoeKSpr5cpQRUlz3jr0m44wyzmSXu9bVpfir+N4+8bg=="], @@ -608,21 +610,21 @@ "@jsonjoy.com/codegen": ["@jsonjoy.com/codegen@1.0.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g=="], - "@jsonjoy.com/fs-core": ["@jsonjoy.com/fs-core@4.57.1", "", { "dependencies": { "@jsonjoy.com/fs-node-builtins": "4.57.1", "@jsonjoy.com/fs-node-utils": "4.57.1", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA=="], + "@jsonjoy.com/fs-core": ["@jsonjoy.com/fs-core@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-uI++Wx6VkBJqVmkb4ZeExwAVpZiA2Do5NrEtXoDk0Pdvce3ytFXJoviT1sLOj16+qDIMnD5nWPfOhVpnDmRJKg=="], - "@jsonjoy.com/fs-fsa": ["@jsonjoy.com/fs-fsa@4.57.1", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.1", "@jsonjoy.com/fs-node-builtins": "4.57.1", "@jsonjoy.com/fs-node-utils": "4.57.1", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA=="], + "@jsonjoy.com/fs-fsa": ["@jsonjoy.com/fs-fsa@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.6", "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-pKkw/yC5CzSZKhIIUIsH1przOa+K5jGmZIg1sWaSF24JojyrUFbjcQv7QrcGAudriei6HQ6R0BFj+V8NbQinJw=="], - "@jsonjoy.com/fs-node": ["@jsonjoy.com/fs-node@4.57.1", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.1", "@jsonjoy.com/fs-node-builtins": "4.57.1", "@jsonjoy.com/fs-node-utils": "4.57.1", "@jsonjoy.com/fs-print": "4.57.1", "@jsonjoy.com/fs-snapshot": "4.57.1", "glob-to-regex.js": "^1.0.0", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ=="], + "@jsonjoy.com/fs-node": ["@jsonjoy.com/fs-node@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.6", "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6", "@jsonjoy.com/fs-print": "4.57.6", "@jsonjoy.com/fs-snapshot": "4.57.6", "glob-to-regex.js": "^1.0.0", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-Kbn1jdkvDN4F2+BhoB6mMu7NCbhP0bgA5NcI1aJj/Q5UcU+I1JLLW+dEQean33iV4tXv35AzBVKPICnDltBpxw=="], - "@jsonjoy.com/fs-node-builtins": ["@jsonjoy.com/fs-node-builtins@4.57.1", "", { "peerDependencies": { "tslib": "2" } }, "sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og=="], + "@jsonjoy.com/fs-node-builtins": ["@jsonjoy.com/fs-node-builtins@4.57.6", "", { "peerDependencies": { "tslib": "2" } }, "sha512-V4DgEFT3Cg5S9fCMOZSCVdTxdJWWLBO0WnAazV7hnCM96u5zXHyW/ubDAfcSVwqjkMJ50W1Y44IXtxRoIwaCVg=="], - "@jsonjoy.com/fs-node-to-fsa": ["@jsonjoy.com/fs-node-to-fsa@4.57.1", "", { "dependencies": { "@jsonjoy.com/fs-fsa": "4.57.1", "@jsonjoy.com/fs-node-builtins": "4.57.1", "@jsonjoy.com/fs-node-utils": "4.57.1" }, "peerDependencies": { "tslib": "2" } }, "sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg=="], + "@jsonjoy.com/fs-node-to-fsa": ["@jsonjoy.com/fs-node-to-fsa@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-fsa": "4.57.6", "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6" }, "peerDependencies": { "tslib": "2" } }, "sha512-+JptNw3iifihxH2rEXrninDzX4FFVW8JD/wPR8GbJPAeL9CQUSblrlumOPB5gZuS7tYRX+PJPLtT7XzKoRhv/Q=="], - "@jsonjoy.com/fs-node-utils": ["@jsonjoy.com/fs-node-utils@4.57.1", "", { "dependencies": { "@jsonjoy.com/fs-node-builtins": "4.57.1" }, "peerDependencies": { "tslib": "2" } }, "sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw=="], + "@jsonjoy.com/fs-node-utils": ["@jsonjoy.com/fs-node-utils@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-node-builtins": "4.57.6" }, "peerDependencies": { "tslib": "2" } }, "sha512-foyUrfS7WmYEUzqYXSNxmJBcSj04TABrkpFabwO9SCDCpVCfJ+qG+2sk5FjfiflG2n0SDFZDCJ6vYlJAEpxJFg=="], - "@jsonjoy.com/fs-print": ["@jsonjoy.com/fs-print@4.57.1", "", { "dependencies": { "@jsonjoy.com/fs-node-utils": "4.57.1", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw=="], + "@jsonjoy.com/fs-print": ["@jsonjoy.com/fs-print@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-node-utils": "4.57.6", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-96eAn4Dudtt67LTeuU47yUD+pg9/G/oKpI10zei9ljk3X3WK4lYKc+n3cpaPCAbKPzoyfxl0mXm8f8Y7BOSFXw=="], - "@jsonjoy.com/fs-snapshot": ["@jsonjoy.com/fs-snapshot@4.57.1", "", { "dependencies": { "@jsonjoy.com/buffers": "^17.65.0", "@jsonjoy.com/fs-node-utils": "4.57.1", "@jsonjoy.com/json-pack": "^17.65.0", "@jsonjoy.com/util": "^17.65.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg=="], + "@jsonjoy.com/fs-snapshot": ["@jsonjoy.com/fs-snapshot@4.57.6", "", { "dependencies": { "@jsonjoy.com/buffers": "^17.65.0", "@jsonjoy.com/fs-node-utils": "4.57.6", "@jsonjoy.com/json-pack": "^17.65.0", "@jsonjoy.com/util": "^17.65.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-V57CMzbOgTzUWGOWQ8GzHQdpJP6JnrYVNCtTBNxVYEnlVRvo4uEJqHhtAT8vhDFrIuJOXLrTL1Fki4h5oI7xxg=="], "@jsonjoy.com/json-pack": ["@jsonjoy.com/json-pack@1.21.0", "", { "dependencies": { "@jsonjoy.com/base64": "^1.1.2", "@jsonjoy.com/buffers": "^1.2.0", "@jsonjoy.com/codegen": "^1.0.0", "@jsonjoy.com/json-pointer": "^1.0.2", "@jsonjoy.com/util": "^1.9.0", "hyperdyperid": "^1.2.0", "thingies": "^2.5.0", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg=="], @@ -648,17 +650,17 @@ "@module-federation/webpack-bundler-runtime": ["@module-federation/webpack-bundler-runtime@0.22.0", "", { "dependencies": { "@module-federation/runtime": "0.22.0", "@module-federation/sdk": "0.22.0" } }, "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA=="], - "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw=="], + "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ=="], - "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw=="], + "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w=="], - "@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3", "", { "os": "linux", "cpu": "arm" }, "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw=="], + "@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4", "", { "os": "linux", "cpu": "arm" }, "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw=="], - "@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg=="], + "@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw=="], - "@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3", "", { "os": "linux", "cpu": "x64" }, "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg=="], + "@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ=="], - "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ=="], + "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", "", { "os": "win32", "cpu": "x64" }, "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ=="], "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], @@ -672,25 +674,27 @@ "@oxc-project/types": ["@oxc-project/types@0.133.0", "", {}, "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA=="], - "@peculiar/asn1-cms": ["@peculiar/asn1-cms@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "@peculiar/asn1-x509-attr": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw=="], + "@peculiar/asn1-cms": ["@peculiar/asn1-cms@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "@peculiar/asn1-x509-attr": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-hew63shtzzvBcSHbhm+cyAmKe6AIfinT9hzEqSPjDC6opTTMKmTkQ0gHuN2KsWlvqiKw1S/fS94fhag/FJkioQ=="], - "@peculiar/asn1-csr": ["@peculiar/asn1-csr@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w=="], + "@peculiar/asn1-csr": ["@peculiar/asn1-csr@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-VVsAyGqErT9D1SY4aEqozThXMVI+ssVRiv2DDeYuvpBKLIgZ3hYs3Ay3u/VSoKq6ESFi9cf6rf3IOOzfwh7oMA=="], - "@peculiar/asn1-ecc": ["@peculiar/asn1-ecc@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g=="], + "@peculiar/asn1-ecc": ["@peculiar/asn1-ecc@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-n7KEs/Q/wrB415cxy4fHOBhegp4NdJ15fkJPwcB/3/8iNBQC2L/N7SChJPKDJPZGYH0jD4Tg4/0vnHmwghnbKw=="], - "@peculiar/asn1-pfx": ["@peculiar/asn1-pfx@2.6.1", "", { "dependencies": { "@peculiar/asn1-cms": "^2.6.1", "@peculiar/asn1-pkcs8": "^2.6.1", "@peculiar/asn1-rsa": "^2.6.1", "@peculiar/asn1-schema": "^2.6.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw=="], + "@peculiar/asn1-pfx": ["@peculiar/asn1-pfx@2.7.0", "", { "dependencies": { "@peculiar/asn1-cms": "^2.7.0", "@peculiar/asn1-pkcs8": "^2.7.0", "@peculiar/asn1-rsa": "^2.7.0", "@peculiar/asn1-schema": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-V/nrlQVmhg7lYAsM7E13UDL5erAwFv6kCIVFqNaMIHSVi7dngcT839JkRTkQBqznMG98l2XjxYk74ZztAohZzA=="], - "@peculiar/asn1-pkcs8": ["@peculiar/asn1-pkcs8@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw=="], + "@peculiar/asn1-pkcs8": ["@peculiar/asn1-pkcs8@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-9GTl1nE8Mx1kTZ+7QyYatDyKsm34QcWRBFkY1iPvWC3X4Dona5s/tlLiQsx5WzVdZqiMBZNYT0buyw4/vbhnjw=="], - "@peculiar/asn1-pkcs9": ["@peculiar/asn1-pkcs9@2.6.1", "", { "dependencies": { "@peculiar/asn1-cms": "^2.6.1", "@peculiar/asn1-pfx": "^2.6.1", "@peculiar/asn1-pkcs8": "^2.6.1", "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "@peculiar/asn1-x509-attr": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw=="], + "@peculiar/asn1-pkcs9": ["@peculiar/asn1-pkcs9@2.7.0", "", { "dependencies": { "@peculiar/asn1-cms": "^2.7.0", "@peculiar/asn1-pfx": "^2.7.0", "@peculiar/asn1-pkcs8": "^2.7.0", "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "@peculiar/asn1-x509-attr": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-Bh7m+OuIaSEllPQcSd9OSp93F4ROWH7sbITWV8MI+8dwsjE5111/87VxiWVvYFKyww3vp39geLv9ENqhwWHcew=="], - "@peculiar/asn1-rsa": ["@peculiar/asn1-rsa@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA=="], + "@peculiar/asn1-rsa": ["@peculiar/asn1-rsa@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-/qvENQrXyTZURjMqSeofHul0JJt2sNSzSwk36pl2olkHbaioMQgrASDZAlHXl0xUlnVbHj0uGgOrBMTb5x2aJQ=="], - "@peculiar/asn1-schema": ["@peculiar/asn1-schema@2.6.0", "", { "dependencies": { "asn1js": "^3.0.6", "pvtsutils": "^1.3.6", "tslib": "^2.8.1" } }, "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg=="], + "@peculiar/asn1-schema": ["@peculiar/asn1-schema@2.7.0", "", { "dependencies": { "@peculiar/utils": "^2.0.2", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-W8ZfWzLmQnrcky+eh3tni4IozMdqBDiHWU0N+vve/UGjMaUs8c0L7A2oEdkBXS8rTpWDpK/aoI3DG/L/hxmxPg=="], - "@peculiar/asn1-x509": ["@peculiar/asn1-x509@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "asn1js": "^3.0.6", "pvtsutils": "^1.3.6", "tslib": "^2.8.1" } }, "sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA=="], + "@peculiar/asn1-x509": ["@peculiar/asn1-x509@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/utils": "^2.0.2", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-mUn9RRrkGDnG4ALfunDmzyRW5dg+sWCj/pfnCCqEHYbkGxEpvUt6iVJv8Yw1cyp6SWZ26ZE5oSmI5SqEaen15g=="], - "@peculiar/asn1-x509-attr": ["@peculiar/asn1-x509-attr@2.6.1", "", { "dependencies": { "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.1", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ=="], + "@peculiar/asn1-x509-attr": ["@peculiar/asn1-x509-attr@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-NS8e7SOgXipkzUPLF/sce7ukpMpWjhxYsH0n6Y+bHYo4TTxOb95Zv7hqwSuL212mj5YxovjdOKQOgH1As3E94w=="], + + "@peculiar/utils": ["@peculiar/utils@2.0.3", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ=="], "@peculiar/x509": ["@peculiar/x509@1.14.3", "", { "dependencies": { "@peculiar/asn1-cms": "^2.6.0", "@peculiar/asn1-csr": "^2.6.0", "@peculiar/asn1-ecc": "^2.6.0", "@peculiar/asn1-pkcs9": "^2.6.0", "@peculiar/asn1-rsa": "^2.6.0", "@peculiar/asn1-schema": "^2.6.0", "@peculiar/asn1-x509": "^2.6.0", "pvtsutils": "^1.3.6", "reflect-metadata": "^0.2.2", "tslib": "^2.8.1", "tsyringe": "^4.10.0" } }, "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA=="], @@ -704,125 +708,125 @@ "@radix-ui/colors": ["@radix-ui/colors@3.0.0", "", {}, "sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg=="], - "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], + "@radix-ui/number": ["@radix-ui/number@1.1.2", "", {}, "sha512-ceTwaxc4I5IOi97DgCotl3pqiyRGvffcc0oOsE2dQYaJOFIDsDt4VWG6xEbg1QePv9QWausCEIppud/tJ1wNig=="], - "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.4", "", {}, "sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ=="], - "@radix-ui/react-accessible-icon": ["@radix-ui/react-accessible-icon@1.1.7", "", { "dependencies": { "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A=="], + "@radix-ui/react-accessible-icon": ["@radix-ui/react-accessible-icon@1.1.9", "", { "dependencies": { "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5W9KzJz/3DeYbGJHbZv8Q6AkxMOKUmALfc+PRg9dWwJZMk6zD37Sz8sZrF7UD6CBkiJvn7dNeRzn5G7XiCMyig=="], - "@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA=="], + "@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collapsible": "1.1.13", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-xITxBB2p5m5tAe7M0F95kb4uAh7jSIKGlExMEm93HlW+XxZHV2eXFbPWLktd4JhRiwcnXNbO7iekcrbZy6ZCvA=="], - "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw=="], + "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dialog": "1.1.16", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-vPaIgo0mxYlvcFaM9jB2Uot9TjGXMuAPEvrc6BOLeV+I5U8s1dkIoouYaa6lmSfc5SPMo5x5djOTOTvaigdGMQ=="], - "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="], + "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-yqHW5WQ/cTpU/un7dqqIKNy2iRU8BC0JB78PEzTfCCYvZu1U6W9KwObAniMk9nhSfyotKPQTYaUD/HB0f5muig=="], - "@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g=="], + "@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Xy+Dpxt/5n9rVTdPrNFmf8GwG1NlT1pzCF/z1MgOGZMLZWdWl+km+ZRWGQAPEhbkzSwYEsfYmTca8NhUtVxqnw=="], - "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.10", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog=="], + "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.12", "", { "dependencies": { "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-NQCQyWC7QrDPhjMn8hUqFeU0lUrprIgm1AyMgLbzuQJibNnatdc3SSMo3/UGFu/eUkJUU1cEcKCnyhXTQzq6tA=="], - "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="], + "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.4", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m3JmIOAX5ZzZ6VPjxEU2dbTOhoHi0nT5riwcDwe8idocsWf4a5DXJLDtZ6LfJwMBx7W+A2b7kp2TgPEKtaiF6A=="], - "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA=="], + "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F0s8+p2XNpfc3k02zBfB0jPWbkHVG162+p7BdUMyJ2308QMqZ+oaclX+FAzKFovgL5OqRU+Rvy6f/vbdlJVaqA=="], - "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="], + "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.9", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zuSVi7ziP7uQRqc+yGxsKJfNkdyHv3ZKDaHe0gzg4dRgws96TPKWIiz84tVHP4GEcEl8bC0mdt17NkcxaJHmaQ=="], - "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], + "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA=="], - "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], + "@radix-ui/react-context": ["@radix-ui/react-context@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg=="], - "@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww=="], + "@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.3.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-menu": "2.1.17", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-d7CouXhAW+CGmFOqmB+IEvd3E9GcaqfgvfjCc3hfulp2pkaUCEVEGa0SN5nNWYA+IvQ6g1Pt+S5dpNn1AoY9hg=="], - "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="], + "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-l9ok83YBclEZhbjgzt76Hw733e6cvRKPNgO6GJ/IETlufXG9p+fRu2wlvpImQvR6xdJ8h7J8J2DBvsPEiEsKMw=="], - "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], + "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA=="], - "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="], + "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-escape-keydown": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-MhoruH6xEzsbvOmo4TNgMfmtvRGyDZw4MDSdf4ybMHfezjqwzv6hyd4lsMzBp8K9Sn6sGzCF62x1I7BYUECXOg=="], - "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw=="], + "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.17", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-S6b3Jm57sY5EdDyOMLkacbB0qMnKhy1RCKZCt795ZkmtUOAvojYIZ5p7dXHIh5Cyr3jCLLI5/g64V3FKLudZmw=="], - "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="], + "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q=="], - "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="], + "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.9", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9Se8t+Zry+1rEOL7Y6l/4ANYU/TOtAtf8O2fKdwLltcaMcm6kOqYGbzO4tMFQ0bvzO920pRAoHpFZ4W85S3keQ=="], - "@radix-ui/react-form": ["@radix-ui/react-form@0.1.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-label": "2.1.7", "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ=="], + "@radix-ui/react-form": ["@radix-ui/react-form@0.1.9", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-label": "2.1.9", "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-eTPyThIKDacJ3mJDvYwf/PSmsEYlOyA2Qcb+aGyWwYv+P5w57VPUkMVA2XJ9z0Du2KBY1HoHQzhPV9iYL/r4hg=="], - "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg=="], + "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-hAileDBtd6CX7nlZOarOnISQ6PP4q0e16BX51ulzdZ+7IzjL0sDTVpFdmSYrIjw6zVNsfQBao5gG6AWr3qwfvA=="], - "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], + "@radix-ui/react-id": ["@radix-ui/react-id@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA=="], - "@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="], + "@radix-ui/react-label": ["@radix-ui/react-label@2.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-rDoTeMbCwRVcnmo7NGT9IlPo1yXmEI+xc1URP3oeewwZEV4mdTp1dYUhYbQdo4D1q2SjKVvv4N1gNY77QAQtjA=="], - "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg=="], + "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-callback-ref": "1.1.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-fmbNnFyf+JYCN0DhhWnEdUTDnZD1mXaPQWivdsPIb8oOSbARfD3LIQJbLCG8a8QLCwoMxiJ7GVPIFcC8Dw8v2Q=="], - "@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA=="], + "@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.17", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-AKtZ4O782yO7qwIyq73WpulYt1IHhQ0htDb6wNcxzxnSDCcSWMVBiU9ycpcA90XzQO4IVIxIErtak6Kg/Vt0rQ=="], - "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w=="], + "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/fS8hKCcRt4DwCGa5QIB3juRXmfYSOk4a2AEe/BDIyy7Hm+eje2Y13oUx5zejl+wFt1owrM7E8NWlbaEl5EGpg=="], - "@radix-ui/react-one-time-password-field": ["@radix-ui/react-one-time-password-field@0.1.8", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg=="], + "@radix-ui/react-one-time-password-field": ["@radix-ui/react-one-time-password-field@0.1.9", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-fvCzA9hm7yN5xxTPJIi4VhSmH5gv+76ILsxguBK3cm3icD5BR4vW7POQmu8Zio0yh91uuouG/Kang40IbMkaSQ=="], - "@radix-ui/react-password-toggle-field": ["@radix-ui/react-password-toggle-field@0.1.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-is-hydrated": "0.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw=="], + "@radix-ui/react-password-toggle-field": ["@radix-ui/react-password-toggle-field@0.1.4", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qoDSkObZ9faJlsjlwyBH6ia7kq9vaJ2QwWTowT3nQpzPvUTAKesmWuGJYpd91HIoJqS+5ZPXy5uFPp+HlwdaAg=="], - "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="], + "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8brVpAU5Uq7Bh0c8EFc4ZTf2JJTYn0o+1L+CUJB3UYIOkTjKGMgoHvduylrahdmNlr3DfH0rFq2DrbNZXgaspw=="], - "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="], + "@radix-ui/react-popper": ["@radix-ui/react-popper@1.3.0", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-rect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9PB589e1aWZbrlFUHdz6WiPCL+xLZHQFX7oibqG/6Q0SwOkxDyQX9W/cyPa+sAPPKuC8cpLCpRczE5a/1DiwVQ=="], - "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="], + "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-UEytdjgEh2tJGgD/gZK4FUx6t1rNIlM3U0DENhSrG7I75FGm1DnaDuVUWF1pWAWUwGmn1sCJ1VGHn8LhN1aTOw=="], - "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="], + "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.6", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ=="], - "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.5", "", { "dependencies": { "@radix-ui/react-slot": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zifXeB8Y88qCYx8PLZ5oQb32KwZub+s925mMoZsBBq9KUQqWKkREubTfs6ASjRPPBe7Jt9O8OHH89+95VG+grA=="], - "@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.7", "", { "dependencies": { "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg=="], + "@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.9", "", { "dependencies": { "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-+EOkvg1Zn1vI1+fRDfRSAiJ7BWfcDAo5ASMmbqrcLZ4s4USk2FGkoHgeb2X+CkUgo2zJMiyObwf1k44CrRWsyw=="], - "@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.3.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ=="], + "@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.4.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-eHdV5bLx9sH+tBnbDjkIBdvQEH/c6MEtQYhTbxkaDK9qsIFFLtmJYEQFVdwhnruWotLfQmIuWEL/J+L3utE8rQ=="], - "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="], + "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FvgPt1bRmg8Xt2QpF7NUZW3dE0ZQHGm41dAdgT2J2GJPoIXz+9Em3NobAxf4fupcxhgHu03E5CRiU2MWvObXyg=="], - "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.10", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A=="], + "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.11", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-DS39ziOgea75U/TrXKU2/oKp0be2jrDHnzFLvahg/0iNAT1Zq16e4Uw0WXwyXvsK+mG3BRyMb7A3NRZMDuEXtQ=="], - "@radix-ui/react-select": ["@radix-ui/react-select@2.2.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ=="], + "@radix-ui/react-select": ["@radix-ui/react-select@2.3.0", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.5", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-mENc7WpJvJcW8hlMpzfFcHcEhTvYS5JMBmi9HVC1Q00uhBwML086MHYUV8QQdQv6lcu0Wg8dzd1RB8AFADcG/g=="], - "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA=="], + "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-gvgW+JV/Mbjj6darztTetnmElpQEzZrXpJvfj+dOxNAxiyHEAyUvEjjl4zxblvmjmKmi3jfPoy7ZdxzCuUBJSA=="], - "@radix-ui/react-slider": ["@radix-ui/react-slider@1.3.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw=="], + "@radix-ui/react-slider": ["@radix-ui/react-slider@1.4.0", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-RHcPlLOThRJM51DSIC33ZnpDEBYhyEFroVWkd2P54PGGjkmAt14RboYUU9E1MFst666zFHM0tGtWvMjSOtU1pw=="], - "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rCMO3QsIVKv5JTY5CVbo2MvO77SpEqqYc8AvRE7OWqRDOIqAKjsp+DrmnY9uc8NPdxB5E2z47HTYGeE2+NTptg=="], - "@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="], + "@radix-ui/react-switch": ["@radix-ui/react-switch@1.3.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-GP1EZwhoZO/GGnhM1P5/2Vpm8iN8EnngyU0oezn2l78kN8tj25pyrvjIaT7azBhK615KSt+P2w39y57YV5jVkA=="], - "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="], + "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-D5jwp9JNuwDeCw3CYD2Fz+sSHo0droQjC8u75dJHe4aWr5q6yBiXZU+hurXnKudRgEpUkD5TsI6bjHPo5ThUxA=="], - "@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g=="], + "@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-WUymDDiN2DpoGudRN1aW4wF5O3BNQjZZO/5nngPoNiEVqjyOzirvZZNO0R6dC1ifucSINVaSv8JX1aq47VGgiA=="], - "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.10", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ=="], + "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FikrKJemoBGZQ6uRID0HJqSPBP6D7OppdD2OhLl0ZYLlAyPXI7MezoYGmumwNkrAoRm35xXkb4C8JPfJZZzcaw=="], - "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q=="], + "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-toggle": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TEgECgJaWGAHJJZGzNNEYTNBdIXqX7LchANycpyP7DkfjmuiSN7ISt1k/ZRGVJgVJonsgP4vwaiKMn5utrcwWQ=="], - "@radix-ui/react-toolbar": ["@radix-ui/react-toolbar@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-separator": "1.1.7", "@radix-ui/react-toggle-group": "1.1.11" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg=="], + "@radix-ui/react-toolbar": ["@radix-ui/react-toolbar@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-separator": "1.1.9", "@radix-ui/react-toggle-group": "1.1.12" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-4wHtJVdIgqMmEwUvxA0BYg/2JMRbt0L3+8UD8Ml/nhKkfXtiZcM8u/S15gQ5xj9YEd/0qlrm5bE805LsjQ+J8A=="], - "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg=="], + "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.9", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-u6F9MmTtBSLkiXNVDrtB/yPCZarM9smNswC24YYLV/M+bth6J3Gs3vlJezEoFwKZvPvxhCpUYdUnOsNG/0XOlA=="], - "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], + "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw=="], - "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], + "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.3", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-PLzC90MS+ReootmjC597dvopoelpZ8Q61HJkDXZSExitIq7PL55vHNnesAHwguHK0aPfBnpdNzQtv1uliaqQrA=="], - "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="], + "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.3", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA=="], - "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="], + "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.2", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2uVLvLjgO7NZCWw01/FdqRwmA42J0BcjPMUCA+koFEOAb+zjqIP7SiFz/7zWPrKnVmSqr76Omq2ALyCuX4dhLw=="], - "@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.0", "", { "dependencies": { "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA=="], + "@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A=="], - "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], + "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA=="], - "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="], + "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-IGBQPtRFdhN6MQ8dbegVmBq1LVZluya3F1jWY+puIcQC3MHctRwTDSBWCkL/3ZcnMJLTMJ++Z+ktmvg0F89iCw=="], - "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="], + "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.2", "", { "dependencies": { "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-d8a+bBY/FxikNPlgJJoaBHZX+zKVbWHYJGTLnLvveQgFSTntkGdEKv3JDtHrMS0DNYpllz2nRsTLGLKYttbpmw=="], - "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="], + "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w=="], - "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="], + "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.5", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tPcHNI3FajdDBFpl/Ez1m2WL0ufJqBKyHxMDBvKitopamK36WwBGOMicuMEZKkM5Wce41QxUyv6BsiqfrWBiGg=="], - "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], + "@radix-ui/rect": ["@radix-ui/rect@1.1.2", "", {}, "sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA=="], "@radix-ui/themes": ["@radix-ui/themes@3.3.0", "", { "dependencies": { "@radix-ui/colors": "^3.0.0", "classnames": "^2.3.2", "radix-ui": "^1.1.3", "react-remove-scroll-bar": "^2.3.8" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I0/h2CRNTpYNB7Mi3xFIvSsQq5a108d7kK8dTO5zp5b9HR5QJXKag6B8tjpz2ITkVYkFdkGk45doNkSr7OxwNw=="], @@ -976,59 +980,59 @@ "@svgr/webpack": ["@svgr/webpack@8.1.0", "", { "dependencies": { "@babel/core": "^7.21.3", "@babel/plugin-transform-react-constant-elements": "^7.21.3", "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@svgr/core": "8.1.0", "@svgr/plugin-jsx": "8.1.0", "@svgr/plugin-svgo": "8.1.0" } }, "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA=="], - "@swc/core": ["@swc/core@1.15.33", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.26" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.33", "@swc/core-darwin-x64": "1.15.33", "@swc/core-linux-arm-gnueabihf": "1.15.33", "@swc/core-linux-arm64-gnu": "1.15.33", "@swc/core-linux-arm64-musl": "1.15.33", "@swc/core-linux-ppc64-gnu": "1.15.33", "@swc/core-linux-s390x-gnu": "1.15.33", "@swc/core-linux-x64-gnu": "1.15.33", "@swc/core-linux-x64-musl": "1.15.33", "@swc/core-win32-arm64-msvc": "1.15.33", "@swc/core-win32-ia32-msvc": "1.15.33", "@swc/core-win32-x64-msvc": "1.15.33" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-jOlwnFV2xhuuZeAUILGFULeR6vDPfijEJ57evfocwznQldLU3w2cZ9bSDryY9ip+AsM3r1NJKzf47V2NXebkeQ=="], + "@swc/core": ["@swc/core@1.15.40", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.26" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.40", "@swc/core-darwin-x64": "1.15.40", "@swc/core-linux-arm-gnueabihf": "1.15.40", "@swc/core-linux-arm64-gnu": "1.15.40", "@swc/core-linux-arm64-musl": "1.15.40", "@swc/core-linux-ppc64-gnu": "1.15.40", "@swc/core-linux-s390x-gnu": "1.15.40", "@swc/core-linux-x64-gnu": "1.15.40", "@swc/core-linux-x64-musl": "1.15.40", "@swc/core-win32-arm64-msvc": "1.15.40", "@swc/core-win32-ia32-msvc": "1.15.40", "@swc/core-win32-x64-msvc": "1.15.40" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-2kwzJikRvgtNAG7MwVZY2vEzZjTxKIq5jXOihuSV/8U+Hej8Va22t65aKnJZs3P+NwojZvR8Mf8kyM7O+V8sQg=="], - "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.33", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N+L0uXhuO7FIfzqwgxmzv0zIpV0qEp8wPX3QQs2p4atjMoywup2JTeDlXPw+z9pWJGCae3JjM+tZ6myclI+2gA=="], + "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.40", "", { "os": "darwin", "cpu": "arm64" }, "sha512-PaYyclfmQ++77D8ityYvmmVzHv9aG8ROwt2GfG6/ccloy4Hgf80qtOnzb9VYvPsUT7Ty1uhuDRhv3XYpf62qhQ=="], - "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.15.33", "", { "os": "darwin", "cpu": "x64" }, "sha512-/Il4QHSOhV4FekbsDtkrNmKbsX26oSysvgrRswa/RYOHXAkwXDbB4jaeKq6PsJLSPkzJ2KzQ061gtBnk0vNHfA=="], + "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.15.40", "", { "os": "darwin", "cpu": "x64" }, "sha512-HbbPzvfLBUXjIB1Ezks+//lNUjmLjfyd63XSwprJgrZaXYdm70kohXPJUWdqKZozolFxbPaO+xtBaiUp6BoueA=="], - "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.15.33", "", { "os": "linux", "cpu": "arm" }, "sha512-C64hBnBxq4viOPQ8hlx+2lJ23bzZBGnjw7ryALmS+0Q3zHmwO8lw1/DArLENw4Q18/0w5wdEO1k3m1wWNtKGqQ=="], + "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.15.40", "", { "os": "linux", "cpu": "arm" }, "sha512-SlRZsCjOCPR2LvFs0Ri/Xrx/5o5TCt8vl4gW6mX1hEZOG0a625RxzRHpHdAQNGykmAN/7IeaFAJG+QnNmxlHcA=="], - "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.15.33", "", { "os": "linux", "cpu": "arm64" }, "sha512-TRJfnJbX3jqpxRDRoieMzRiCBS5jOmXNb3iQXmcgjFEHKLnAgK1RZRU8Cq1MsPqO4jAJp/ld1G4O3fXuxv85uw=="], + "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-Q8byxJt2fh8CR3EUX6snBpy47AoBVm+In/+Z3rjDHMjC38ZvR9/gtUUNCT0tfrn4EdVsO8/QPi59nxrxvqxvBQ=="], - "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.15.33", "", { "os": "linux", "cpu": "arm64" }, "sha512-il7tYM+CpUNzieQbwAjFT1P8zqAhmGWNAGhQZBnxurXZ0aNn+5nqYFTEUKNZl7QibtT0uQXzTZrNGHCIj6Y1Og=="], + "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-4z0MgHU+7M0pZDqBN1El7mFXDI1SBwinfcUkAyA4v8QrhOIUOZltySt2aStQLZGrdXVXM4Y4ylfiTC04ED+MoQ=="], - "@swc/core-linux-ppc64-gnu": ["@swc/core-linux-ppc64-gnu@1.15.33", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ZtNBwN0Z7CFj9Il0FcPaKdjgP7URyKu/3RfH46vq+0paOBqLj4NYldD6Qo//Duif/7IOtAraUfDOmp0PLAufog=="], + "@swc/core-linux-ppc64-gnu": ["@swc/core-linux-ppc64-gnu@1.15.40", "", { "os": "linux", "cpu": "ppc64" }, "sha512-fLI4iUgeSZu0eRWUXwe6YzPFx9gHbFiPkl8Rp3mJfP8OpNR3nTQCGPvHdDh9xniW7mVvgMY4ni7A4VzqI1KrpA=="], - "@swc/core-linux-s390x-gnu": ["@swc/core-linux-s390x-gnu@1.15.33", "", { "os": "linux", "cpu": "s390x" }, "sha512-De1IyajoOmhOYYjw/lx66bKlyDpHZTueqwpDrWgf5O7T6d1ODeJJO9/OqMBmrBQc5C+dNnlmIufHsp4QVCWufA=="], + "@swc/core-linux-s390x-gnu": ["@swc/core-linux-s390x-gnu@1.15.40", "", { "os": "linux", "cpu": "s390x" }, "sha512-YqeKMAb7d4nQSGMJQ454IlaCENpzcDqhvBE9+CPfdnYpnUXxd+BSrB6Xk0YjW8UyoEhUj4p6quATCxbsp6J3jg=="], - "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.15.33", "", { "os": "linux", "cpu": "x64" }, "sha512-mGTH0YxmUN+x6vRN/I6NOk5X0ogNktkwPnJ94IMvR7QjhRDwL0O8RXEDhyUM0YtwWrryBOqaJQBX4zruxEPRGw=="], + "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-7HOuS1iGcme/j/TuL1TfmmLGiMQrjv/GmjyZeydl00FKPtpGXEldwqfI56xgd1YzrzoB2svWjxbGGyQ0TEASxg=="], - "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.15.33", "", { "os": "linux", "cpu": "x64" }, "sha512-hj628ZkSEJf6zMf5VMbYrG2O6QqyTIp2qwY6VlCjvIa9lAEZ5c2lfPblCLVGYubTeLJDxadLB/CxqQYOQABeEQ=="], + "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-h4kZYHc7dpc9P9u4brRJaS8Pl7tPVHAeiLSzw7T5RfIJgAoSdaCMKzI/2Uay9gFhaw8uyCDl0L5q37r0EpAfIA=="], - "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.15.33", "", { "os": "win32", "cpu": "arm64" }, "sha512-GV2oohtN2/5+KSccl86VULu3aT+LrISC8uzgSq0FRnikpD+Zwc+sBlXmoKQ+Db6jI57ITUOIB8jRkdGMABC29g=="], + "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.15.40", "", { "os": "win32", "cpu": "arm64" }, "sha512-+mQgKZXSj6mV38Zh05QaxSjUDmGP/R2JWlXZTDLSPkDzHU6p3GxN9eeSf5dfyDVU86946fmCvSzyl/ucImx8+A=="], - "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.15.33", "", { "os": "win32", "cpu": "ia32" }, "sha512-gtyvzSNR8DHKfFEA2uqb8Ld1myqi6uEg2jyeUq3ikn5ytYs7H8RpZYC8mdy4NXr8hfcdJfCLXPlYaqqfBXpoEQ=="], + "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.15.40", "", { "os": "win32", "cpu": "ia32" }, "sha512-yvwdPLGd25mcj/mNatjNQ0lZujtQD6psH3v9PNmMb+fSzjbNG8KIDxjFWrcV+fsFVLOkyOmdJsFmX7NAFjVyPw=="], - "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.15.33", "", { "os": "win32", "cpu": "x64" }, "sha512-d6fRqQSkJI+kmMEBWaDQ7TMl8+YjLYbwRUPZQ9DY0ORBJeTzOrG0twvfvlZ2xgw6jA0ScQKgfBm4vHLSLl5Hqg=="], + "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.15.40", "", { "os": "win32", "cpu": "x64" }, "sha512-OXtKsLU1bVtInzzDEAY2sYiF/rl4tvAnLLLpuMp3HzAOQZ5A+i69AKDhA1YLQTaMAqO3vzyYNVAYVRMPtSYD4w=="], "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], - "@swc/html": ["@swc/html@1.15.33", "", { "dependencies": { "@swc/counter": "^0.1.3" }, "optionalDependencies": { "@swc/html-darwin-arm64": "1.15.33", "@swc/html-darwin-x64": "1.15.33", "@swc/html-linux-arm-gnueabihf": "1.15.33", "@swc/html-linux-arm64-gnu": "1.15.33", "@swc/html-linux-arm64-musl": "1.15.33", "@swc/html-linux-ppc64-gnu": "1.15.33", "@swc/html-linux-s390x-gnu": "1.15.33", "@swc/html-linux-x64-gnu": "1.15.33", "@swc/html-linux-x64-musl": "1.15.33", "@swc/html-win32-arm64-msvc": "1.15.33", "@swc/html-win32-ia32-msvc": "1.15.33", "@swc/html-win32-x64-msvc": "1.15.33" } }, "sha512-PZIfmj5zYpAJ2eMptf0My2q9Bl8bkraW28+FD1pRnxOiYMrKrP5vL2tB2PdxMRjS0ziLFVM5HEuGFw8PxEDOaw=="], + "@swc/html": ["@swc/html@1.15.40", "", { "dependencies": { "@swc/counter": "^0.1.3" }, "optionalDependencies": { "@swc/html-darwin-arm64": "1.15.40", "@swc/html-darwin-x64": "1.15.40", "@swc/html-linux-arm-gnueabihf": "1.15.40", "@swc/html-linux-arm64-gnu": "1.15.40", "@swc/html-linux-arm64-musl": "1.15.40", "@swc/html-linux-ppc64-gnu": "1.15.40", "@swc/html-linux-s390x-gnu": "1.15.40", "@swc/html-linux-x64-gnu": "1.15.40", "@swc/html-linux-x64-musl": "1.15.40", "@swc/html-win32-arm64-msvc": "1.15.40", "@swc/html-win32-ia32-msvc": "1.15.40", "@swc/html-win32-x64-msvc": "1.15.40" } }, "sha512-YVWNrh3wZWH2oXz7uL+s1WZbFIsnAp9cCl/b+C7ufDJqhsOvbr0un9IOYZ/CxRIRdnHGfhVD199n8baD/kRQew=="], - "@swc/html-darwin-arm64": ["@swc/html-darwin-arm64@1.15.33", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zyO6uMBfLyCh55wundAxKX+8P/f98ecuyir4VX6nTmn6y7x37ndB8f01LUrd9Tiq6eEAvDXLiqEUvuGjEc7Pmg=="], + "@swc/html-darwin-arm64": ["@swc/html-darwin-arm64@1.15.40", "", { "os": "darwin", "cpu": "arm64" }, "sha512-A9oxSh60pMEsX/4VBpn3e6s8DfGWsHzAeG+Vd9mXgkTqt/ouX12owP6RyqfqK8v0WuEsBKkGY0+MbwLvlOG8NQ=="], - "@swc/html-darwin-x64": ["@swc/html-darwin-x64@1.15.33", "", { "os": "darwin", "cpu": "x64" }, "sha512-MaGunsY/J5l7Rb5OmoztEWh+ikooydT7nWkjiDovj7UfkB9HLk5sLr9O7ZdNGJ2u9dD6FX89SzMdA0Psm9NJrQ=="], + "@swc/html-darwin-x64": ["@swc/html-darwin-x64@1.15.40", "", { "os": "darwin", "cpu": "x64" }, "sha512-GZ5KxJ/1pqnpOAjaa9hnkSk3M1LHjc5ci5GCt5/llAgDKFLDHzydIflHXTOIaS4nRCtfVMmD0joKX+ZWruSkJw=="], - "@swc/html-linux-arm-gnueabihf": ["@swc/html-linux-arm-gnueabihf@1.15.33", "", { "os": "linux", "cpu": "arm" }, "sha512-CrbUDjVl6/hQ1C5KPMiK4vxk/eOMjxkVELqwnOxsZ+aFVTv3L3YrGMaJ5H47vvIihkPhqiSOUPmMEFqxvqKmXg=="], + "@swc/html-linux-arm-gnueabihf": ["@swc/html-linux-arm-gnueabihf@1.15.40", "", { "os": "linux", "cpu": "arm" }, "sha512-Bbwtl0G6vYcWlDQmjeuyFx8YIvqi1StlQWjRNB1ZtvrRNL3JadFARhijBONiUIyTK9MgUbWtTV3QU69qzjNENQ=="], - "@swc/html-linux-arm64-gnu": ["@swc/html-linux-arm64-gnu@1.15.33", "", { "os": "linux", "cpu": "arm64" }, "sha512-7tZ0IgmUslI9Extu/TpxJS0GjJoDx0j9zeq2cIidPdM/njSBpyRB7n4B292Q5WFVh7PcZl7WXqqqMczibQ27aA=="], + "@swc/html-linux-arm64-gnu": ["@swc/html-linux-arm64-gnu@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-buu4fGyCIhkwmCetI4CfWOPn7cphJHwQ9ksK685hlL0R0PUaDCNdIxo+JAz0mK2JgPhoGqnKsVEmV6gLIL5GBw=="], - "@swc/html-linux-arm64-musl": ["@swc/html-linux-arm64-musl@1.15.33", "", { "os": "linux", "cpu": "arm64" }, "sha512-gYi2ainYZV2z+jwjp9UKuPVOf3c5q+NkH3QRDjqDrIPLagqDsYNjobi8p5oajGcPGFLNTcVw08VTcubJGChReA=="], + "@swc/html-linux-arm64-musl": ["@swc/html-linux-arm64-musl@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-BwWtpAGEHIP1QwKExWqBIjGpAHMahjT26ORZv3+TbwW4IuEl2QP5FrcYc30O8abCG5J1lWRl1vXKYDpzbIDz1A=="], - "@swc/html-linux-ppc64-gnu": ["@swc/html-linux-ppc64-gnu@1.15.33", "", { "os": "linux", "cpu": "ppc64" }, "sha512-6CfzyVQSdD8ezFdxFve4J/b6qTgXIwYFWEvSdaJvXSgwTy976uUV5Ff1LOF86mt2zWMhZJX9DqmkGyIhepbyWw=="], + "@swc/html-linux-ppc64-gnu": ["@swc/html-linux-ppc64-gnu@1.15.40", "", { "os": "linux", "cpu": "ppc64" }, "sha512-wLtHgwmZu5K7PvuTROklgWJO6D+KwywpYR1geI8dSWX/AYnx/KCGVK9ncPzWVfnLXWhXbkgua3Ujdrfoxf+qSw=="], - "@swc/html-linux-s390x-gnu": ["@swc/html-linux-s390x-gnu@1.15.33", "", { "os": "linux", "cpu": "s390x" }, "sha512-Msx1eniw95lhMHUSe3D5FXweKHtkHtzJLsHJDj920uL4Dm7UHqzwaCuZdCmzbkHnO96YjjQvAm266djg8wupmQ=="], + "@swc/html-linux-s390x-gnu": ["@swc/html-linux-s390x-gnu@1.15.40", "", { "os": "linux", "cpu": "s390x" }, "sha512-WbWzQBCmvECZG6ep9D5SMMZTFCbFmRSCc7lPD3YhhaK16BNqr1AybvybZYOgxX9Ot5tq7gTWCgjFZXLDOn6Y/g=="], - "@swc/html-linux-x64-gnu": ["@swc/html-linux-x64-gnu@1.15.33", "", { "os": "linux", "cpu": "x64" }, "sha512-JDNb4Uq+7g+23QuOtwWnP0/EqztWIHFFdQdeBIS5zx83YBG2dYRMdPAjnHJWh2YRZxdepd8q6S9MUIxpSrouAg=="], + "@swc/html-linux-x64-gnu": ["@swc/html-linux-x64-gnu@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-i+/JqL5j9mTGMcVshWLMzciqyE3Np+gN5+UqMyO1D5zSmniJD5MHRlGXCtLaWx/MIKX0Q4Xkre33o56fmxp+uA=="], - "@swc/html-linux-x64-musl": ["@swc/html-linux-x64-musl@1.15.33", "", { "os": "linux", "cpu": "x64" }, "sha512-NSpZdbz4dj0pu1A0Z9l68Bll5HAzEMtBAeMe6jc4GEVfpIw6eeafQHm2/yMUEh09tgl8t9LzM9DycfdTZDjM4g=="], + "@swc/html-linux-x64-musl": ["@swc/html-linux-x64-musl@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-mroZnb5omFc4iE01UsJgta+Nm0sIFWpGfTPk+BHfH165MZAM4wNndeczX5RpGZbQSF1nNpCoNgqJyT7l3hITMg=="], - "@swc/html-win32-arm64-msvc": ["@swc/html-win32-arm64-msvc@1.15.33", "", { "os": "win32", "cpu": "arm64" }, "sha512-w7iho3/zS3lCDqgUZMDLMBO0ElX7j+KgvMb8BOrKqLDOSTDDj3lY/BClNJ7vBpAliI2kPQs/mUikdZyzi4MBjQ=="], + "@swc/html-win32-arm64-msvc": ["@swc/html-win32-arm64-msvc@1.15.40", "", { "os": "win32", "cpu": "arm64" }, "sha512-qg1LXRrsY9FXy0S7vouSF0kkn1vdkTD//FW66iuezH7HMm5/DJGwEj7oc1zTKPWU0HnwOINOUbl6rUHrRuXHAQ=="], - "@swc/html-win32-ia32-msvc": ["@swc/html-win32-ia32-msvc@1.15.33", "", { "os": "win32", "cpu": "ia32" }, "sha512-6hJ2pBweSfZ38trYHXmzTBDpRNvqJgFl2PkIWdy4IXbV/Fv0v9Dqe0t9Gi2ZVEBpgI7PD6pF42AT4HmrNTVFyQ=="], + "@swc/html-win32-ia32-msvc": ["@swc/html-win32-ia32-msvc@1.15.40", "", { "os": "win32", "cpu": "ia32" }, "sha512-5NwMmgt9A70LQzcYOl4OiIJk5AhsGP69fNRfkmXXop+iIcAGUmYy+d6F2/Gc0u05j9G0R04NPWcHBQrHQhr0Gw=="], - "@swc/html-win32-x64-msvc": ["@swc/html-win32-x64-msvc@1.15.33", "", { "os": "win32", "cpu": "x64" }, "sha512-eaY/vNE7rkPKluJYjhOiQOA1tto5VbJOoD1C1xFTBmr9t7WsqYUfbQhYQy5A26/z83NNgtDwELM85rkMB+/vWA=="], + "@swc/html-win32-x64-msvc": ["@swc/html-win32-x64-msvc@1.15.40", "", { "os": "win32", "cpu": "x64" }, "sha512-WUNZqCZ+8WY1pr8t3X3fq4gI5+FL/tCCzlrJ2lLn0s+TyA2SLm/RPfXxQIr94EnjJWcIV21G//6/uXeBN8cPzw=="], "@swc/types": ["@swc/types@0.1.26", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw=="], @@ -1036,21 +1040,21 @@ "@tanstack/history": ["@tanstack/history@1.162.0", "", {}, "sha512-79pf/RkhteYZTRgcR4F9kbk84P2N8rugQJswxfIqovlbRiT3yI7eBE+5QorIrZaOKktsgzRlXh1l/du/xpl4iA=="], - "@tanstack/react-router": ["@tanstack/react-router@1.170.10", "", { "dependencies": { "@tanstack/history": "1.162.0", "@tanstack/react-store": "^0.9.3", "@tanstack/router-core": "1.171.8", "isbot": "^5.1.22" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-gVmWYq0ucWr+OB97Nud0YhKa9NOipB7/QrWI7wRZJJWEL0qUS8WPqAs0vA1f3IBXZpXmf8xxzf/tl5cmo4tlmA=="], + "@tanstack/react-router": ["@tanstack/react-router@1.170.15", "", { "dependencies": { "@tanstack/history": "1.162.0", "@tanstack/react-store": "^0.9.3", "@tanstack/router-core": "1.171.13", "isbot": "^5.1.22" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-GawYz7HEjj8rTUUDoT/SemDEVm63pZUO+2mOcXHY9Jl3EwMS5gFBnPu/2UvcrwRm1jN1k79fokc0d4aFmrLatg=="], "@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.167.0", "", { "dependencies": { "@tanstack/router-devtools-core": "1.168.0" }, "peerDependencies": { "@tanstack/react-router": "^1.170.0", "@tanstack/router-core": "^1.170.0", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["@tanstack/router-core"] }, "sha512-nGw095EG7IHx0h5NtlEmzf6vcCTaFNPWdTSuDKazajhN0ct/v/TkekJ9J6KYUCeV1a8/2ZmToc58M+0rrOyn7w=="], "@tanstack/react-store": ["@tanstack/react-store@0.9.3", "", { "dependencies": { "@tanstack/store": "0.9.3", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg=="], - "@tanstack/router-core": ["@tanstack/router-core@1.171.8", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-PbrTBbofFcacrH3RLgHYILRqTFnAGq+gXrXoA/vo7qUSkJpSO4GWfLtrtCahD4VayzRm19IPwcjPPLEugag6pw=="], + "@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], "@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.168.0", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16" }, "peerDependencies": { "@tanstack/router-core": "^1.170.0", "csstype": "^3.0.10" }, "optionalPeers": ["csstype"] }, "sha512-wQoQhlBK7nlZgqzaqdYXKWNTpdHdsaREdaPhFZVH0/Ador+F+eM3/NF2i3f2LPeS0GgKraZUQXe1Q/1+KHyEYg=="], - "@tanstack/router-generator": ["@tanstack/router-generator@1.167.12", "", { "dependencies": { "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.8", "@tanstack/router-utils": "1.162.1", "@tanstack/virtual-file-routes": "1.162.0", "jiti": "^2.7.0", "magic-string": "^0.30.21", "prettier": "^3.5.0", "zod": "^4.4.3" } }, "sha512-FGr7nn6VhjL53TUCTyDgApSkAYRxhId+v0HVQdSu0ADkNuHY+sUnYEMqiF6aN82jYWuXzrSL1xazg6/rfEP82g=="], + "@tanstack/router-generator": ["@tanstack/router-generator@1.167.17", "", { "dependencies": { "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.13", "@tanstack/router-utils": "1.162.2", "@tanstack/virtual-file-routes": "1.162.0", "jiti": "^2.7.0", "magic-string": "^0.30.21", "prettier": "^3.5.0", "zod": "^4.4.3" } }, "sha512-xtB9tB2Ws0tWR6Pi7nc3Qk9IYgoh1mQCKWjHqIl9tf6BNUpKoqniJoPAQ4+LGrK8FeZYU0o0p/qlZEyj9FAulA=="], - "@tanstack/router-plugin": ["@tanstack/router-plugin@1.168.13", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.8", "@tanstack/router-generator": "1.167.12", "@tanstack/router-utils": "1.162.1", "@tanstack/virtual-file-routes": "1.162.0", "chokidar": "^5.0.0", "unplugin": "^3.0.0", "zod": "^4.4.3" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2 || ^2.0.0", "@tanstack/react-router": "^1.170.10", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-LnepwDai+TaC4K3aZeXrrKpnGoP8xGGilVGFfa5flGgC3+jCSBysb8SktidRE8eF2/iOzCQC0LIGirtMyZepSA=="], + "@tanstack/router-plugin": ["@tanstack/router-plugin@1.168.18", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.13", "@tanstack/router-generator": "1.167.17", "@tanstack/router-utils": "1.162.2", "chokidar": "^5.0.0", "unplugin": "^3.0.0", "zod": "^4.4.3" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2 || ^2.0.0", "@tanstack/react-router": "^1.170.15", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-MofS28/axfnfnhOD2RSgJEaU882aX5RsAzhGz5Vc4XhAmvCjy919u9JrNs4QsTWFbTD1P7IJ8WFlFVsrg0pStg=="], - "@tanstack/router-utils": ["@tanstack/router-utils@1.162.1", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/generator": "^7.28.5", "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "ansis": "^4.1.0", "babel-dead-code-elimination": "^1.0.12", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-62layyTGmclHDQS/eidwKRfN1hhCKwViG7iEBcVmL0MXgcAB3OOucWCEcDDGd9Cu11H6b4QQ5oOo47MWIqwz0A=="], + "@tanstack/router-utils": ["@tanstack/router-utils@1.162.2", "", { "dependencies": { "@babel/generator": "^7.28.5", "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "ansis": "^4.1.0", "babel-dead-code-elimination": "^1.0.12", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-hTWqJtqIFFdvuCl8WXNyrodp2L9zo2G37xKRrcVmVRWpAB2h+U1LuRAfS4tsFTiWOIoE/B+WDVFB8JpoEdw6jQ=="], "@tanstack/store": ["@tanstack/store@0.9.3", "", {}, "sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw=="], @@ -1072,7 +1076,7 @@ "@turbo/windows-arm64": ["@turbo/windows-arm64@2.9.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-Y7SJppD0Z8wjO3Ec0ZGd9KQ4Yv0BMnA8CIowj5Vp+OEVsosXDG2weK6/t1RRLfJmc2Ozrnd6y4DOgQys+mn3WQ=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], "@typed/id": ["@typed/id@0.17.2", "", { "peerDependencies": { "effect": "^3.14.7" } }, "sha512-z/Z14/moeu9x45IpkGaRwuvb+CQ3s3UCc/agcpZibTz1yPb3RgSDXx4rOHIuyb6hG6oNzqe9yY4GbbMq3Hb5Ug=="], @@ -1094,11 +1098,7 @@ "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], - "@types/eslint": ["@types/eslint@9.6.1", "", { "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag=="], - - "@types/eslint-scope": ["@types/eslint-scope@3.7.7", "", { "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg=="], - - "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], @@ -1130,21 +1130,21 @@ "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], - "@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="], + "@types/mdx": ["@types/mdx@2.0.14", "", {}, "sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg=="], "@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="], "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], + "@types/node": ["@types/node@25.9.2", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw=="], "@types/prismjs": ["@types/prismjs@1.26.6", "", {}, "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw=="], - "@types/qs": ["@types/qs@6.15.0", "", {}, "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow=="], + "@types/qs": ["@types/qs@6.15.1", "", {}, "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw=="], "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="], - "@types/react": ["@types/react@19.2.15", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q=="], + "@types/react": ["@types/react@19.2.17", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw=="], "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], @@ -1158,7 +1158,7 @@ "@types/sax": ["@types/sax@1.2.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A=="], - "@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="], + "@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="], "@types/serve-index": ["@types/serve-index@1.9.4", "", { "dependencies": { "@types/express": "*" } }, "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug=="], @@ -1174,7 +1174,7 @@ "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], - "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.1", "", {}, "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ=="], "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.2", "", { "dependencies": { "@rolldown/pluginutils": "^1.0.0" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg=="], @@ -1242,15 +1242,15 @@ "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], - "ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], + "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], "ajv-formats": ["ajv-formats@2.1.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="], "ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], - "algoliasearch": ["algoliasearch@5.50.0", "", { "dependencies": { "@algolia/abtesting": "1.16.0", "@algolia/client-abtesting": "5.50.0", "@algolia/client-analytics": "5.50.0", "@algolia/client-common": "5.50.0", "@algolia/client-insights": "5.50.0", "@algolia/client-personalization": "5.50.0", "@algolia/client-query-suggestions": "5.50.0", "@algolia/client-search": "5.50.0", "@algolia/ingestion": "1.50.0", "@algolia/monitoring": "1.50.0", "@algolia/recommend": "5.50.0", "@algolia/requester-browser-xhr": "5.50.0", "@algolia/requester-fetch": "5.50.0", "@algolia/requester-node-http": "5.50.0" } }, "sha512-yE5I83Q2s8euVou8Y3feXK08wyZInJWLYXgWO6Xti9jBUEZAGUahyeQ7wSZWkifLWVnQVKEz5RAmBlXG5nqxog=="], + "algoliasearch": ["algoliasearch@5.53.0", "", { "dependencies": { "@algolia/abtesting": "1.19.0", "@algolia/client-abtesting": "5.53.0", "@algolia/client-analytics": "5.53.0", "@algolia/client-common": "5.53.0", "@algolia/client-insights": "5.53.0", "@algolia/client-personalization": "5.53.0", "@algolia/client-query-suggestions": "5.53.0", "@algolia/client-search": "5.53.0", "@algolia/ingestion": "1.53.0", "@algolia/monitoring": "1.53.0", "@algolia/recommend": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-OGW1q6b91CRSSeiOnM8LxuR5NYJ2esvw66jUZ4IIvdv+ItNkx3pwLuyR+jaCdbGee4ov5WgUnyPryyh11xvByQ=="], - "algoliasearch-helper": ["algoliasearch-helper@3.28.1", "", { "dependencies": { "@algolia/events": "^4.0.1" }, "peerDependencies": { "algoliasearch": ">= 3.1 < 6" } }, "sha512-6iXpbkkrAI5HFpCWXlNmIDSBuoN/U1XnEvb2yJAoWfqrZ+DrybI7MQ5P5mthFaprmocq+zbi6HxnR28xnZAYBw=="], + "algoliasearch-helper": ["algoliasearch-helper@3.29.1", "", { "dependencies": { "@algolia/events": "^4.0.1" }, "peerDependencies": { "algoliasearch": ">= 3.1 < 6" } }, "sha512-6ck2YFudF2Pje7szQoPBiRFTGfd+1I+0I/WfLPGn0bj1kvrFoOQmNyedNiDxTk3/r4IfSLDYk+RA4G7u8H6+yA=="], "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="], @@ -1260,7 +1260,7 @@ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="], + "ansis": ["ansis@4.3.1", "", {}, "sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA=="], "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], @@ -1276,13 +1276,13 @@ "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], - "asn1js": ["asn1js@3.0.7", "", { "dependencies": { "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" } }, "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ=="], + "asn1js": ["asn1js@3.0.10", "", { "dependencies": { "pvtsutils": "^1.3.6", "pvutils": "^1.1.5", "tslib": "^2.8.1" } }, "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg=="], "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], - "autoprefixer": ["autoprefixer@10.4.27", "", { "dependencies": { "browserslist": "^4.28.1", "caniuse-lite": "^1.0.30001774", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA=="], + "autoprefixer": ["autoprefixer@10.5.0", "", { "dependencies": { "browserslist": "^4.28.2", "caniuse-lite": "^1.0.30001787", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong=="], "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="], @@ -1300,7 +1300,7 @@ "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.13", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-BL2sTuHOdy0YT1lYieUxTw/QMtPBC3pmlJC6xk8BBYVv6vcw3SGdKemQ+Xsx9ik2F/lYDO9tqsFQH1r9PFuHKw=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.10.34", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw=="], "batch": ["batch@0.6.1", "", {}, "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw=="], @@ -1308,15 +1308,15 @@ "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], - "body-parser": ["body-parser@1.20.4", "", { "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "~1.2.0", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.14.0", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA=="], + "body-parser": ["body-parser@1.20.5", "", { "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "~1.2.0", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.15.1", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA=="], - "bonjour-service": ["bonjour-service@1.3.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA=="], + "bonjour-service": ["bonjour-service@1.4.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "sha512-fGQtj1qdR9vIKjFiWPQd52qIqwjaYqhcI40JEiDuvlZ86E7ZBPBwY9fPgHy9r2rYGIjiRfctNPYz6OQU73ww2w=="], "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], "boxen": ["boxen@6.2.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^6.2.0", "chalk": "^4.1.2", "cli-boxes": "^3.0.0", "string-width": "^5.0.1", "type-fest": "^2.5.0", "widest-line": "^4.0.1", "wrap-ansi": "^8.0.1" } }, "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw=="], - "brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="], + "brace-expansion": ["brace-expansion@1.1.15", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], @@ -1338,7 +1338,7 @@ "cacheable-request": ["cacheable-request@10.2.14", "", { "dependencies": { "@types/http-cache-semantics": "^4.0.2", "get-stream": "^6.0.1", "http-cache-semantics": "^4.1.1", "keyv": "^4.5.3", "mimic-response": "^4.0.0", "normalize-url": "^8.0.0", "responselike": "^3.0.0" } }, "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ=="], - "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="], + "call-bind": ["call-bind@1.0.9", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" } }, "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ=="], "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], @@ -1352,7 +1352,7 @@ "caniuse-api": ["caniuse-api@3.0.0", "", { "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw=="], - "caniuse-lite": ["caniuse-lite@1.0.30001782", "", {}, "sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw=="], + "caniuse-lite": ["caniuse-lite@1.0.30001797", "", {}, "sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], @@ -1458,7 +1458,7 @@ "css-blank-pseudo": ["css-blank-pseudo@7.0.1", "", { "dependencies": { "postcss-selector-parser": "^7.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag=="], - "css-declaration-sorter": ["css-declaration-sorter@7.3.1", "", { "peerDependencies": { "postcss": "^8.0.9" } }, "sha512-gz6x+KkgNCjxq3Var03pRYLhyNfwhkKF1g/yoLgDNtFvVu0/fOLV9C8fFEZRjACp/XQLumjAYo7JVjzH3wLbxA=="], + "css-declaration-sorter": ["css-declaration-sorter@7.4.0", "", { "peerDependencies": { "postcss": "^8.0.9" } }, "sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw=="], "css-has-pseudo": ["css-has-pseudo@7.0.3", "", { "dependencies": { "@csstools/selector-specificity": "^5.0.0", "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA=="], @@ -1474,7 +1474,7 @@ "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], - "cssdb": ["cssdb@8.8.0", "", {}, "sha512-QbLeyz2Bgso1iRlh7IpWk6OKa3lLNGXsujVjDMPl9rOZpxKeiG69icLpbLCFxeURwmcdIfZqQyhlooKJYM4f8Q=="], + "cssdb": ["cssdb@8.9.0", "", {}, "sha512-J8jOU/hLjaXcO1LldOLraJSQpfLXRKof0I7mtbRyOy2AAXgqst0x9rlgi2qXeD6d0ou3ZLqcPAMqYVbpCbrxEw=="], "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], @@ -1570,13 +1570,13 @@ "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], - "effect": ["effect@3.21.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-rXd2FGDM8KdjSIrc+mqEELo7ScW7xTVxEf1iInmPSpIde9/nyGuFM710cjTo7/EreGXiUX2MOonPpprbz2XHCg=="], + "effect": ["effect@3.21.3", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-RqwU7WnJ6CqYhyjpOVJA5vh1Sgkn6eVECO6mnD0EjlbWcC2M3LJaPglXXr13Rdo/Y+B+wTEPzGRYFNL2xKxNeQ=="], "effect-fc": ["effect-fc@workspace:packages/effect-fc"], "effect-lens": ["effect-lens@0.2.0", "", { "peerDependencies": { "effect": "^3.21.0" } }, "sha512-Cfyps811WQVSxnbxm6xqJldL08YXUU1jAzWtdKXSKWZfF6LAEqm1l8swnw4ltVky1TSfi2vvS+I/tFPqwObrMg=="], - "electron-to-chromium": ["electron-to-chromium@1.5.329", "", {}, "sha512-/4t+AS1l4S3ZC0Ja7PHFIWeBIxGA3QGqV8/yKsP36v7NcyUCl+bIcmw6s5zVuMIECWwBrAK/6QLzTmbJChBboQ=="], + "electron-to-chromium": ["electron-to-chromium@1.5.368", "", {}, "sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw=="], "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], @@ -1588,7 +1588,7 @@ "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], - "enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="], + "enhanced-resolve": ["enhanced-resolve@5.23.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA=="], "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], @@ -1598,9 +1598,9 @@ "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], - "es-module-lexer": ["es-module-lexer@2.0.0", "", {}, "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw=="], + "es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], - "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + "es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="], "esast-util-from-estree": ["esast-util-from-estree@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "unist-util-position-from-estree": "^2.0.0" } }, "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ=="], @@ -1656,7 +1656,7 @@ "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], - "express": ["express@4.22.1", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.3", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g=="], + "express": ["express@4.22.2", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.5", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q=="], "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], @@ -1670,7 +1670,7 @@ "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], - "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], + "fast-uri": ["fast-uri@3.1.2", "", {}, "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ=="], "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], @@ -1696,7 +1696,7 @@ "flat": ["flat@5.0.2", "", { "bin": { "flat": "cli.js" } }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="], - "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], + "follow-redirects": ["follow-redirects@1.16.0", "", {}, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="], "form-data-encoder": ["form-data-encoder@2.1.4", "", {}, "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw=="], @@ -1708,7 +1708,7 @@ "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="], - "fs-extra": ["fs-extra@11.3.4", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA=="], + "fs-extra": ["fs-extra@11.3.5", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -1740,7 +1740,7 @@ "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], - "goober": ["goober@2.1.18", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw=="], + "goober": ["goober@2.1.19", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-U7veizMqxyKlM58+Z5j2ngJBH/r9siDmxpvNxSw0PylF6WQvrASJEZrxh1hidRBJc2jqoBVSyOban5u8m+6Rxg=="], "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], @@ -1762,7 +1762,7 @@ "has-yarn": ["has-yarn@3.0.0", "", {}, "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA=="], - "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="], @@ -1798,7 +1798,7 @@ "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], - "html-webpack-plugin": ["html-webpack-plugin@5.6.6", "", { "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", "lodash": "^4.17.21", "pretty-error": "^4.0.0", "tapable": "^2.0.0" }, "peerDependencies": { "@rspack/core": "0.x || 1.x", "webpack": "^5.20.0" }, "optionalPeers": ["@rspack/core", "webpack"] }, "sha512-bLjW01UTrvoWTJQL5LsMRo1SypHW80FTm12OJRSnr3v6YHNhfe+1r0MYUZJMACxnCHURVnBWRwAsWs2yPU9Ezw=="], + "html-webpack-plugin": ["html-webpack-plugin@5.6.7", "", { "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", "lodash": "^4.17.21", "pretty-error": "^4.0.0", "tapable": "^2.0.0" }, "peerDependencies": { "@rspack/core": "0.x || 1.x", "webpack": "^5.20.0" }, "optionalPeers": ["@rspack/core", "webpack"] }, "sha512-md+vXtdCAe60s1k6AU3dUyMJnDxUyQAwfwPKoLisvgUF1IXjtlLsk2se54+qfL9Mdm26bbwvjJybpNx48NKRLw=="], "htmlparser2": ["htmlparser2@8.0.2", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" } }, "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA=="], @@ -1850,7 +1850,7 @@ "invariant": ["invariant@2.2.4", "", { "dependencies": { "loose-envify": "^1.0.0" } }, "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA=="], - "ipaddr.js": ["ipaddr.js@2.3.0", "", {}, "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg=="], + "ipaddr.js": ["ipaddr.js@2.4.0", "", {}, "sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ=="], "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], @@ -1862,7 +1862,7 @@ "is-ci": ["is-ci@3.0.1", "", { "dependencies": { "ci-info": "^3.2.0" }, "bin": { "is-ci": "bin.js" } }, "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ=="], - "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], + "is-core-module": ["is-core-module@2.16.2", "", { "dependencies": { "hasown": "^2.0.3" } }, "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA=="], "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], @@ -1882,7 +1882,7 @@ "is-installed-globally": ["is-installed-globally@0.4.0", "", { "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" } }, "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ=="], - "is-network-error": ["is-network-error@1.3.1", "", {}, "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw=="], + "is-network-error": ["is-network-error@1.3.2", "", {}, "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA=="], "is-npm": ["is-npm@6.1.0", "", {}, "sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA=="], @@ -1910,7 +1910,7 @@ "isarray": ["isarray@0.0.1", "", {}, "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="], - "isbot": ["isbot@5.1.37", "", {}, "sha512-5bcicX81xf6NlTEV8rWdg7Pk01LFizDetuYGHx6d/f6y3lR2/oo8IfxjzJqn1UdDEyCcwT9e7NRloj8DwCYujQ=="], + "isbot": ["isbot@5.1.41", "", {}, "sha512-9WFV/Vhh0FEj6CQ7MoHweEL9/vLKPjeoD2I2htbAjX7kbW7VJs3OCpWOVyd+JraNTWVU6/DRx2MZy2KaUNXHcg=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], @@ -1926,7 +1926,7 @@ "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "js-yaml": ["js-yaml@4.2.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw=="], "jsdom": ["jsdom@26.1.0", "", { "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", "decimal.js": "^10.5.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.6", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.16", "parse5": "^7.2.1", "rrweb-cssom": "^0.8.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^5.1.1", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.1.1", "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg=="], @@ -1940,7 +1940,7 @@ "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], - "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], + "jsonfile": ["jsonfile@6.2.1", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q=="], "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], @@ -1950,7 +1950,7 @@ "latest-version": ["latest-version@7.0.0", "", { "dependencies": { "package-json": "^8.1.0" } }, "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg=="], - "launch-editor": ["launch-editor@2.13.2", "", { "dependencies": { "picocolors": "^1.1.1", "shell-quote": "^1.8.3" } }, "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg=="], + "launch-editor": ["launch-editor@2.14.1", "", { "dependencies": { "picocolors": "^1.1.1", "shell-quote": "^1.8.4" } }, "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA=="], "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="], @@ -1982,13 +1982,13 @@ "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], - "loader-runner": ["loader-runner@4.3.1", "", {}, "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q=="], + "loader-runner": ["loader-runner@4.3.2", "", {}, "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w=="], "loader-utils": ["loader-utils@2.0.4", "", { "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw=="], "locate-path": ["locate-path@7.2.0", "", { "dependencies": { "p-locate": "^6.0.0" } }, "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA=="], - "lodash": ["lodash@4.18.0", "", {}, "sha512-l1mfj2atMqndAHI3ls7XqPxEjV2J9ZkcNyHpoZA3r2T1LLwDB69jgkMWh71YKwhBbK0G2f4WSn05ahmQXVxupA=="], + "lodash": ["lodash@4.18.1", "", {}, "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="], "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], @@ -2058,7 +2058,7 @@ "media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], - "memfs": ["memfs@4.57.1", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.1", "@jsonjoy.com/fs-fsa": "4.57.1", "@jsonjoy.com/fs-node": "4.57.1", "@jsonjoy.com/fs-node-builtins": "4.57.1", "@jsonjoy.com/fs-node-to-fsa": "4.57.1", "@jsonjoy.com/fs-node-utils": "4.57.1", "@jsonjoy.com/fs-print": "4.57.1", "@jsonjoy.com/fs-snapshot": "4.57.1", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", "thingies": "^2.5.0", "tree-dump": "^1.0.3", "tslib": "^2.0.0" } }, "sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ=="], + "memfs": ["memfs@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.6", "@jsonjoy.com/fs-fsa": "4.57.6", "@jsonjoy.com/fs-node": "4.57.6", "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-to-fsa": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6", "@jsonjoy.com/fs-print": "4.57.6", "@jsonjoy.com/fs-snapshot": "4.57.6", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", "thingies": "^2.5.0", "tree-dump": "^1.0.3", "tslib": "^2.0.0" } }, "sha512-WQK+DGjKCnPdpSyJUXphz+COF2uEhhsxQ3VIWBSbzpbbXuch3h4FePMqXrXGdLjsTgo4JFzBFsP6AWd9pVazGw=="], "merge-descriptors": ["merge-descriptors@1.0.3", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="], @@ -2146,9 +2146,9 @@ "mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], - "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], - "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "mime-types": ["mime-types@2.1.18", "", { "dependencies": { "mime-db": "~1.33.0" } }, "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ=="], "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], @@ -2166,9 +2166,9 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "msgpackr": ["msgpackr@1.11.10", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-iCZNq+HszvF+fC3anCm4nBmWEnbeIAfpDs6IStAEKhQ2YSgkjzVG2FF9XJqwwQh5bH3N9OUTUt4QwVN6MLMLtA=="], + "msgpackr": ["msgpackr@1.11.14", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-suPZQcjFtPGp0cksn70ICfLuxsO9F2/sRrbJzeNepojZ+OPwGzA0lNdLyU4SJUKAd5ZgvUWWPojzzdlVuOYcrQ=="], - "msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="], + "msgpackr-extract": ["msgpackr-extract@3.0.4", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw=="], "multicast-dns": ["multicast-dns@7.2.5", "", { "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" }, "bin": { "multicast-dns": "cli.js" } }, "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg=="], @@ -2186,13 +2186,13 @@ "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="], - "node-releases": ["node-releases@2.0.36", "", {}, "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA=="], + "node-releases": ["node-releases@2.0.47", "", {}, "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], "normalize-url": ["normalize-url@8.1.1", "", {}, "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ=="], - "npm-check-updates": ["npm-check-updates@22.2.1", "", { "bin": { "npm-check-updates": "build/cli.js", "ncu": "build/cli.js" } }, "sha512-mGdIJfhtg+q0BzhbOpbOL73zhMZlgBQMG4wnBwPMMD5k96028UCuV0753YeSYk9odoh7HWK6/cY69bWxT7o+yg=="], + "npm-check-updates": ["npm-check-updates@22.2.3", "", { "bin": { "npm-check-updates": "build/cli.js", "ncu": "build/cli.js" } }, "sha512-n8HZ0ywZugYRgEqIm67hbZC5L/9S/gLX+MkGchJB43pP2xib1+u76OpVEJRZ4QP2BksPRi5M1CCStJVfc16+/A=="], "npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], @@ -2418,7 +2418,7 @@ "postcss-zindex": ["postcss-zindex@6.0.2", "", { "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg=="], - "prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="], + "prettier": ["prettier@3.8.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="], "pretty-error": ["pretty-error@4.0.0", "", { "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" } }, "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw=="], @@ -2436,7 +2436,7 @@ "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], - "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], + "property-information": ["property-information@7.2.0", "", {}, "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg=="], "proto-list": ["proto-list@1.2.4", "", {}, "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="], @@ -2452,13 +2452,13 @@ "pvutils": ["pvutils@1.1.5", "", {}, "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA=="], - "qs": ["qs@6.14.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q=="], + "qs": ["qs@6.15.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw=="], "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], - "radix-ui": ["radix-ui@1.4.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-accessible-icon": "1.1.7", "@radix-ui/react-accordion": "1.2.12", "@radix-ui/react-alert-dialog": "1.1.15", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-aspect-ratio": "1.1.7", "@radix-ui/react-avatar": "1.1.10", "@radix-ui/react-checkbox": "1.3.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-context-menu": "2.2.16", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-dropdown-menu": "2.1.16", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-form": "0.1.8", "@radix-ui/react-hover-card": "1.1.15", "@radix-ui/react-label": "2.1.7", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-menubar": "1.1.16", "@radix-ui/react-navigation-menu": "1.2.14", "@radix-ui/react-one-time-password-field": "0.1.8", "@radix-ui/react-password-toggle-field": "0.1.3", "@radix-ui/react-popover": "1.1.15", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-progress": "1.1.7", "@radix-ui/react-radio-group": "1.3.8", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-scroll-area": "1.2.10", "@radix-ui/react-select": "2.2.6", "@radix-ui/react-separator": "1.1.7", "@radix-ui/react-slider": "1.3.6", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-switch": "1.2.6", "@radix-ui/react-tabs": "1.1.13", "@radix-ui/react-toast": "1.2.15", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-toggle-group": "1.1.11", "@radix-ui/react-toolbar": "1.1.11", "@radix-ui/react-tooltip": "1.2.8", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-escape-keydown": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA=="], + "radix-ui": ["radix-ui@1.5.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-accessible-icon": "1.1.9", "@radix-ui/react-accordion": "1.2.13", "@radix-ui/react-alert-dialog": "1.1.16", "@radix-ui/react-arrow": "1.1.9", "@radix-ui/react-aspect-ratio": "1.1.9", "@radix-ui/react-avatar": "1.1.12", "@radix-ui/react-checkbox": "1.3.4", "@radix-ui/react-collapsible": "1.1.13", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-context-menu": "2.3.0", "@radix-ui/react-dialog": "1.1.16", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-dropdown-menu": "2.1.17", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-form": "0.1.9", "@radix-ui/react-hover-card": "1.1.16", "@radix-ui/react-label": "2.1.9", "@radix-ui/react-menu": "2.1.17", "@radix-ui/react-menubar": "1.1.17", "@radix-ui/react-navigation-menu": "1.2.15", "@radix-ui/react-one-time-password-field": "0.1.9", "@radix-ui/react-password-toggle-field": "0.1.4", "@radix-ui/react-popover": "1.1.16", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-progress": "1.1.9", "@radix-ui/react-radio-group": "1.4.0", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-scroll-area": "1.2.11", "@radix-ui/react-select": "2.3.0", "@radix-ui/react-separator": "1.1.9", "@radix-ui/react-slider": "1.4.0", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-switch": "1.3.0", "@radix-ui/react-tabs": "1.1.14", "@radix-ui/react-toast": "1.2.16", "@radix-ui/react-toggle": "1.1.11", "@radix-ui/react-toggle-group": "1.1.12", "@radix-ui/react-toolbar": "1.1.12", "@radix-ui/react-tooltip": "1.2.9", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-escape-keydown": "1.1.2", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nzh2HNpClgB31FBHRqt2xG8XNUfVfQRpf34hACC5PNrXTd5JdXdqOXwLs3BL+D8CNYiNQiJiT8QGr5Q4vq+00w=="], "randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="], @@ -2468,9 +2468,9 @@ "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], - "react": ["react@19.2.6", "", {}, "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q=="], + "react": ["react@19.2.7", "", {}, "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ=="], - "react-dom": ["react-dom@19.2.6", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.6" } }, "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g=="], + "react-dom": ["react-dom@19.2.7", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.7" } }, "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ=="], "react-fast-compare": ["react-fast-compare@3.2.2", "", {}, "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="], @@ -2524,7 +2524,7 @@ "regjsgen": ["regjsgen@0.8.0", "", {}, "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q=="], - "regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="], + "regjsparser": ["regjsparser@0.13.1", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw=="], "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], @@ -2556,7 +2556,7 @@ "requires-port": ["requires-port@1.0.0", "", {}, "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="], - "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], + "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], "resolve-alpn": ["resolve-alpn@1.2.1", "", {}, "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="], @@ -2604,7 +2604,7 @@ "selfsigned": ["selfsigned@5.5.0", "", { "dependencies": { "@peculiar/x509": "^1.14.2", "pkijs": "^3.3.3" } }, "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew=="], - "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + "semver": ["semver@7.8.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ=="], "semver-diff": ["semver-diff@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA=="], @@ -2634,11 +2634,11 @@ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], - "shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="], + "shell-quote": ["shell-quote@1.8.4", "", {}, "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ=="], "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], - "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], + "side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="], "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], @@ -2724,11 +2724,11 @@ "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="], - "tapable": ["tapable@2.3.2", "", {}, "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA=="], + "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="], - "terser": ["terser@5.46.1", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ=="], + "terser": ["terser@5.48.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q=="], - "terser-webpack-plugin": ["terser-webpack-plugin@5.4.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", "terser": "^5.31.1" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g=="], + "terser-webpack-plugin": ["terser-webpack-plugin@5.6.1", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", "terser": "^5.31.1" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ=="], "thingies": ["thingies@2.6.0", "", { "peerDependencies": { "tslib": "^2" } }, "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg=="], @@ -2784,7 +2784,7 @@ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], - "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], + "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="], @@ -2868,23 +2868,23 @@ "webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], - "webpack": ["webpack@5.105.4", "", { "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.20.0", "es-module-lexer": "^2.0.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "terser-webpack-plugin": "^5.3.17", "watchpack": "^2.5.1", "webpack-sources": "^3.3.4" }, "bin": { "webpack": "bin/webpack.js" } }, "sha512-jTywjboN9aHxFlToqb0K0Zs9SbBoW4zRUlGzI2tYNxVYcEi/IPpn+Xi4ye5jTLvX2YeLuic/IvxNot+Q1jMoOw=="], + "webpack": ["webpack@5.107.2", "", { "dependencies": { "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.22.0", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "loader-runner": "^4.3.2", "mime-db": "^1.54.0", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "terser-webpack-plugin": "^5.5.0", "watchpack": "^2.5.1", "webpack-sources": "^3.5.0" }, "bin": { "webpack": "bin/webpack.js" } }, "sha512-v7RhXaJbpMlV0D7hC7lb2EbnxkoeUqf9qhKr6lozx3Q48pmFrqqNRmZFUEGmi7pSwm6fCQ2H1IjvCkHqdpVdjQ=="], "webpack-bundle-analyzer": ["webpack-bundle-analyzer@4.10.2", "", { "dependencies": { "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", "commander": "^7.2.0", "debounce": "^1.2.1", "escape-string-regexp": "^4.0.0", "gzip-size": "^6.0.0", "html-escaper": "^2.0.2", "opener": "^1.5.2", "picocolors": "^1.0.0", "sirv": "^2.0.3", "ws": "^7.3.1" }, "bin": { "webpack-bundle-analyzer": "lib/bin/analyzer.js" } }, "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw=="], "webpack-dev-middleware": ["webpack-dev-middleware@7.4.5", "", { "dependencies": { "colorette": "^2.0.10", "memfs": "^4.43.1", "mime-types": "^3.0.1", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" }, "peerDependencies": { "webpack": "^5.0.0" }, "optionalPeers": ["webpack"] }, "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA=="], - "webpack-dev-server": ["webpack-dev-server@5.2.3", "", { "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", "@types/express": "^4.17.25", "@types/express-serve-static-core": "^4.17.21", "@types/serve-index": "^1.9.4", "@types/serve-static": "^1.15.5", "@types/sockjs": "^0.3.36", "@types/ws": "^8.5.10", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.2.1", "chokidar": "^3.6.0", "colorette": "^2.0.10", "compression": "^1.8.1", "connect-history-api-fallback": "^2.0.0", "express": "^4.22.1", "graceful-fs": "^4.2.6", "http-proxy-middleware": "^2.0.9", "ipaddr.js": "^2.1.0", "launch-editor": "^2.6.1", "open": "^10.0.3", "p-retry": "^6.2.0", "schema-utils": "^4.2.0", "selfsigned": "^5.5.0", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", "webpack-dev-middleware": "^7.4.2", "ws": "^8.18.0" }, "peerDependencies": { "webpack": "^5.0.0" }, "optionalPeers": ["webpack"], "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" } }, "sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ=="], + "webpack-dev-server": ["webpack-dev-server@5.2.4", "", { "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", "@types/express": "^4.17.25", "@types/express-serve-static-core": "^4.17.21", "@types/serve-index": "^1.9.4", "@types/serve-static": "^1.15.5", "@types/sockjs": "^0.3.36", "@types/ws": "^8.5.10", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.2.1", "chokidar": "^3.6.0", "colorette": "^2.0.10", "compression": "^1.8.1", "connect-history-api-fallback": "^2.0.0", "express": "^4.22.1", "graceful-fs": "^4.2.6", "http-proxy-middleware": "^2.0.9", "ipaddr.js": "^2.1.0", "launch-editor": "^2.6.1", "open": "^10.0.3", "p-retry": "^6.2.0", "schema-utils": "^4.2.0", "selfsigned": "^5.5.0", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", "webpack-dev-middleware": "^7.4.2", "ws": "^8.18.0" }, "peerDependencies": { "webpack": "^5.0.0" }, "optionalPeers": ["webpack"], "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" } }, "sha512-GqDPGZN9bRqKBTkp4aWkobDDHMsrXKoGSdOH56smIri8qR0JG8gfL8/v/f/OZR3/OKXjG8uwJbFVhKm/FNU/UA=="], "webpack-merge": ["webpack-merge@5.10.0", "", { "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", "wildcard": "^2.0.0" } }, "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA=="], - "webpack-sources": ["webpack-sources@3.3.4", "", {}, "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q=="], + "webpack-sources": ["webpack-sources@3.5.0", "", {}, "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ=="], "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], "webpackbar": ["webpackbar@7.0.0", "", { "dependencies": { "ansis": "^3.2.0", "consola": "^3.2.3", "pretty-time": "^1.1.0", "std-env": "^3.7.0" }, "peerDependencies": { "@rspack/core": "*", "webpack": "3 || 4 || 5" }, "optionalPeers": ["@rspack/core", "webpack"] }, "sha512-aS9soqSO2iCHgqHoCrj4LbfGQUboDCYJPSFOAchEK+9psIjNrfSWW4Y0YEz67MKURNvMmfo0ycOg9d/+OOf9/Q=="], - "websocket-driver": ["websocket-driver@0.7.4", "", { "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg=="], + "websocket-driver": ["websocket-driver@0.7.5", "", { "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, "sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA=="], "websocket-extensions": ["websocket-extensions@0.1.4", "", {}, "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="], @@ -2906,7 +2906,7 @@ "write-file-atomic": ["write-file-atomic@3.0.3", "", { "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q=="], - "ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], + "ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], @@ -2942,22 +2942,12 @@ "@babel/preset-env/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@docusaurus/bundler/postcss": ["postcss@8.5.12", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA=="], + "@docsearch/react/@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.19.2", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", "@algolia/autocomplete-shared": "1.19.2" } }, "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw=="], "@docusaurus/core/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], "@docusaurus/core/webpack-merge": ["webpack-merge@6.0.1", "", { "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", "wildcard": "^2.0.1" } }, "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg=="], - "@docusaurus/cssnano-preset/postcss": ["postcss@8.5.12", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA=="], - - "@docusaurus/module-type-aliases/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], - - "@docusaurus/theme-classic/postcss": ["postcss@8.5.12", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA=="], - - "@docusaurus/theme-common/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], - - "@docusaurus/types/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], - "@docusaurus/utils/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], "@jsonjoy.com/fs-snapshot/@jsonjoy.com/json-pack": ["@jsonjoy.com/json-pack@17.67.0", "", { "dependencies": { "@jsonjoy.com/base64": "17.67.0", "@jsonjoy.com/buffers": "17.67.0", "@jsonjoy.com/codegen": "17.67.0", "@jsonjoy.com/json-pointer": "17.67.0", "@jsonjoy.com/util": "17.67.0", "hyperdyperid": "^1.2.0", "thingies": "^2.5.0", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w=="], @@ -2974,11 +2964,9 @@ "@svgr/hast-util-to-babel-ast/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - "@types/react-router/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], + "@types/serve-static/@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="], - "@types/react-router-config/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], - - "@types/react-router-dom/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], + "accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], "accepts/negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], @@ -3002,8 +2990,6 @@ "cli-table3/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "compressible/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], - "compression/bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], "compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -3016,12 +3002,8 @@ "crypto-random-string/type-fest": ["type-fest@1.4.0", "", {}, "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="], - "css-loader/postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], - "css-minimizer-webpack-plugin/jest-worker": ["jest-worker@29.7.0", "", { "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw=="], - "css-minimizer-webpack-plugin/postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], - "css-select/domhandler": ["domhandler@4.3.1", "", { "dependencies": { "domelementtype": "^2.2.0" } }, "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ=="], "css-select/domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="], @@ -3194,6 +3176,8 @@ "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + "mime-types/mime-db": ["mime-db@1.33.0", "", {}, "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="], + "null-loader/schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="], "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], @@ -3224,28 +3208,22 @@ "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], - "react-loadable/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], - "renderkid/htmlparser2": ["htmlparser2@6.1.0", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", "domutils": "^2.5.2", "entities": "^2.0.0" } }, "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A=="], "renderkid/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "rollup/@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], - - "rtlcss/postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], - "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "send/range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], - "serve-handler/mime-types": ["mime-types@2.1.18", "", { "dependencies": { "mime-db": "~1.33.0" } }, "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ=="], - "serve-handler/path-to-regexp": ["path-to-regexp@3.3.0", "", {}, "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw=="], "serve-index/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "serve-index/http-errors": ["http-errors@1.8.1", "", { "dependencies": { "depd": "~1.1.2", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": ">= 1.5.0 < 2", "toidentifier": "1.0.1" } }, "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g=="], + "serve-index/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "sitemap/@types/node": ["@types/node@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="], "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], @@ -3264,10 +3242,14 @@ "tsyringe/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], + "type-is/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "update-notifier/boxen": ["boxen@7.1.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^7.0.1", "chalk": "^5.2.0", "cli-boxes": "^3.0.0", "string-width": "^5.1.2", "type-fest": "^2.13.0", "widest-line": "^4.0.1", "wrap-ansi": "^8.1.0" } }, "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog=="], "update-notifier/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + "url-loader/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "url-loader/schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="], "vite-node/es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], @@ -3278,7 +3260,7 @@ "webpack-bundle-analyzer/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], - "webpack-bundle-analyzer/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], + "webpack-bundle-analyzer/ws": ["ws@7.5.11", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA=="], "webpack-dev-middleware/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], @@ -3294,14 +3276,12 @@ "wsl-utils/is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="], - "@docusaurus/bundler/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "@docsearch/react/@algolia/autocomplete-core/@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.19.2", "", { "dependencies": { "@algolia/autocomplete-shared": "1.19.2" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg=="], + + "@docsearch/react/@algolia/autocomplete-core/@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.19.2", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w=="], "@docusaurus/core/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - "@docusaurus/cssnano-preset/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - - "@docusaurus/theme-classic/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "@jsonjoy.com/fs-snapshot/@jsonjoy.com/json-pack/@jsonjoy.com/base64": ["@jsonjoy.com/base64@17.67.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw=="], "@jsonjoy.com/fs-snapshot/@jsonjoy.com/json-pack/@jsonjoy.com/codegen": ["@jsonjoy.com/codegen@17.67.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q=="], @@ -3310,6 +3290,8 @@ "@jsonjoy.com/fs-snapshot/@jsonjoy.com/util/@jsonjoy.com/codegen": ["@jsonjoy.com/codegen@17.67.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q=="], + "accepts/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -3324,19 +3306,15 @@ "copy-webpack-plugin/globby/slash": ["slash@4.0.0", "", {}, "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew=="], - "css-loader/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "css-minimizer-webpack-plugin/jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], - "css-minimizer-webpack-plugin/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "css-select/domutils/dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="], "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], "express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - "file-loader/schema-utils/ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "file-loader/schema-utils/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], "file-loader/schema-utils/ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], @@ -3354,7 +3332,7 @@ "mdast-util-gfm-autolink-literal/micromark-util-character/micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], - "null-loader/schema-utils/ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "null-loader/schema-utils/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], "null-loader/schema-utils/ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], @@ -3364,28 +3342,28 @@ "renderkid/htmlparser2/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="], - "rtlcss/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - "serve-handler/mime-types/mime-db": ["mime-db@1.33.0", "", {}, "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="], - "serve-index/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "serve-index/http-errors/depd": ["depd@1.1.2", "", {}, "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ=="], "serve-index/http-errors/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="], + "serve-index/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "update-notifier/boxen/camelcase": ["camelcase@7.0.1", "", {}, "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw=="], "update-notifier/boxen/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], - "url-loader/schema-utils/ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "url-loader/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "url-loader/schema-utils/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], "url-loader/schema-utils/ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], - "webpack-dev-middleware/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], - "webpack-dev-server/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], "webpack-dev-server/open/define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="], -- 2.52.0 From 05a8ae9ae4ac3f5cdb4494d1e1c070d5d3e6b4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 8 Jun 2026 21:47:27 +0200 Subject: [PATCH 08/61] Docs --- packages/docs/docs/getting-started.md | 61 ++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 5 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index 0f3eecb..ef07f77 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -86,27 +86,41 @@ provider so route components can be converted with the same runtime context. ## Write Your First Component Use `Component.make` when you want automatic tracing spans, or -`Component.makeUntraced` when you only want the component behavior. +`Component.makeUntraced` when you only want the component behavior. This creates +an Effect-FC component, not a plain React component yet. -```tsx title="src/Hello.tsx" +```tsx title="src/HelloEffect.tsx" import { Effect } from "effect" import { Component } from "effect-fc" -import { runtime } from "./runtime" -const HelloEffect = Component.make("HelloEffect")(function* (props: { +export const HelloEffect = Component.make("HelloEffect")(function* (props: { readonly name: string }) { const message = yield* Effect.succeed(`Hello, ${props.name}`) return

{message}

}) +``` + +At this point `HelloEffect` can yield Effects, services, and scoped lifecycle +work, but React cannot render it directly. + +## Apply A Runtime + +Use `Component.withRuntime` at the boundary where an Effect-FC component needs +to become a regular React function component. + +```tsx title="src/Hello.tsx" +import { Component } from "effect-fc" +import { HelloEffect } from "./HelloEffect" +import { runtime } from "./runtime" export const Hello = HelloEffect.pipe( Component.withRuntime(runtime.context), ) ``` -`Hello` is now a regular React component: +`Hello` is now a normal React component: ```tsx title="src/App.tsx" import { Hello } from "./Hello" @@ -116,6 +130,43 @@ export function App() { } ``` +## Use Effect-FC Components Together + +Inside an Effect-FC component, other Effect-FC components are available through +their `.use` effect. Yield `.use` to get a React component for the current +runtime context, then render it like JSX. + +```tsx title="src/GreetingCardEffect.tsx" +import { Component } from "effect-fc" +import { HelloEffect } from "./HelloEffect" + +export const GreetingCardEffect = Component.make("GreetingCard")( + function* () { + const Hello = yield* HelloEffect.use + + return ( +
+ +

This component is still running inside Effect-FC.

+
+ ) + }, +) +``` + +Use `Component.withRuntime` only when you leave the Effect-FC tree and need a +normal React component again: + +```tsx title="src/GreetingCard.tsx" +import { Component } from "effect-fc" +import { GreetingCardEffect } from "./GreetingCardEffect" +import { runtime } from "./runtime" + +export const GreetingCard = GreetingCardEffect.pipe( + Component.withRuntime(runtime.context), +) +``` + ## Use Services Components can yield Effect services directly. Define services with Effect, -- 2.52.0 From d40ac326ec4ff2452af3818c4fdbf57cca58ea72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 8 Jun 2026 22:01:58 +0200 Subject: [PATCH 09/61] Docs --- packages/docs/docs/getting-started.md | 53 +++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index ef07f77..5076eb5 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -167,6 +167,59 @@ export const GreetingCard = GreetingCardEffect.pipe( ) ``` +## Component Lifecycle + +Every Effect-FC component instance exposes an Effect `Scope`. Effects that need +`Scope.Scope` can use that component scope to register finalizers, fork scoped +work, or acquire scoped resources. + +The component scope is created when React mounts the component and closes when +React unmounts it. When the scope closes, Effect runs the finalizers registered +inside that scope. + +```tsx title="src/MountedMessageEffect.tsx" +import { Console, Effect } from "effect" +import { Component } from "effect-fc" + +export const MountedMessageEffect = Component.make("MountedMessage")( + function* () { + yield* Component.useOnMount(() => + Effect.gen(function* () { + yield* Console.log("MountedMessage mounted") + yield* Effect.addFinalizer(() => + Console.log("MountedMessage unmounted"), + ) + }), + ) + + return

This component owns an Effect scope.

+ }, +) +``` + +Use `Component.useOnMount` for work that should run once for the component +instance. Use `Component.useOnChange` when the scoped work should be recreated +when dependencies change. + +```tsx +const UserPanelEffect = Component.make("UserPanel")( + function* (props: { readonly userId: string }) { + const user = yield* Component.useOnChange( + () => fetchUser(props.userId), + [props.userId], + ) + + return

{user.name}

+ }, +) +``` + +In this example, changing `userId` closes the previous dependency scope before +creating a new one. Unlike `useOnMount`, `useOnChange` does not expose the component's root scope directly. +It creates and provides its own scope for that dependency window. Some other Effect-FC hooks +follow the same pattern when they need a lifecycle that is narrower than the +whole component instance. + ## Use Services Components can yield Effect services directly. Define services with Effect, -- 2.52.0 From a8d4520fed1fb691efd29dd9bcc8c06b3cf33af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 8 Jun 2026 22:03:42 +0200 Subject: [PATCH 10/61] Docs --- packages/docs/docs/getting-started.md | 34 +++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index 5076eb5..554183c 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -215,10 +215,36 @@ const UserPanelEffect = Component.make("UserPanel")( ``` In this example, changing `userId` closes the previous dependency scope before -creating a new one. Unlike `useOnMount`, `useOnChange` does not expose the component's root scope directly. -It creates and provides its own scope for that dependency window. Some other Effect-FC hooks -follow the same pattern when they need a lifecycle that is narrower than the -whole component instance. +creating a new one. Unlike `useOnMount`, `useOnChange` does not expose the +component's root scope directly. It creates and provides its own scope for that +dependency window. Some other Effect-FC hooks follow the same pattern when they +need a lifecycle that is narrower than the whole component instance. + +## Use React Normally + +An Effect-FC component is still a React function component. Anything you can do +in a regular React component can also be done in an Effect-FC component, +including React hooks, refs, event handlers, context, and JSX composition. + +```tsx +import { Component } from "effect-fc" +import * as React from "react" + +const CounterEffect = Component.make("Counter")(function* () { + const [count, setCount] = React.useState(0) + const buttonRef = React.useRef(null) + + return ( + + ) +}) +``` + +Use regular React hooks for local UI concerns, and reach for Effect-FC helpers +when the component needs Effect services, scopes, resources, or Effect-powered +callbacks. ## Use Services -- 2.52.0 From c941e5970af24f2f3259aa41e9b5788aa21c9618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 8 Jun 2026 22:19:58 +0200 Subject: [PATCH 11/61] Docs --- packages/docs/docs/getting-started.md | 63 +++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index 554183c..cae6a2e 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -220,6 +220,69 @@ component's root scope directly. It creates and provides its own scope for that dependency window. Some other Effect-FC hooks follow the same pattern when they need a lifecycle that is narrower than the whole component instance. +## Useful Effect-FC Hooks + +The most common Effect-FC hooks are: + +- `Component.useOnMount`: run an Effect once for the component instance and + return its value. + +```tsx +const initialData = yield* Component.useOnMount(() => loadInitialData) +``` + +- `Component.useOnChange`: run an Effect again when dependencies change and + return its latest value. + +```tsx +const user = yield* Component.useOnChange(() => fetchUser(id), [id]) +``` + +- `Component.useReactEffect`: Effect-powered `React.useEffect` with scoped + finalizers. + +```tsx +yield* Component.useReactEffect(() => subscribe(id), [id]) +``` + +- `Component.useReactLayoutEffect`: Effect-powered `React.useLayoutEffect`. + +```tsx +yield* Component.useReactLayoutEffect(() => measure(ref), []) +``` + +- `Component.useRunSync` and `Component.useRunPromise`: run Effects from React + event handlers. + +```tsx +const runPromise = yield* Component.useRunPromise() + +return ( + +) +``` + +- `Component.useCallbackSync` and `Component.useCallbackPromise`: create stable + React callbacks. + +```tsx +const save = yield* Component.useCallbackPromise( + (user: User) => saveUser(user), + [], +) + +return +``` + +- `Component.useContextFromLayer`: create a React runtime context from an Effect + `Layer`. + +```tsx +yield* Component.useContextFromLayer(UserLive) +``` + ## Use React Normally An Effect-FC component is still a React function component. Anything you can do -- 2.52.0 From 8303c1f70e0bfe6174c8efda021f69eb43dd3bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 8 Jun 2026 22:23:49 +0200 Subject: [PATCH 12/61] Docs --- packages/docs/docs/getting-started.md | 28 ++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index cae6a2e..68c9d7f 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -183,29 +183,42 @@ import { Component } from "effect-fc" export const MountedMessageEffect = Component.make("MountedMessage")( function* () { - yield* Component.useOnMount(() => + const message = yield* Component.useOnMount(() => Effect.gen(function* () { yield* Console.log("MountedMessage mounted") yield* Effect.addFinalizer(() => Console.log("MountedMessage unmounted"), ) + + return "This value was loaded on mount." }), ) - return

This component owns an Effect scope.

+ return

{message}

}, ) ``` Use `Component.useOnMount` for work that should run once for the component -instance. Use `Component.useOnChange` when the scoped work should be recreated -when dependencies change. +instance and return a cached value. Use `Component.useOnChange` when the scoped +work should be recreated when dependencies change. ```tsx +import { Console, Effect } from "effect" +import { Component } from "effect-fc" + const UserPanelEffect = Component.make("UserPanel")( function* (props: { readonly userId: string }) { const user = yield* Component.useOnChange( - () => fetchUser(props.userId), + () => + Effect.gen(function* () { + yield* Console.log(`Loading ${props.userId}`) + yield* Effect.addFinalizer(() => + Console.log(`Cleaning up ${props.userId}`), + ) + + return yield* fetchUser(props.userId) + }), [props.userId], ) @@ -214,8 +227,9 @@ const UserPanelEffect = Component.make("UserPanel")( ) ``` -In this example, changing `userId` closes the previous dependency scope before -creating a new one. Unlike `useOnMount`, `useOnChange` does not expose the +In this example, each `userId` gets its own scope. When `userId` changes, +Effect-FC closes the previous scope, runs its finalizers, and creates a new +scope for the next load. Unlike `useOnMount`, `useOnChange` does not expose the component's root scope directly. It creates and provides its own scope for that dependency window. Some other Effect-FC hooks follow the same pattern when they need a lifecycle that is narrower than the whole component instance. -- 2.52.0 From 74a8e3a102898d97c504ed53e0714ebdb9ee4da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 10:42:42 +0200 Subject: [PATCH 13/61] Fix --- packages/docs/docs/getting-started.md | 58 ++++++++------------------- 1 file changed, 17 insertions(+), 41 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index 68c9d7f..574adb5 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -89,11 +89,11 @@ Use `Component.make` when you want automatic tracing spans, or `Component.makeUntraced` when you only want the component behavior. This creates an Effect-FC component, not a plain React component yet. -```tsx title="src/HelloEffect.tsx" +```tsx title="src/HelloView.tsx" import { Effect } from "effect" import { Component } from "effect-fc" -export const HelloEffect = Component.make("HelloEffect")(function* (props: { +export const HelloView = Component.make("HelloView")(function* (props: { readonly name: string }) { const message = yield* Effect.succeed(`Hello, ${props.name}`) @@ -102,7 +102,7 @@ export const HelloEffect = Component.make("HelloEffect")(function* (props: { }) ``` -At this point `HelloEffect` can yield Effects, services, and scoped lifecycle +At this point `HelloView` can yield Effects, services, and scoped lifecycle work, but React cannot render it directly. ## Apply A Runtime @@ -112,10 +112,10 @@ to become a regular React function component. ```tsx title="src/Hello.tsx" import { Component } from "effect-fc" -import { HelloEffect } from "./HelloEffect" +import { HelloView } from "./HelloView" import { runtime } from "./runtime" -export const Hello = HelloEffect.pipe( +export const Hello = HelloView.pipe( Component.withRuntime(runtime.context), ) ``` @@ -136,13 +136,13 @@ Inside an Effect-FC component, other Effect-FC components are available through their `.use` effect. Yield `.use` to get a React component for the current runtime context, then render it like JSX. -```tsx title="src/GreetingCardEffect.tsx" +```tsx title="src/GreetingCardView.tsx" import { Component } from "effect-fc" -import { HelloEffect } from "./HelloEffect" +import { HelloView } from "./HelloView" -export const GreetingCardEffect = Component.make("GreetingCard")( +export const GreetingCardView = Component.make("GreetingCard")( function* () { - const Hello = yield* HelloEffect.use + const Hello = yield* HelloView.use return (
@@ -159,10 +159,10 @@ normal React component again: ```tsx title="src/GreetingCard.tsx" import { Component } from "effect-fc" -import { GreetingCardEffect } from "./GreetingCardEffect" +import { GreetingCardView } from "./GreetingCardView" import { runtime } from "./runtime" -export const GreetingCard = GreetingCardEffect.pipe( +export const GreetingCard = GreetingCardView.pipe( Component.withRuntime(runtime.context), ) ``` @@ -177,11 +177,11 @@ The component scope is created when React mounts the component and closes when React unmounts it. When the scope closes, Effect runs the finalizers registered inside that scope. -```tsx title="src/MountedMessageEffect.tsx" +```tsx title="src/MountedMessageView.tsx" import { Console, Effect } from "effect" import { Component } from "effect-fc" -export const MountedMessageEffect = Component.make("MountedMessage")( +export const MountedMessageView = Component.make("MountedMessage")( function* () { const message = yield* Component.useOnMount(() => Effect.gen(function* () { @@ -207,7 +207,7 @@ work should be recreated when dependencies change. import { Console, Effect } from "effect" import { Component } from "effect-fc" -const UserPanelEffect = Component.make("UserPanel")( +const UserPanelView = Component.make("UserPanel")( function* (props: { readonly userId: string }) { const user = yield* Component.useOnChange( () => @@ -307,7 +307,7 @@ including React hooks, refs, event handlers, context, and JSX composition. import { Component } from "effect-fc" import * as React from "react" -const CounterEffect = Component.make("Counter")(function* () { +const CounterView = Component.make("Counter")(function* () { const [count, setCount] = React.useState(0) const buttonRef = React.useRef(null) @@ -362,7 +362,7 @@ import { Component } from "effect-fc" import { runtime } from "./runtime" import { GreetingService } from "./services" -const GreetingEffect = Component.make("Greeting")(function* (props: { +const GreetingView = Component.make("Greeting")(function* (props: { readonly name: string }) { const greeting = yield* GreetingService @@ -370,35 +370,11 @@ const GreetingEffect = Component.make("Greeting")(function* (props: { return

{greeting.greet(props.name)}

}) -export const Greeting = GreetingEffect.pipe( +export const Greeting = GreetingView.pipe( Component.withRuntime(runtime.context), ) ``` -## Mount And Cleanup Effects - -Use `Component.useOnMount` for scoped work that should start when the component -mounts and finalize when it unmounts. - -```tsx -import { Console, Effect } from "effect" -import { Component } from "effect-fc" - -const Mounted = Component.make("Mounted")(function* () { - yield* Component.useOnMount(() => - Effect.gen(function* () { - yield* Console.log("Mounted") - yield* Effect.addFinalizer(() => Console.log("Unmounted")) - }), - ) - - return

Open the console, then unmount me.

-}) -``` - -Finalizers are tied to the component scope, so this is the right place for -subscriptions, resources, and other lifecycle-bound Effects. - ## Where To Go Next Once the runtime and component boundary are in place, the rest of the library -- 2.52.0 From 88b3a1c98a3f291c62fba7f994a52b8dd97c9f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 10:48:46 +0200 Subject: [PATCH 14/61] Docs --- packages/docs/docs/getting-started.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index 574adb5..98b84d3 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -89,6 +89,11 @@ Use `Component.make` when you want automatic tracing spans, or `Component.makeUntraced` when you only want the component behavior. This creates an Effect-FC component, not a plain React component yet. +The Effect run during render must be synchronous. Effect-FC follows React's +render model, so component bodies should produce JSX without waiting on async +work. Use lifecycle hooks, callbacks, queries, or other Effect-FC helpers for +async work that happens outside render. + ```tsx title="src/HelloView.tsx" import { Effect } from "effect" import { Component } from "effect-fc" -- 2.52.0 From 0a59fdf2b40b77ce15e37c7d289ceb3bae3577eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 10:54:00 +0200 Subject: [PATCH 15/61] Docs --- packages/docs/docs/getting-started.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index 98b84d3..388ac9f 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -214,20 +214,20 @@ import { Component } from "effect-fc" const UserPanelView = Component.make("UserPanel")( function* (props: { readonly userId: string }) { - const user = yield* Component.useOnChange( + const label = yield* Component.useOnChange( () => Effect.gen(function* () { - yield* Console.log(`Loading ${props.userId}`) + yield* Console.log(`Preparing view for ${props.userId}`) yield* Effect.addFinalizer(() => Console.log(`Cleaning up ${props.userId}`), ) - return yield* fetchUser(props.userId) + return `Viewing user ${props.userId}` }), [props.userId], ) - return

{user.name}

+ return

{label}

}, ) ``` -- 2.52.0 From d3525aaad7b5b0033351d2ac86691078602579ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 11:09:47 +0200 Subject: [PATCH 16/61] Docs --- packages/docs/docs/getting-started.md | 28 ++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index 388ac9f..192fc1a 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -204,9 +204,14 @@ export const MountedMessageView = Component.make("MountedMessage")( ) ``` -Use `Component.useOnMount` for work that should run once for the component -instance and return a cached value. Use `Component.useOnChange` when the scoped -work should be recreated when dependencies change. +Use `Component.useOnMount` when the component needs a value produced by an +Effect during its first render. The value is then cached for the component +instance. + +Use `Component.useOnChange` when render needs the value computed by +scoped work that depends on changing inputs. When a dependency changes, React +re-renders the component and the hook computes the next value during that +render. ```tsx import { Console, Effect } from "effect" @@ -243,18 +248,22 @@ need a lifecycle that is narrower than the whole component instance. The most common Effect-FC hooks are: -- `Component.useOnMount`: run an Effect once for the component instance and - return its value. +Unlike plain React hooks, Effect-FC hooks return Effects. Use `yield*` to run +them inside the component body. + +- `Component.useOnMount`: run an Effect once during the component's first render + after mount, and return its value. The Effect must be synchronous. ```tsx const initialData = yield* Component.useOnMount(() => loadInitialData) ``` -- `Component.useOnChange`: run an Effect again when dependencies change and - return its latest value. +- `Component.useOnChange`: when a dependency changes, React re-renders the + component and the Effect is run again inside the component body. It returns + the latest value, so the Effect must be synchronous too. ```tsx -const user = yield* Component.useOnChange(() => fetchUser(id), [id]) +const label = yield* Component.useOnChange(() => formatUserLabel(id), [id]) ``` - `Component.useReactEffect`: Effect-powered `React.useEffect` with scoped @@ -264,7 +273,8 @@ const user = yield* Component.useOnChange(() => fetchUser(id), [id]) yield* Component.useReactEffect(() => subscribe(id), [id]) ``` -- `Component.useReactLayoutEffect`: Effect-powered `React.useLayoutEffect`. +- `Component.useReactLayoutEffect`: Effect-powered `React.useLayoutEffect` with scoped + finalizers. ```tsx yield* Component.useReactLayoutEffect(() => measure(ref), []) -- 2.52.0 From 91670779fe82152f791185b3702e4c70313ba4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 11:16:33 +0200 Subject: [PATCH 17/61] Docs --- packages/docs/docs/getting-started.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index 192fc1a..d2856f3 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -206,7 +206,8 @@ export const MountedMessageView = Component.make("MountedMessage")( Use `Component.useOnMount` when the component needs a value produced by an Effect during its first render. The value is then cached for the component -instance. +instance. You can also use it to set up scoped component logic, subscriptions, +or resources that should live for the lifetime of that component instance. Use `Component.useOnChange` when render needs the value computed by scoped work that depends on changing inputs. When a dependency changes, React -- 2.52.0 From 3000ff2d875634f621c24398e0921f812963f5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 11:18:08 +0200 Subject: [PATCH 18/61] Docs --- packages/docs/docs/getting-started.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index d2856f3..d2ab3f4 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -182,6 +182,10 @@ The component scope is created when React mounts the component and closes when React unmounts it. When the scope closes, Effect runs the finalizers registered inside that scope. +Finalizers are forked when the scope closes, so cleanup logic can run +asynchronous Effects even though the component body itself must stay +synchronous. + ```tsx title="src/MountedMessageView.tsx" import { Console, Effect } from "effect" import { Component } from "effect-fc" -- 2.52.0 From eb81ff16d2f4cad22e74241dd12916c99879f3f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 11:27:39 +0200 Subject: [PATCH 19/61] Docs --- packages/docs/docs/getting-started.md | 51 ++++++--------------------- 1 file changed, 11 insertions(+), 40 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index d2ab3f4..af28d4f 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -343,45 +343,13 @@ Use regular React hooks for local UI concerns, and reach for Effect-FC helpers when the component needs Effect services, scopes, resources, or Effect-powered callbacks. -## Use Services +## Use Tags -Components can yield Effect services directly. Define services with Effect, -provide them in your runtime layer, then consume them from the component body. - -```ts title="src/services.ts" -import { Effect } from "effect" - -export class GreetingService extends Effect.Service()( - "GreetingService", - { - succeed: { - greet: (name: string) => `Welcome, ${name}`, - }, - }, -) {} -``` - -Provide the service in your runtime: - -```tsx title="src/runtime.ts" -import { Layer } from "effect" -import { ReactRuntime } from "effect-fc" -import { GreetingService } from "./services" - -const AppLive = Layer.empty.pipe( - Layer.provideMerge(GreetingService.Default), -) - -export const runtime = ReactRuntime.make(AppLive) -``` - -Then read it inside a component: +Components can yield Effect tags directly in the component body. There is no +need to memoize the service yourself; just yield the tag wherever the component +needs it. ```tsx title="src/Greeting.tsx" -import { Component } from "effect-fc" -import { runtime } from "./runtime" -import { GreetingService } from "./services" - const GreetingView = Component.make("Greeting")(function* (props: { readonly name: string }) { @@ -389,12 +357,15 @@ const GreetingView = Component.make("Greeting")(function* (props: { return

{greeting.greet(props.name)}

}) - -export const Greeting = GreetingView.pipe( - Component.withRuntime(runtime.context), -) ``` +Service values in the runtime context are reactive by default. If a provided +service instance changes, Effect-FC recreates the React component function for +components that depend on that context, so the component reads the new service +and its scoped lifecycle can restart with the new environment. For services that +should not trigger that behavior, pass their tags with `Component.withOptions({ +nonReactiveTags: [...] })`. + ## Where To Go Next Once the runtime and component boundary are in place, the rest of the library -- 2.52.0 From 054f8773f07ffb925eec5e4cf67d8d9d6db7a3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 11:34:13 +0200 Subject: [PATCH 20/61] Docs --- packages/docs/docs/getting-started.md | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index af28d4f..be478f3 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -366,6 +366,35 @@ and its scoped lifecycle can restart with the new environment. For services that should not trigger that behavior, pass their tags with `Component.withOptions({ nonReactiveTags: [...] })`. +## Provide Services To A Subtree + +Use `Component.useContextFromLayer` when an Effect-FC component should provide +extra services to another Effect-FC component. It turns a `Layer` into a runtime +context that can be provided to `.use`. + +```tsx title="src/GreetingPageView.tsx" +import { Effect } from "effect" +import { Component } from "effect-fc" +import { GreetingView } from "./Greeting" +import { GreetingService } from "./services" + +const GreetingLive = GreetingService.Default({ + greet: (name: string) => `Welcome, ${name}`, +}) + +export const GreetingPageView = Component.make("GreetingPage")(function* () { + const context = yield* Component.useContextFromLayer(GreetingLive) + const Greeting = yield* Effect.provide(GreetingView.use, context) + + return +}) +``` + +The layer passed to `useContextFromLayer` should be stable. If a new layer value +is created on every render, Effect-FC has to build a new context, which can +cause unnecessary re-renders and scoped lifecycle restarts. Define static layers +outside the component, or memoize layers that depend on React props or state. + ## Where To Go Next Once the runtime and component boundary are in place, the rest of the library -- 2.52.0 From 86bdb5374eea7932591f5b871890967ba70b44d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 13:35:58 +0200 Subject: [PATCH 21/61] Docs --- packages/docs/docs/getting-started.md | 32 ++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index be478f3..ec691f4 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -271,11 +271,15 @@ const initialData = yield* Component.useOnMount(() => loadInitialData) const label = yield* Component.useOnChange(() => formatUserLabel(id), [id]) ``` -- `Component.useReactEffect`: Effect-powered `React.useEffect` with scoped - finalizers. +- `Component.useReactEffect`: Effect-powered `React.useEffect` for side effects + that do not need to compute render output or trigger a re-render. The Effect + must be synchronous and can register scoped finalizers. ```tsx -yield* Component.useReactEffect(() => subscribe(id), [id]) +yield* Component.useReactEffect( + () => Effect.forkScoped(subscribeToUser(id)), + [id], +) ``` - `Component.useReactLayoutEffect`: Effect-powered `React.useLayoutEffect` with scoped @@ -310,13 +314,6 @@ const save = yield* Component.useCallbackPromise( return ``` -- `Component.useContextFromLayer`: create a React runtime context from an Effect - `Layer`. - -```tsx -yield* Component.useContextFromLayer(UserLive) -``` - ## Use React Normally An Effect-FC component is still a React function component. Anything you can do @@ -360,11 +357,11 @@ const GreetingView = Component.make("Greeting")(function* (props: { ``` Service values in the runtime context are reactive by default. If a provided -service instance changes, Effect-FC recreates the React component function for -components that depend on that context, so the component reads the new service -and its scoped lifecycle can restart with the new environment. For services that -should not trigger that behavior, pass their tags with `Component.withOptions({ -nonReactiveTags: [...] })`. +service instance changes, Effect-FC unmounts and mounts again the components +that depend on that context, so they read the new service and restart their +scoped lifecycle with the new environment. For services that should not trigger +that behavior, pass their tags with `Component.withOptions({ nonReactiveTags: +[...] })`. ## Provide Services To A Subtree @@ -395,6 +392,11 @@ is created on every render, Effect-FC has to build a new context, which can cause unnecessary re-renders and scoped lifecycle restarts. Define static layers outside the component, or memoize layers that depend on React props or state. +Layers built with `useContextFromLayer` are scoped to the component that builds +them. That means service construction can register scoped logic, acquire +resources, fork scoped fibers, and add finalizers that are tied to that +component's lifecycle. + ## Where To Go Next Once the runtime and component boundary are in place, the rest of the library -- 2.52.0 From c492408969c819f3efcdccd96ba8b0c36d3e489e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 14:50:25 +0200 Subject: [PATCH 22/61] Docs --- packages/docs/docs/getting-started.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index ec691f4..be19515 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -10,26 +10,28 @@ component body you can yield services, run Effects, subscribe to Effect-powered state, and still export a normal React function component at the edge of your app. -This guide starts with the smallest useful setup: - -1. Install `effect-fc` with its peer dependencies. -2. Create a React runtime from an Effect `Layer`. -3. Wrap your React app with `ReactRuntime.Provider`. -4. Write a component with `Component.make`. -5. Convert it to a React component with `Component.withRuntime`. - ## Install Install `effect-fc` alongside `effect` and React 19.2 or newer: ```bash npm2yarn -npm install effect-fc effect react react-dom +npm install effect-fc effect react +``` +```bash npm2yarn +npm install --save-dev @types/react ``` -If your project uses TypeScript, also install React's type packages: +`effect-fc` is not opinionated about the React platform. Use it with web, +native, custom renderers, or any environment where React components can run. +Then install the platform-specific React packages for your target. + +For web apps, install React DOM: ```bash npm2yarn -npm install --save-dev @types/react @types/react-dom +npm install react-dom +``` +```bash npm2yarn +npm install --save-dev @types/react-dom ``` ## Create A Runtime -- 2.52.0 From fe65cd96aa99f6035c856eaa5467b34416e5dbed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 15:30:00 +0200 Subject: [PATCH 23/61] Docs --- packages/docs/docs/state-management.md | 114 +++++++++++++++++++++++++ packages/docs/sidebars.ts | 2 +- 2 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 packages/docs/docs/state-management.md diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md new file mode 100644 index 0000000..cd62f75 --- /dev/null +++ b/packages/docs/docs/state-management.md @@ -0,0 +1,114 @@ +--- +sidebar_position: 2 +title: State Management +--- + +# State Management + +`effect-fc` works well with state that lives in Effect services, layers, and +scopes. The usual pattern is: + +1. Create state with Effect primitives such as `SubscriptionRef`. +2. Expose read-only reactive state as a `Subscribable`. +3. Expose read/write reactive state as a `Lens`. +4. Bind values into components with `Subscribable.useAll`. + +`effect-fc` re-exports the `Lens` and `Subscribable` modules from +[`effect-lens`](https://github.com/Thiladev/effect-lens) for convenience. The +core data model and transformation APIs belong to `effect-lens`, so check the +`effect-lens` documentation for the full Lens/Subscribable API. + +## Subscribables + +A `Subscribable
` is reactive state with a current value and a stream of +changes. Use `Subscribable.useAll` whenever a component needs to bind +subscribable values into render output. + +`Lens` is a `Subscribable`, so this is also the default way to read Lens values +from a component. + +```tsx +import { Effect, SubscriptionRef } from "effect" +import { Component, Lens, Subscribable } from "effect-fc" + +class CounterState extends Effect.Service()("CounterState", { + effect: Effect.gen(function* () { + const count = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(0)) + const doubled = Subscribable.map(count, (n) => n * 2) + + return { count, doubled } as const + }), +}) {} + +const CounterReadOnlyView = Component.make("CounterReadOnly")( + function* () { + const state = yield* CounterState + const [doubled] = yield* Subscribable.useAll([state.doubled]) + + return

Doubled: {doubled}

+ }, +) +``` + +Use `Subscribable.useAll` instead of subscribing manually. It reads the current +values during render and uses scoped subscriptions to update React state when +changes arrive. + +## Lenses + +A `Lens
` is a `Subscribable` that can also be written to. If a component +only needs to display the value, keep using `Subscribable.useAll`. + +Use `Lens.useState` when React needs a read/write tuple, especially for inputs +that require synchronous updates such as controlled text inputs. + +```tsx +import { Effect, SubscriptionRef } from "effect" +import { Component, Lens } from "effect-fc" + +class FormState extends Effect.Service()("FormState", { + effect: Effect.gen(function* () { + const name = Lens.fromSubscriptionRef(yield* SubscriptionRef.make("")) + + return { name } as const + }), +}) {} + +const NameInputView = Component.make("NameInput")(function* () { + const state = yield* FormState + const [name, setName] = yield* Lens.useState(state.name) + + return ( + setName(event.currentTarget.value)} + /> + ) +}) +``` + +`Lens.useState` returns the current value and a React-compatible setter. Calling +the setter writes through the Lens, so every other component subscribed to the +same Lens sees the update. + +## Choosing One + +Use `Subscribable.useAll` when render needs to read values: + +```tsx +const [count, doubled] = yield* Subscribable.useAll([ + state.count, + state.doubled, +]) +``` + +Use `Lens.useState` when JSX needs both the current value and a synchronous +setter: + +```tsx +const [name, setName] = yield* Lens.useState(state.name) +``` + +For focusing into nested state, deriving lenses, custom write behavior, and the +complete API, refer to the +[`effect-lens` documentation](https://github.com/Thiladev/effect-lens). diff --git a/packages/docs/sidebars.ts b/packages/docs/sidebars.ts index 7efd336..e774757 100644 --- a/packages/docs/sidebars.ts +++ b/packages/docs/sidebars.ts @@ -3,7 +3,7 @@ import type { SidebarsConfig } from "@docusaurus/plugin-content-docs" // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const sidebars: SidebarsConfig = { - docsSidebar: ["getting-started"], + docsSidebar: ["getting-started", "state-management"], } export default sidebars -- 2.52.0 From a74ec6e398ad1a11abda92856e3d4148a523fe01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 18:09:47 +0200 Subject: [PATCH 24/61] Docs --- packages/docs/docs/state-management.md | 56 +++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index cd62f75..bcb0c49 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -18,6 +18,55 @@ scopes. The usual pattern is: core data model and transformation APIs belong to `effect-lens`, so check the `effect-lens` documentation for the full Lens/Subscribable API. +## Where To Store State + +State can live pretty much anywhere: in a service, in a layer, in a component +scope, or in plain React state. Pick the owner based on who needs the state. + +If state is shared by multiple components or belongs to application logic, store +it in an Effect service: + +```tsx +import { Effect, SubscriptionRef } from "effect" +import { Component, Lens, Subscribable } from "effect-fc" + +class CounterState extends Effect.Service()("CounterState", { + effect: Effect.gen(function* () { + const count = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(0)) + + return { count } as const + }), +}) {} + +const CounterValueView = Component.make("CounterValue")(function* () { + const state = yield* CounterState + const [count] = yield* Subscribable.useAll([state.count]) + + return

Count: {count}

+}) +``` + +If state belongs to a single Effect-FC component instance but still benefits +from Lens/Subscribable APIs, create it with `Component.useOnMount`: + +```tsx +import { Effect, SubscriptionRef } from "effect" +import { Component, Lens, Subscribable } from "effect-fc" + +const LocalCounterView = Component.make("LocalCounter")(function* () { + const countLens = yield* Component.useOnMount(() => + Effect.map(SubscriptionRef.make(0), Lens.fromSubscriptionRef), + ) + const [count] = yield* Subscribable.useAll([countLens]) + + return

Count: {count}

+}) +``` + +For simple UI state that is not shared and does not need Effect integration, +prefer regular React state. A local "show details" toggle is usually better as +`React.useState(false)` than as a Lens. + ## Subscribables A `Subscribable
` is reactive state with a current value and a stream of @@ -43,9 +92,12 @@ class CounterState extends Effect.Service()("CounterState", { const CounterReadOnlyView = Component.make("CounterReadOnly")( function* () { const state = yield* CounterState - const [doubled] = yield* Subscribable.useAll([state.doubled]) + const [count, doubled] = yield* Subscribable.useAll([ + state.count, + state.doubled, + ]) - return

Doubled: {doubled}

+ return

Count: {count}, doubled: {doubled}

}, ) ``` -- 2.52.0 From 5791c08b51f51695dcf13c6c53b1f4be2cd540a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 19:00:09 +0200 Subject: [PATCH 25/61] Docs --- packages/docs/docs/state-management.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index bcb0c49..1806b47 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -9,9 +9,11 @@ title: State Management scopes. The usual pattern is: 1. Create state with Effect primitives such as `SubscriptionRef`. -2. Expose read-only reactive state as a `Subscribable`. -3. Expose read/write reactive state as a `Lens`. -4. Bind values into components with `Subscribable.useAll`. +2. Turn the Effect primitive into a `Lens` with the matching constructor, such + as `Lens.fromSubscriptionRef`. +3. Expose read-only reactive state as a `Subscribable`. +4. Expose read/write reactive state as a `Lens`. +5. Bind values into components with `Subscribable.useAll`. `effect-fc` re-exports the `Lens` and `Subscribable` modules from [`effect-lens`](https://github.com/Thiladev/effect-lens) for convenience. The @@ -102,9 +104,7 @@ const CounterReadOnlyView = Component.make("CounterReadOnly")( ) ``` -Use `Subscribable.useAll` instead of subscribing manually. It reads the current -values during render and uses scoped subscriptions to update React state when -changes arrive. +`Subscribable.useAll` reads the current values during render and uses scoped subscriptions to update React state when changes arrive. ## Lenses -- 2.52.0 From 436dc275b3fb60167200a7a930d9deaf762ce813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 20:34:24 +0200 Subject: [PATCH 26/61] Docs --- packages/docs/docs/state-management.md | 31 +++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index 1806b47..8fa58ea 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -69,7 +69,7 @@ For simple UI state that is not shared and does not need Effect integration, prefer regular React state. A local "show details" toggle is usually better as `React.useState(false)` than as a Lens. -## Subscribables +## Subscribable.useAll A `Subscribable
` is reactive state with a current value and a stream of changes. Use `Subscribable.useAll` whenever a component needs to bind @@ -106,6 +106,35 @@ const CounterReadOnlyView = Component.make("CounterReadOnly")( `Subscribable.useAll` reads the current values during render and uses scoped subscriptions to update React state when changes arrive. +When the state is a `Lens`, keep binding it with `Subscribable.useAll` and +write to it with `Lens.set` or `Lens.update` from an Effect-FC callback: + +```tsx +const CounterControlsView = Component.make("CounterControls")( + function* () { + const state = yield* CounterState + const [count] = yield* Subscribable.useAll([state.count]) + + const increment = yield* Component.useCallbackSync( + () => Lens.update(state.count, (n) => n + 1), + [state.count], + ) + const reset = yield* Component.useCallbackSync( + () => Lens.set(state.count, 0), + [state.count], + ) + + return ( +
+

Count: {count}

+ + +
+ ) + }, +) +``` + ## Lenses A `Lens
` is a `Subscribable` that can also be written to. If a component -- 2.52.0 From c90c5f9532b87e5d50fae35564207356a3f3a8c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 21:44:08 +0200 Subject: [PATCH 27/61] Docs --- packages/docs/docs/state-management.md | 35 ++++++++------------------ 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index 8fa58ea..2bc1280 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -106,8 +106,8 @@ const CounterReadOnlyView = Component.make("CounterReadOnly")( `Subscribable.useAll` reads the current values during render and uses scoped subscriptions to update React state when changes arrive. -When the state is a `Lens`, keep binding it with `Subscribable.useAll` and -write to it with `Lens.set` or `Lens.update` from an Effect-FC callback: +When you need to modify state, write to the Lens with `Lens.set` or +`Lens.update` from an Effect-FC callback: ```tsx const CounterControlsView = Component.make("CounterControls")( @@ -135,13 +135,16 @@ const CounterControlsView = Component.make("CounterControls")( ) ``` -## Lenses +## Lens.useState -A `Lens` is a `Subscribable` that can also be written to. If a component -only needs to display the value, keep using `Subscribable.useAll`. +`Lens.useState` is useful when React needs the familiar `[value, setValue]` +tuple, backed by a Lens. Reach for it when the JSX API expects a synchronous +setter, especially controlled inputs such as text fields, checkboxes, selects, +or third-party components with `value` / `onChange` props. -Use `Lens.useState` when React needs a read/write tuple, especially for inputs -that require synchronous updates such as controlled text inputs. +If a component only needs to display the value, prefer `Subscribable.useAll`. +`Lens.useState` is for places where reading and writing need to be wired +together in React's local-state shape. ```tsx import { Effect, SubscriptionRef } from "effect" @@ -172,24 +175,6 @@ const NameInputView = Component.make("NameInput")(function* () { the setter writes through the Lens, so every other component subscribed to the same Lens sees the update. -## Choosing One - -Use `Subscribable.useAll` when render needs to read values: - -```tsx -const [count, doubled] = yield* Subscribable.useAll([ - state.count, - state.doubled, -]) -``` - -Use `Lens.useState` when JSX needs both the current value and a synchronous -setter: - -```tsx -const [name, setName] = yield* Lens.useState(state.name) -``` - For focusing into nested state, deriving lenses, custom write behavior, and the complete API, refer to the [`effect-lens` documentation](https://github.com/Thiladev/effect-lens). -- 2.52.0 From 81fb1dcf4239874b912c56391d0388f1b59006ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 21:59:12 +0200 Subject: [PATCH 28/61] Docs --- packages/docs/docs/state-management.md | 55 ++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index 2bc1280..72f0f7c 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -175,6 +175,61 @@ const NameInputView = Component.make("NameInput")(function* () { the setter writes through the Lens, so every other component subscribed to the same Lens sees the update. +## Focused Lenses + +Use focused Lenses when a component should work with one part of a larger state +object. A focused Lens is still a Lens, so it can be read with +`Subscribable.useAll` or used with `Lens.useState` when React needs a +read/write tuple. + +```tsx +import { Effect, SubscriptionRef } from "effect" +import { Component, Lens, Subscribable } from "effect-fc" + +interface UserProfile { + readonly name: string + readonly email: string + readonly role: string +} + +class ProfileState extends Effect.Service()("ProfileState", { + effect: Effect.gen(function* () { + const profile = Lens.fromSubscriptionRef( + yield* SubscriptionRef.make({ + name: "", + email: "", + role: "reader", + }), + ) + const name = Lens.focusObjectOn(profile, "name") + const role = Lens.focusObjectOn(profile, "role") + + return { profile, name, role } as const + }), +}) {} + +const ProfileNameView = Component.make("ProfileName")(function* () { + const state = yield* ProfileState + const [name, setName] = yield* Lens.useState(state.name) + const [role] = yield* Subscribable.useAll([state.role]) + + return ( + + ) +}) +``` + +Updating the focused `name` Lens through `Lens.useState` updates the parent +`profile` Lens. The focused `role` Lens is only read, so it stays on the simpler +`Subscribable.useAll` path. + For focusing into nested state, deriving lenses, custom write behavior, and the complete API, refer to the [`effect-lens` documentation](https://github.com/Thiladev/effect-lens). -- 2.52.0 From ad1ef4a73b4fb3d545d9ee80433e77e342306f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 22:15:41 +0200 Subject: [PATCH 29/61] Docs --- packages/docs/docs/state-management.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index 72f0f7c..c1f685e 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -22,8 +22,10 @@ core data model and transformation APIs belong to `effect-lens`, so check the ## Where To Store State -State can live pretty much anywhere: in a service, in a layer, in a component -scope, or in plain React state. Pick the owner based on who needs the state. +State can live pretty much anywhere as a `Lens` or `Subscribable`: in a +service, in a layer, in a component scope, or alongside plain React state. Pick +the owner based on who needs the state. Once you have a Lens/Subscribable +handle, pass it around however you like, including through React props. If state is shared by multiple components or belongs to application logic, store it in an Effect service: @@ -56,10 +58,14 @@ import { Effect, SubscriptionRef } from "effect" import { Component, Lens, Subscribable } from "effect-fc" const LocalCounterView = Component.make("LocalCounter")(function* () { - const countLens = yield* Component.useOnMount(() => - Effect.map(SubscriptionRef.make(0), Lens.fromSubscriptionRef), + const state = yield* Component.useOnMount(() => + Effect.gen(function* () { + const count = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(0)) + + return { count } as const + }), ) - const [count] = yield* Subscribable.useAll([countLens]) + const [count] = yield* Subscribable.useAll([state.count]) return

Count: {count}

}) -- 2.52.0 From 1cead4bb7bfd1cba0aab150408ca03d00b4a3c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 22:21:26 +0200 Subject: [PATCH 30/61] Docs --- packages/docs/docs/state-management.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index c1f685e..8e2a84c 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -50,8 +50,9 @@ const CounterValueView = Component.make("CounterValue")(function* () { }) ``` -If state belongs to a single Effect-FC component instance but still benefits -from Lens/Subscribable APIs, create it with `Component.useOnMount`: +If state belongs to a single Effect-FC component instance, or to a shallow +hierarchy of subcomponents that receive it through props, create it with +`Component.useOnMount`: ```tsx import { Effect, SubscriptionRef } from "effect" -- 2.52.0 From 9fb56da120ec4ce018fedc48564702e3d8f99fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 9 Jun 2026 22:25:53 +0200 Subject: [PATCH 31/61] Docs --- packages/docs/docs/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/docs/docs/getting-started.md b/packages/docs/docs/getting-started.md index be19515..2c4141c 100644 --- a/packages/docs/docs/getting-started.md +++ b/packages/docs/docs/getting-started.md @@ -253,11 +253,11 @@ need a lifecycle that is narrower than the whole component instance. ## Useful Effect-FC Hooks -The most common Effect-FC hooks are: - Unlike plain React hooks, Effect-FC hooks return Effects. Use `yield*` to run them inside the component body. +The most common Effect-FC hooks are: + - `Component.useOnMount`: run an Effect once during the component's first render after mount, and return its value. The Effect must be synchronous. -- 2.52.0 From 7ae5d085553424503844e78eef113ea9e4fb365e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 11 Jun 2026 12:29:10 +0200 Subject: [PATCH 32/61] Docs --- packages/docs/docs/state-management.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index 8e2a84c..dde9485 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -18,7 +18,7 @@ scopes. The usual pattern is: `effect-fc` re-exports the `Lens` and `Subscribable` modules from [`effect-lens`](https://github.com/Thiladev/effect-lens) for convenience. The core data model and transformation APIs belong to `effect-lens`, so check the -`effect-lens` documentation for the full Lens/Subscribable API. +[`effect-lens` documentation](https://github.com/Thiladev/effect-lens/tree/master/packages/effect-lens) for the full Lens/Subscribable API. ## Where To Store State @@ -124,11 +124,11 @@ const CounterControlsView = Component.make("CounterControls")( const increment = yield* Component.useCallbackSync( () => Lens.update(state.count, (n) => n + 1), - [state.count], + [], ) const reset = yield* Component.useCallbackSync( () => Lens.set(state.count, 0), - [state.count], + [], ) return ( @@ -239,4 +239,4 @@ Updating the focused `name` Lens through `Lens.useState` updates the parent For focusing into nested state, deriving lenses, custom write behavior, and the complete API, refer to the -[`effect-lens` documentation](https://github.com/Thiladev/effect-lens). +[`effect-lens` documentation](https://github.com/Thiladev/effect-lens/tree/master/packages/effect-lens). -- 2.52.0 From cf2cb8bf09375a1d51ca8610ca023cf3244f6729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 11 Jun 2026 14:25:00 +0200 Subject: [PATCH 33/61] Docs --- packages/docs/docs/state-management.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index dde9485..618a08b 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -5,15 +5,20 @@ title: State Management # State Management -`effect-fc` works well with state that lives in Effect services, layers, and -scopes. The usual pattern is: +`Lens` is the main type used for state management in `effect-fc`. -1. Create state with Effect primitives such as `SubscriptionRef`. -2. Turn the Effect primitive into a `Lens` with the matching constructor, such - as `Lens.fromSubscriptionRef`. -3. Expose read-only reactive state as a `Subscribable`. -4. Expose read/write reactive state as a `Lens`. -5. Bind values into components with `Subscribable.useAll`. +A Lens is an effectful handle to a piece of state. It can read the current value, +subscribe to changes, and write updates back to the underlying source. A Lens +can point at a whole state object or focus on one nested field inside it. + +The usual pattern is to create state with Effect primitives such as +`SubscriptionRef`, turn that primitive into a Lens with a matching constructor +such as `Lens.fromSubscriptionRef`, and bind Lens values into components with +`Subscribable.useAll`. + +`Subscribable` is the read-only side of this model. Every Lens is also a +Subscribable, so use `Subscribable.useAll` whenever a component only needs to +read reactive state. `effect-fc` re-exports the `Lens` and `Subscribable` modules from [`effect-lens`](https://github.com/Thiladev/effect-lens) for convenience. The @@ -113,8 +118,7 @@ const CounterReadOnlyView = Component.make("CounterReadOnly")( `Subscribable.useAll` reads the current values during render and uses scoped subscriptions to update React state when changes arrive. -When you need to modify state, write to the Lens with `Lens.set` or -`Lens.update` from an Effect-FC callback: +When you need to modify state, write to the Lens with `Lens.set` or `Lens.update`: ```tsx const CounterControlsView = Component.make("CounterControls")( -- 2.52.0 From 241d489b0c4b53bce7e7105a7308376955049710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 12 Jun 2026 01:44:40 +0200 Subject: [PATCH 34/61] Docs --- packages/docs/docs/state-management.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/docs/docs/state-management.md b/packages/docs/docs/state-management.md index 618a08b..160bf96 100644 --- a/packages/docs/docs/state-management.md +++ b/packages/docs/docs/state-management.md @@ -17,8 +17,7 @@ such as `Lens.fromSubscriptionRef`, and bind Lens values into components with `Subscribable.useAll`. `Subscribable` is the read-only side of this model. Every Lens is also a -Subscribable, so use `Subscribable.useAll` whenever a component only needs to -read reactive state. +Subscribable. `effect-fc` re-exports the `Lens` and `Subscribable` modules from [`effect-lens`](https://github.com/Thiladev/effect-lens) for convenience. The -- 2.52.0 From 257d505fdfb5a4b9f6f289e171989fa1abccdfcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 12 Jun 2026 01:51:30 +0200 Subject: [PATCH 35/61] Docs --- packages/docs/docs/forms.md | 153 ++++++++++++++++++++++++++++++++++++ packages/docs/sidebars.ts | 2 +- 2 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 packages/docs/docs/forms.md diff --git a/packages/docs/docs/forms.md b/packages/docs/docs/forms.md new file mode 100644 index 0000000..37eca25 --- /dev/null +++ b/packages/docs/docs/forms.md @@ -0,0 +1,153 @@ +--- +sidebar_position: 3 +title: Forms +--- + +# Forms + +The `Form` module is the low-level field model used by Effect-FC forms. A form +field is built on the same state model as the rest of Effect-FC: + +- `encodedValue`: a `Lens` containing the raw value used by the input. +- `value`: a `Subscribable` containing the decoded value as an `Option`. +- `issues`: a `Subscribable` containing schema validation issues for that field. +- `canCommit`, `isValidating`, and `isCommitting`: `Subscribable` flags for UI + state. + +Most apps create a root form with `SubmittableForm` or `SynchronizedForm`, then +focus it into fields with `Form.focusObjectOn`, `Form.focusArrayAt`, or the +other focusing helpers. + +## Field Inputs + +Use `Form.useInput` to connect a `Form` field to a controlled input. It returns +a React-style `{ value, setValue }` pair and writes changes back to the field's +`encodedValue` Lens. + +```tsx +import { Component, Form, Subscribable } from "effect-fc" + +const TextInputView = Component.make("TextInput")( + function* (props: { + readonly form: Form.Form + readonly label: string + }) { + const input = yield* Form.useInput(props.form, { + debounce: "250 millis", + }) + const [issues] = yield* Subscribable.useAll([props.form.issues]) + + return ( + + ) + }, +) +``` + +Use `Form.useOptionalInput` for `Option` fields. It returns the same value/setter +pair plus `enabled` and `setEnabled`, which is useful for optional inputs that +can be toggled on and off. + +## Submittable Forms + +Use `SubmittableForm` when the user edits local encoded form state, validates it +with a schema, and then submits a decoded value. + +```tsx +import { Effect, Schema } from "effect" +import { Component, Form, SubmittableForm, Subscribable } from "effect-fc" +import { TextInputView } from "./TextInputView" + +const RegisterSchema = Schema.Struct({ + email: Schema.String, + password: Schema.String, +}) + +class RegisterFormState extends Effect.Service()( + "RegisterFormState", + { + scoped: Effect.gen(function* () { + const form = yield* SubmittableForm.service({ + schema: RegisterSchema, + initialEncodedValue: { + email: "", + password: "", + }, + f: ([value]) => + Effect.log(`Registering ${value.email}`), + }) + + return { + form, + email: Form.focusObjectOn(form, "email"), + password: Form.focusObjectOn(form, "password"), + } as const + }), + }, +) {} + +const RegisterFormView = Component.make("RegisterForm")( + function* () { + const state = yield* RegisterFormState + const [canCommit, isCommitting] = yield* Subscribable.useAll([ + state.form.canCommit, + state.form.isCommitting, + ]) + const runPromise = yield* Component.useRunPromise() + const TextInput = yield* TextInputView.use + + return ( +
{ + event.preventDefault() + void runPromise(state.form.submit) + }} + > + + + + + ) + }, +) +``` + +`SubmittableForm.service` starts validation in the form's scope. The form keeps +its encoded input state, decoded value, validation issues, submit mutation, and +commit flags available as Lenses/Subscribables. + +## Synchronized Forms + +Use `SynchronizedForm` when a form should edit an existing target `Lens`. +Instead of submitting a final value, valid encoded changes are synchronized back +to the target Lens. + +This is useful for edit screens where the form is a validated view over existing +state. Use `SubmittableForm` for "submit this draft" flows, and +`SynchronizedForm` for "keep this target state synchronized when valid" flows. + +## Focusing Fields + +Forms can be focused just like Lenses: + +```tsx +const emailField = Form.focusObjectOn(form, "email") +const firstItemField = Form.focusArrayAt(form, 0) +``` + +Focused fields keep the parent form's validation and commit state, but narrow +`encodedValue`, `value`, and `issues` to the field path. This lets each input +component receive only the field it needs. diff --git a/packages/docs/sidebars.ts b/packages/docs/sidebars.ts index e774757..58f6b8a 100644 --- a/packages/docs/sidebars.ts +++ b/packages/docs/sidebars.ts @@ -3,7 +3,7 @@ import type { SidebarsConfig } from "@docusaurus/plugin-content-docs" // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const sidebars: SidebarsConfig = { - docsSidebar: ["getting-started", "state-management"], + docsSidebar: ["getting-started", "state-management", "forms"], } export default sidebars -- 2.52.0 From b7ea35006db8232458f0133dcba92b8153c04e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 22 Jun 2026 01:38:06 +0200 Subject: [PATCH 36/61] Add forms doc --- packages/docs/docs/forms.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/docs/docs/forms.md b/packages/docs/docs/forms.md index 37eca25..944234f 100644 --- a/packages/docs/docs/forms.md +++ b/packages/docs/docs/forms.md @@ -5,18 +5,33 @@ title: Forms # Forms -The `Form` module is the low-level field model used by Effect-FC forms. A form -field is built on the same state model as the rest of Effect-FC: +The form modules provide an Effect-first model for editable, schema-validated +state. They are not a visual component library. Instead, they give you +Lenses/Subscribables for form values, validation issues, and commit state, so +you can build the UI with whatever components your app already uses. -- `encodedValue`: a `Lens` containing the raw value used by the input. +The base `Form` type represents a field. A field tracks both the raw encoded +value used by inputs and the decoded value produced by an Effect `Schema`: + +- `encodedValue`: a `Lens` containing the raw input value. - `value`: a `Subscribable` containing the decoded value as an `Option`. - `issues`: a `Subscribable` containing schema validation issues for that field. - `canCommit`, `isValidating`, and `isCommitting`: `Subscribable` flags for UI state. -Most apps create a root form with `SubmittableForm` or `SynchronizedForm`, then -focus it into fields with `Form.focusObjectOn`, `Form.focusArrayAt`, or the -other focusing helpers. +There are two root form flavors: + +- `SubmittableForm`: owns local encoded form state, validates it, and submits a + decoded value through a mutation. +- `SynchronizedForm`: wraps an existing target `Lens` and writes valid changes + back to that target. + +Most apps create one of those root forms, then focus it into fields with +`Form.focusObjectOn`, `Form.focusArrayAt`, or the other focusing helpers. + +The core form model is Effect code and can technically be used outside +Effect-FC. Effect-FC adds the React-facing hooks, such as `Form.useInput`, that +make those forms convenient to bind to components. ## Field Inputs -- 2.52.0 From 091e102b2321be2802531529fced921fea7b4a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 22 Jun 2026 02:04:20 +0200 Subject: [PATCH 37/61] Add Effect v4 version --- bun.lock | 70 +++- packages/effect-fc-next/README.md | 56 +++ packages/effect-fc-next/biome.json | 8 + packages/effect-fc-next/package.json | 54 +++ packages/effect-fc-next/src/Async.ts | 171 ++++++++ packages/effect-fc-next/src/Component.ts | 385 ++++++++++++++++++ packages/effect-fc-next/src/ErrorObserver.ts | 47 +++ packages/effect-fc-next/src/Form.ts | 279 +++++++++++++ packages/effect-fc-next/src/Lens.ts | 62 +++ packages/effect-fc-next/src/Memoized.ts | 112 +++++ packages/effect-fc-next/src/Mutation.ts | 146 +++++++ packages/effect-fc-next/src/PubSub.ts | 17 + packages/effect-fc-next/src/Query.ts | 283 +++++++++++++ packages/effect-fc-next/src/QueryClient.ts | 191 +++++++++ packages/effect-fc-next/src/ReactRuntime.ts | 71 ++++ packages/effect-fc-next/src/Result.ts | 249 +++++++++++ packages/effect-fc-next/src/SetStateAction.ts | 12 + packages/effect-fc-next/src/Stream.ts | 33 ++ .../effect-fc-next/src/SubmittableForm.ts | 212 ++++++++++ packages/effect-fc-next/src/Subscribable.ts | 53 +++ .../effect-fc-next/src/SynchronizedForm.ts | 204 ++++++++++ packages/effect-fc-next/src/index.ts | 17 + packages/effect-fc-next/src/utils.ts | 3 + .../effect-fc-next/test/Component.test.tsx | 354 ++++++++++++++++ packages/effect-fc-next/test/Lens.test.tsx | 165 ++++++++ packages/effect-fc-next/test/Query.test.ts | 169 ++++++++ .../effect-fc-next/test/Subscribable.test.tsx | 129 ++++++ packages/effect-fc-next/tsconfig.json | 40 ++ packages/effect-fc-next/vitest.config.ts | 9 + packages/example-next/.gitignore | 26 ++ packages/example-next/README.md | 10 + packages/example-next/biome.json | 8 + packages/example-next/index.html | 13 + packages/example-next/package.json | 34 ++ packages/example-next/src/index.css | 28 ++ packages/example-next/src/main.tsx | 40 ++ packages/example-next/src/vite-env.d.ts | 1 + packages/example-next/tsconfig.app.json | 31 ++ packages/example-next/tsconfig.json | 7 + packages/example-next/tsconfig.node.json | 25 ++ packages/example-next/vite.config.ts | 10 + 41 files changed, 3832 insertions(+), 2 deletions(-) create mode 100644 packages/effect-fc-next/README.md create mode 100644 packages/effect-fc-next/biome.json create mode 100644 packages/effect-fc-next/package.json create mode 100644 packages/effect-fc-next/src/Async.ts create mode 100644 packages/effect-fc-next/src/Component.ts create mode 100644 packages/effect-fc-next/src/ErrorObserver.ts create mode 100644 packages/effect-fc-next/src/Form.ts create mode 100644 packages/effect-fc-next/src/Lens.ts create mode 100644 packages/effect-fc-next/src/Memoized.ts create mode 100644 packages/effect-fc-next/src/Mutation.ts create mode 100644 packages/effect-fc-next/src/PubSub.ts create mode 100644 packages/effect-fc-next/src/Query.ts create mode 100644 packages/effect-fc-next/src/QueryClient.ts create mode 100644 packages/effect-fc-next/src/ReactRuntime.ts create mode 100644 packages/effect-fc-next/src/Result.ts create mode 100644 packages/effect-fc-next/src/SetStateAction.ts create mode 100644 packages/effect-fc-next/src/Stream.ts create mode 100644 packages/effect-fc-next/src/SubmittableForm.ts create mode 100644 packages/effect-fc-next/src/Subscribable.ts create mode 100644 packages/effect-fc-next/src/SynchronizedForm.ts create mode 100644 packages/effect-fc-next/src/index.ts create mode 100644 packages/effect-fc-next/src/utils.ts create mode 100644 packages/effect-fc-next/test/Component.test.tsx create mode 100644 packages/effect-fc-next/test/Lens.test.tsx create mode 100644 packages/effect-fc-next/test/Query.test.ts create mode 100644 packages/effect-fc-next/test/Subscribable.test.tsx create mode 100644 packages/effect-fc-next/tsconfig.json create mode 100644 packages/effect-fc-next/vitest.config.ts create mode 100644 packages/example-next/.gitignore create mode 100644 packages/example-next/README.md create mode 100644 packages/example-next/biome.json create mode 100644 packages/example-next/index.html create mode 100644 packages/example-next/package.json create mode 100644 packages/example-next/src/index.css create mode 100644 packages/example-next/src/main.tsx create mode 100644 packages/example-next/src/vite-env.d.ts create mode 100644 packages/example-next/tsconfig.app.json create mode 100644 packages/example-next/tsconfig.json create mode 100644 packages/example-next/tsconfig.node.json create mode 100644 packages/example-next/vite.config.ts diff --git a/bun.lock b/bun.lock index a30a084..cf8ffc5 100644 --- a/bun.lock +++ b/bun.lock @@ -54,6 +54,23 @@ "react": "^19.2.0", }, }, + "packages/effect-fc-next": { + "name": "effect-fc-next", + "version": "0.1.0-beta.0", + "dependencies": { + "effect-lens": "2.0.0-beta.0", + }, + "devDependencies": { + "@testing-library/react": "^16.3.0", + "jsdom": "^26.1.0", + "vitest": "^3.2.4", + }, + "peerDependencies": { + "@types/react": "^19.2.0", + "effect": "4.0.0-beta.85", + "react": "^19.2.0", + }, + }, "packages/example": { "name": "@effect-fc/example", "version": "0.0.0", @@ -80,6 +97,23 @@ "vite": "^8.0.16", }, }, + "packages/example-next": { + "name": "@effect-fc/example-next", + "version": "0.0.0", + "dependencies": { + "effect": "4.0.0-beta.85", + "effect-fc-next": "workspace:*", + }, + "devDependencies": { + "@types/react": "^19.2.15", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.2", + "globals": "^17.6.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", + "vite": "^8.0.16", + }, + }, }, "packages": { "@algolia/abtesting": ["@algolia/abtesting@1.19.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-Lhnez3hhXHk25lfxLAMxvkP4fmN3+1RgADhD2ssMDBYuAsDVReeyP+3SGRx+ntq8ijMrLqUyfvO72TB6jsTteQ=="], @@ -512,6 +546,8 @@ "@effect-fc/example": ["@effect-fc/example@workspace:packages/example"], + "@effect-fc/example-next": ["@effect-fc/example-next@workspace:packages/example-next"], + "@effect/language-service": ["@effect/language-service@0.86.2", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-SaPln+8srOqDJDUwNTDmP5e+IYpEDr9+1epGznnsLqu8xvo6VnxyWARdeLpqvZJlb0Pgy9ca7ppqvvdWbHPXAg=="], "@effect/platform": ["@effect/platform@0.96.1", "", { "dependencies": { "find-my-way-ts": "^0.1.6", "msgpackr": "^1.11.10", "multipasta": "^0.2.7" }, "peerDependencies": { "effect": "^3.21.2" } }, "sha512-cjB1QZZYEP8JXCFNGvBLVi0T6YUBQTmOVEUA3SDbiQ6RUO+p6CE3eyD2vMWmrz5nE8yY5QSAuOV9v0boEcUv+A=="], @@ -1574,6 +1610,8 @@ "effect-fc": ["effect-fc@workspace:packages/effect-fc"], + "effect-fc-next": ["effect-fc-next@workspace:packages/effect-fc-next"], + "effect-lens": ["effect-lens@0.2.0", "", { "peerDependencies": { "effect": "^3.21.0" } }, "sha512-Cfyps811WQVSxnbxm6xqJldL08YXUU1jAzWtdKXSKWZfF6LAEqm1l8swnw4ltVky1TSfi2vvS+I/tFPqwObrMg=="], "electron-to-chromium": ["electron-to-chromium@1.5.368", "", {}, "sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw=="], @@ -1844,7 +1882,7 @@ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], - "ini": ["ini@2.0.0", "", {}, "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA=="], + "ini": ["ini@7.0.0", "", {}, "sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w=="], "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], @@ -1948,6 +1986,8 @@ "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], + "kubernetes-types": ["kubernetes-types@1.30.0", "", {}, "sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q=="], + "latest-version": ["latest-version@7.0.0", "", { "dependencies": { "package-json": "^8.1.0" } }, "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg=="], "launch-editor": ["launch-editor@2.14.1", "", { "dependencies": { "picocolors": "^1.1.1", "shell-quote": "^1.8.4" } }, "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA=="], @@ -2758,6 +2798,8 @@ "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + "toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="], + "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], "tough-cookie": ["tough-cookie@5.1.2", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A=="], @@ -2840,7 +2882,7 @@ "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="], - "uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], + "uuid": ["uuid@14.0.1", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew=="], "value-equal": ["value-equal@1.0.1", "", {}, "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="], @@ -2920,6 +2962,8 @@ "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], @@ -2950,6 +2994,8 @@ "@docusaurus/utils/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], + "@effect-fc/example-next/effect": ["effect@4.0.0-beta.85", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.8.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.1", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^14.0.0", "yaml": "^2.9.0" } }, "sha512-Cjv9YQyv4CiIccmRAQIWAoeESCpCpiuHYY8zb5vqiYs3Ac2yE5RQAnKq7z4Ir/3VJYZb8kxh6rS8czDDnpTdkQ=="], + "@jsonjoy.com/fs-snapshot/@jsonjoy.com/json-pack": ["@jsonjoy.com/json-pack@17.67.0", "", { "dependencies": { "@jsonjoy.com/base64": "17.67.0", "@jsonjoy.com/buffers": "17.67.0", "@jsonjoy.com/codegen": "17.67.0", "@jsonjoy.com/json-pointer": "17.67.0", "@jsonjoy.com/util": "17.67.0", "hyperdyperid": "^1.2.0", "thingies": "^2.5.0", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w=="], "@jsonjoy.com/fs-snapshot/@jsonjoy.com/util": ["@jsonjoy.com/util@17.67.0", "", { "dependencies": { "@jsonjoy.com/buffers": "17.67.0", "@jsonjoy.com/codegen": "17.67.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew=="], @@ -3016,6 +3062,10 @@ "dot-prop/is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], + "effect-fc-next/effect": ["effect@4.0.0-beta.85", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.8.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.1", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^14.0.0", "yaml": "^2.9.0" } }, "sha512-Cjv9YQyv4CiIccmRAQIWAoeESCpCpiuHYY8zb5vqiYs3Ac2yE5RQAnKq7z4Ir/3VJYZb8kxh6rS8czDDnpTdkQ=="], + + "effect-fc-next/effect-lens": ["effect-lens@2.0.0-beta.0", "", { "peerDependencies": { "effect": "4.0.0-beta.85" } }, "sha512-ntsRQSrzoX+GsNpkNVEGqebl/g1YOEDPIFRAHigf+4P6AtGnnOFcklqDHLrbm4zqnaxuWEgQvvn1J6S3eyC4yw=="], + "esrecurse/estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], "express/content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="], @@ -3030,6 +3080,8 @@ "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "global-dirs/ini": ["ini@2.0.0", "", {}, "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA=="], + "got/@sindresorhus/is": ["@sindresorhus/is@5.6.0", "", {}, "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g=="], "gray-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], @@ -3226,6 +3278,8 @@ "sitemap/@types/node": ["@types/node@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="], + "sockjs/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], + "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], @@ -3282,6 +3336,10 @@ "@docusaurus/core/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + "@effect-fc/example-next/effect/fast-check": ["fast-check@4.8.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg=="], + + "@effect-fc/example-next/effect/msgpackr": ["msgpackr@2.0.4", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA=="], + "@jsonjoy.com/fs-snapshot/@jsonjoy.com/json-pack/@jsonjoy.com/base64": ["@jsonjoy.com/base64@17.67.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw=="], "@jsonjoy.com/fs-snapshot/@jsonjoy.com/json-pack/@jsonjoy.com/codegen": ["@jsonjoy.com/codegen@17.67.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q=="], @@ -3312,6 +3370,10 @@ "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], + "effect-fc-next/effect/fast-check": ["fast-check@4.8.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg=="], + + "effect-fc-next/effect/msgpackr": ["msgpackr@2.0.4", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA=="], + "express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "file-loader/schema-utils/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], @@ -3370,8 +3432,12 @@ "@docusaurus/core/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + "@effect-fc/example-next/effect/fast-check/pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], + "css-select/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="], + "effect-fc-next/effect/fast-check/pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], + "file-loader/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "null-loader/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], diff --git a/packages/effect-fc-next/README.md b/packages/effect-fc-next/README.md new file mode 100644 index 0000000..5c164f8 --- /dev/null +++ b/packages/effect-fc-next/README.md @@ -0,0 +1,56 @@ +# Effect FC Next + +[Effect-TS](https://effect.website/) integration for React 19.2+ that allows you to write function components using Effect generators. + +This library is in early development. While it is (almost) feature complete and mostly usable, expect bugs and quirks. Things are still being ironed out, so ideas and criticisms are more than welcome. + +Documentation is currently being written. In the meantime, you can take a look at the `packages/example` directory. + +## Peer dependencies +- `effect` 3.19+ +- `react` & `@types/react` 19.2+ + +## Known issues +- React Refresh doesn't work for Effect FC's yet. Page reload is required to view changes. Regular React components are unaffected. + +## What writing components looks like +```typescript +export class TodosView extends Component.make("TodosView")(function*() { + const state = yield* TodosState + const [todos] = yield* Component.useSubscribables([state.subscriptionRef]) + + yield* Component.useOnMount(() => Effect.andThen( + Console.log("Todos mounted"), + Effect.addFinalizer(() => Console.log("Todos unmounted")), + )) + + const Todo = yield* TodoView.use + + return ( + + Todos + + + + + {Chunk.map(todos, todo => + + )} + + + ) +}) {} + +const Index = Component.make("IndexView")(function*() { + const context = yield* Component.useContextFromLayer(TodosState.Default) + const Todos = yield* Effect.provide(TodosView.use, context) + + return +}).pipe( + Component.withRuntime(runtime.context) +) + +export const Route = createFileRoute("/")({ + component: Index +}) +``` diff --git a/packages/effect-fc-next/biome.json b/packages/effect-fc-next/biome.json new file mode 100644 index 0000000..41d707b --- /dev/null +++ b/packages/effect-fc-next/biome.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://biomejs.dev/schemas/latest/schema.json", + "root": false, + "extends": "//", + "files": { + "includes": ["./src/**"] + } +} diff --git a/packages/effect-fc-next/package.json b/packages/effect-fc-next/package.json new file mode 100644 index 0000000..f29a70b --- /dev/null +++ b/packages/effect-fc-next/package.json @@ -0,0 +1,54 @@ +{ + "name": "effect-fc-next", + "description": "Write React function components with Effect", + "version": "0.1.0-beta.0", + "type": "module", + "files": [ + "./README.md", + "./dist" + ], + "license": "MIT", + "repository": { + "url": "git+https://github.com/Thiladev/effect-fc.git" + }, + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./*": [ + { + "types": "./dist/*/index.d.ts", + "default": "./dist/*/index.js" + }, + { + "types": "./dist/*.d.ts", + "default": "./dist/*.js" + } + ] + }, + "scripts": { + "build": "tsc", + "lint:tsc": "tsc --noEmit", + "lint:biome": "biome lint", + "test": "vitest run", + "pack": "npm pack", + "clean:cache": "rm -rf .turbo tsconfig.tsbuildinfo", + "clean:dist": "rm -rf dist", + "clean:modules": "rm -rf node_modules" + }, + "devDependencies": { + "@testing-library/react": "^16.3.0", + "jsdom": "^26.1.0", + "vitest": "^3.2.4" + }, + "peerDependencies": { + "@types/react": "^19.2.0", + "effect": "4.0.0-beta.85", + "react": "^19.2.0" + }, + "dependencies": { + "effect-lens": "2.0.0-beta.0" + } +} diff --git a/packages/effect-fc-next/src/Async.ts b/packages/effect-fc-next/src/Async.ts new file mode 100644 index 0000000..6495308 --- /dev/null +++ b/packages/effect-fc-next/src/Async.ts @@ -0,0 +1,171 @@ +/** biome-ignore-all lint/complexity/useArrowFunction: necessary for class prototypes */ +import { Context, Effect, type Equivalence, Function, Predicate, Scope } from "effect" +import * as React from "react" +import * as Component from "./Component.js" + + +export const AsyncTypeId: unique symbol = Symbol.for("@effect-fc/Async/Async") +export type AsyncTypeId = typeof AsyncTypeId + + +/** + * A trait for `Component`'s that allows them running asynchronous effects. + */ +export interface Async extends AsyncPrototype, AsyncOptions {} + +export interface AsyncPrototype { + readonly [AsyncTypeId]: AsyncTypeId +} + +/** + * Configuration options for `Async` components. + */ +export interface AsyncOptions { + /** + * The default fallback React node to display while the async operation is pending. + * Used if no fallback is provided to the component when rendering. + */ + readonly defaultFallback?: React.ReactNode +} + +/** + * Props for `Async` components. + */ +export type AsyncProps = Omit + + +export const AsyncPrototype: AsyncPrototype = Object.freeze({ + [AsyncTypeId]: AsyncTypeId, + + asFunctionComponent

( + this: Component.Component & Async, + contextRef: React.RefObject>>, + ) { + const Inner = (props: { readonly promise: Promise }) => React.use(props.promise) + + return ({ fallback, name, ...props }: AsyncProps) => { + const promise = Effect.runPromiseWith(contextRef.current)( + Effect.andThen( + Component.useScope([], this), + scope => Effect.provideService(this.body(props as P), Scope.Scope, scope), + ) + ) + + return React.createElement( + React.Suspense, + { fallback: fallback ?? this.defaultFallback, name }, + React.createElement(Inner, { promise }), + ) + } + }, +} as const) + +/** + * An equivalence function for comparing `AsyncProps` that ignores the `fallback` property. + * Used by default by async components with `Memoized.memoized` applied. + */ +export const defaultPropsEquivalence: Equivalence.Equivalence = ( + self: Record, + that: Record, +) => { + if (self === that) + return true + + for (const key in self) { + if (key === "fallback") + continue + if (!(key in that) || !Object.is(self[key], that[key])) + return false + } + + for (const key in that) { + if (key === "fallback") + continue + if (!(key in self)) + return false + } + + return true +} + + +export const isAsync = (u: unknown): u is Async => Predicate.hasProperty(u, AsyncTypeId) + +/** + * Converts a Component into an `Async` component that supports running asynchronous effects. + * + * Note: The component cannot have a prop named "promise" as it's reserved for internal use. + * + * @param self - The component to convert to an Async component + * @returns A new `Async` component with the same body, error, and context types as the input + * + * @example + * ```ts + * const MyAsyncComponent = MyComponent.pipe( + * Async.async, + * ) + * ``` + */ +export const async = ( + self: T & ( + "promise" extends keyof Component.Component.Props + ? "The 'promise' prop name is restricted for Async components. Please rename the 'promise' prop to something else." + : T + ) +): ( + & Omit> + & Component.Component< + Component.Component.Props & AsyncProps, + Component.Component.Success, + Component.Component.Error, + Component.Component.Context, + Component.Component.DefaultSignature & AsyncProps, Component.Component.Success> + > + & Async +) => Object.setPrototypeOf( + Object.assign(function() {}, self, { propsEquivalence: defaultPropsEquivalence }), + Object.freeze(Object.setPrototypeOf( + Object.assign({}, AsyncPrototype), + Object.getPrototypeOf(self), + )), +) + +/** + * Applies options to an Async component, returning a new Async component with the updated configuration. + * + * Supports both curried and uncurried application styles. + * + * @param self - The Async component to apply options to (in uncurried form) + * @param options - The options to apply to the component + * @returns An Async component with the applied options + * + * @example + * ```ts + * // Curried + * const MyAsyncComponent = MyComponent.pipe( + * Async.async, + * Async.withOptions({ defaultFallback:

Loading...

}), + * ) + * + * // Uncurried + * const MyAsyncComponent = Async.withOptions( + * Async.async(MyComponent), + * { defaultFallback:

Loading...

}, + * ) + * ``` + */ +export const withOptions: { + ( + options: Partial + ): (self: T) => T + ( + self: T, + options: Partial, + ): T +} = Function.dual(2, ( + self: T, + options: Partial, +): T => Object.setPrototypeOf( + Object.assign(function() {}, self, options), + Object.getPrototypeOf(self), +)) diff --git a/packages/effect-fc-next/src/Component.ts b/packages/effect-fc-next/src/Component.ts new file mode 100644 index 0000000..6bf9d93 --- /dev/null +++ b/packages/effect-fc-next/src/Component.ts @@ -0,0 +1,385 @@ +/** biome-ignore-all lint/complexity/noBannedTypes: {} is the default type for React props */ +import { + Context, + type Duration, + Effect, + Exit, + Function, + identity, + Layer, + Pipeable, + Predicate, + Scope, + Tracer, +} from "effect" +import * as React from "react" + + +export const ComponentTypeId: unique symbol = Symbol.for("@effect-fc/Component/Component") +export type ComponentTypeId = typeof ComponentTypeId + +export interface Component

+extends ComponentPrototype, ComponentOptions { + new(_: never): Record + readonly [ComponentTypeId]: ComponentTypeId + readonly "~Props": P + readonly "~Success": A + readonly "~Error": E + readonly "~Context": R + readonly "~Function": F + readonly body: (props: P) => Effect.Effect +} + +export declare namespace Component { + export type Default

= Component> + export type Any = Component + export type Signature = (props: any) => React.ReactNode + export type DefaultSignature

= (props: P) => A + export type Props = T["~Props"] + export type Success = T["~Success"] + export type Error = T["~Error"] + export type Context = T["~Context"] + export type Function = T["~Function"] + export type AsComponent = Component, Success, Error, Context, Function> +} + +export interface ComponentOptions { + readonly displayName?: string + readonly nonReactiveTags: readonly Context.Key[] + readonly finalizerExecutionStrategy: "sequential" | "parallel" + readonly finalizerExecutionDebounce: Duration.Input +} + +export const defaultOptions: ComponentOptions = { + nonReactiveTags: [Tracer.ParentSpan], + finalizerExecutionStrategy: "sequential", + finalizerExecutionDebounce: "100 millis", +} + +export interface ComponentPrototype extends Pipeable.Pipeable { + readonly [ComponentTypeId]: ComponentTypeId + readonly use: Effect.Effect> +} + +type ComponentImpl = Component + +const makeFunctionComponent = ( + self: ComponentImpl, + contextRef: React.RefObject>, +): Component.Signature => { + if ("asFunctionComponent" in self && typeof self.asFunctionComponent === "function") { + return self.asFunctionComponent(contextRef) + } + const FunctionComponent = (props: {}) => Effect.runSyncWith(contextRef.current)( + Effect.flatMap( + useScope([], self), + scope => Effect.provideService(self.body(props), Scope.Scope, scope), + ), + ) + FunctionComponent.displayName = self.displayName ?? "Anonymous" + return "transformFunctionComponent" in self && typeof self.transformFunctionComponent === "function" + ? self.transformFunctionComponent(FunctionComponent) + : FunctionComponent +} + +const use = Effect.fnUntraced(function* (self: ComponentImpl) { + const context = yield* Effect.context() + const cached = componentCache.get(self) + if (cached !== undefined) { + cached.contextRef.current = context + return cached.component + } + const contextRef = { current: context } + const component = makeFunctionComponent(self, contextRef) + componentCache.set(self, { contextRef, component }) + return component +}) + +const componentCache = new WeakMap } + readonly component: Component.Signature +}>() + +export const ComponentPrototype = Object.freeze({ + [ComponentTypeId]: ComponentTypeId, + ...Pipeable.Prototype, + get use() { + return use(this as ComponentImpl) + }, +}) as unknown as ComponentPrototype + +export const isComponent = (u: unknown): u is Component.Any => Predicate.hasProperty(u, ComponentTypeId) + +type GeneratorBody

= ( + props: P, +) => Effect.fn.Return + +type EffectBody

= ( + props: P, +) => Effect.Effect + +export interface Make { +

( + body: GeneratorBody | EffectBody, + ...pipeables: readonly Function[] + ): Component.Default + (name: string, options?: Tracer.SpanOptionsNoTrace):

( + body: GeneratorBody | EffectBody, + ...pipeables: readonly Function[] + ) => Component.Default +} + +const component = ( + body: Function, + displayName: string | undefined, + traced: boolean, + pipeables: readonly Function[], +): Component.Any => Object.setPrototypeOf( + Object.assign(function() {}, defaultOptions, { + body: traced && displayName + ? Effect.fn(displayName)(body as never, ...pipeables as []) + : Effect.fnUntraced(body as never, ...pipeables as []), + displayName, + }), + ComponentPrototype, +) + +export const make: Make = ((nameOrBody: string | Function, ...args: readonly unknown[]) => { + if (typeof nameOrBody === "string") { + return (body: Function, ...pipeables: readonly Function[]) => component(body, nameOrBody, true, pipeables) + } + return component(nameOrBody, undefined, true, args as readonly Function[]) +}) as Make + +export const makeUntraced: Make = ((nameOrBody: string | Function, ...args: readonly unknown[]) => { + if (typeof nameOrBody === "string") { + return (body: Function, ...pipeables: readonly Function[]) => component(body, nameOrBody, false, pipeables) + } + return component(nameOrBody, undefined, false, args as readonly Function[]) +}) as Make + +export declare namespace withSignature { + export type Result = ( + & Omit> + & Component, Component.Success, Component.Error, Component.Context, F> + ) +} + +export const withSignature: { + (): (self: T) => withSignature.Result + (self: T): withSignature.Result +} = (self?: Component.Any): any => self === undefined ? identity : self + +export const withOptions: { + (options: Partial): (self: T) => T + (self: T, options: Partial): T +} = Function.dual(2, (self: T, options: Partial): T => Object.setPrototypeOf( + Object.assign(function() {}, self, options), + Object.getPrototypeOf(self), +)) + +export const withRuntime: { +

( + context: React.Context>, + ): (self: Component, F>) => F +

( + self: Component, F>, + context: React.Context>, + ): F +} = Function.dual(2,

( + self: Component, + context: React.Context>, +) => function WithRuntime(props: P) { + return React.createElement( + Effect.runSyncWith(React.useContext(context))(self.use) as React.FC

, + props, + ) +}) + +export declare namespace useScope { + export interface Options { + readonly finalizerExecutionStrategy?: "sequential" | "parallel" + readonly finalizerExecutionDebounce?: Duration.Input + } +} + +export const useScope = Effect.fnUntraced(function* ( + deps: React.DependencyList, + options?: useScope.Options, +): Effect.fn.Return { + const context = yield* Effect.context() + const contextRef = React.useRef(context) + contextRef.current = context + const scope = React.useMemo( + () => Scope.makeUnsafe(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy), + // biome-ignore lint/correctness/useExhaustiveDependencies: caller controls scope lifetime + deps, + ) + + React.useEffect(() => { + const pending = scopeCleanupTimers.get(scope) + if (pending !== undefined) clearTimeout(pending) + return () => { + const timer = setTimeout(() => { + Effect.runSyncWith(contextRef.current)(Scope.close(scope, Exit.succeed(undefined))) + scopeCleanupTimers.delete(scope) + }, durationMillis(options?.finalizerExecutionDebounce ?? defaultOptions.finalizerExecutionDebounce)) + scopeCleanupTimers.set(scope, timer) + } + }, [scope, options?.finalizerExecutionDebounce]) + + return scope +}) + +const scopeCleanupTimers = new WeakMap>() + +const durationMillis = (input: Duration.Input): number => { + if (typeof input === "number") return input + return Number(Effect.runSync(Effect.map(Effect.succeed(input), value => { + const match = typeof value === "string" ? /([\d.]+)\s*(millis|seconds?)/.exec(value) : undefined + if (!match) return 0 + return Number(match[1]) * (match[2].startsWith("second") ? 1_000 : 1) + }))) +} + +export const useOnMount = Effect.fnUntraced(function* ( + f: () => Effect.Effect, +): Effect.fn.Return { + const context = yield* Effect.context() + const id = React.useId() + let cached = mountCache.get(id) + if (cached === undefined) { + cached = { + effect: Effect.runSyncWith(context)(Effect.cached(f())), + } + mountCache.set(id, cached) + } + React.useEffect(() => { + if (cached?.cleanup !== undefined) clearTimeout(cached.cleanup) + const entry = cached + return () => { + entry.cleanup = setTimeout(() => mountCache.delete(id), 0) + } + }, [id, cached]) + return yield* cached.effect as Effect.Effect +}) + +const mountCache = new Map + cleanup?: ReturnType +}>() + +export declare namespace useOnChange { + export interface Options extends useScope.Options {} +} + +export const useOnChange = Effect.fnUntraced(function* ( + f: () => Effect.Effect, + deps: React.DependencyList, + options?: useOnChange.Options, +): Effect.fn.Return> { + const context = yield* Effect.context>() + const scope = yield* useScope(deps, options) + const cached = + // biome-ignore lint/correctness/useExhaustiveDependencies: scope tracks the caller-provided dependency list + React.useMemo( + () => Effect.runSyncWith(context)(Effect.cached(Effect.provideService(f(), Scope.Scope, scope))), + [scope], + ) + return yield* cached +}) + +export declare namespace useReactEffect { + export interface Options { + readonly finalizerExecutionMode?: "sync" | "fork" + readonly finalizerExecutionStrategy?: "sequential" | "parallel" + } +} + +const runReactEffect = ( + context: Context.Context>, + f: () => Effect.Effect, + options?: useReactEffect.Options, +): (() => void) => { + const scope = Scope.makeUnsafe(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy) + Effect.runSyncWith(context)(Effect.exit(Effect.provideService(f(), Scope.Scope, scope))) + return () => { + const close = Scope.close(scope, Exit.succeed(undefined)) + if ((options?.finalizerExecutionMode ?? "fork") === "sync") Effect.runSyncWith(context)(close) + else Effect.runForkWith(context)(close) + } +} + +export const useReactEffect = Effect.fnUntraced(function* ( + f: () => Effect.Effect, + deps?: React.DependencyList, + options?: useReactEffect.Options, +): Effect.fn.Return> { + const context = yield* Effect.context>() + // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + React.useEffect(() => runReactEffect(context, f, options), deps) +}) + +export declare namespace useReactLayoutEffect { + export interface Options extends useReactEffect.Options {} +} + +export const useReactLayoutEffect = Effect.fnUntraced(function* ( + f: () => Effect.Effect, + deps?: React.DependencyList, + options?: useReactLayoutEffect.Options, +): Effect.fn.Return> { + const context = yield* Effect.context>() + // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + React.useLayoutEffect(() => runReactEffect(context, f, options), deps) +}) + +export const useRunSync = (): Effect.Effect< + (effect: Effect.Effect) => A, + never, + R +> => Effect.map(Effect.context(), Effect.runSyncWith) + +export const useRunPromise = (): Effect.Effect< + (effect: Effect.Effect) => Promise, + never, + R +> => Effect.map(Effect.context(), Effect.runPromiseWith) + +export const useCallbackSync = Effect.fnUntraced(function* ( + f: (...args: Args) => Effect.Effect, + deps: React.DependencyList, +): Effect.fn.Return<(...args: Args) => A, never, R> { + const context = yield* Effect.context() + const contextRef = React.useRef(context) + contextRef.current = context + // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + return React.useCallback((...args: Args) => Effect.runSyncWith(contextRef.current)(f(...args)), deps) +}) + +export const useCallbackPromise = Effect.fnUntraced(function* ( + f: (...args: Args) => Effect.Effect, + deps: React.DependencyList, +): Effect.fn.Return<(...args: Args) => Promise, never, R> { + const context = yield* Effect.context() + const contextRef = React.useRef(context) + contextRef.current = context + // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + return React.useCallback((...args: Args) => Effect.runPromiseWith(contextRef.current)(f(...args)), deps) +}) + +export declare namespace useContext { + export interface Options extends useOnChange.Options {} +} + +export const useContextFromLayer = ( + layer: Layer.Layer, + options?: useContext.Options, +): Effect.Effect, E, RIn | Scope.Scope> => useOnChange( + () => Effect.flatMap( + Effect.context(), + context => Layer.build(Layer.provide(layer, Layer.succeedContext(context))), + ), + [layer], + options, +) diff --git a/packages/effect-fc-next/src/ErrorObserver.ts b/packages/effect-fc-next/src/ErrorObserver.ts new file mode 100644 index 0000000..0fd19aa --- /dev/null +++ b/packages/effect-fc-next/src/ErrorObserver.ts @@ -0,0 +1,47 @@ +import { type Cause, Context, Effect, Layer, Option, Pipeable, Predicate, PubSub, type Scope } from "effect" + + +export const ErrorObserverTypeId: unique symbol = Symbol.for("@effect-fc/ErrorObserver/ErrorObserver") +export type ErrorObserverTypeId = typeof ErrorObserverTypeId + +export interface ErrorObserver extends Pipeable.Pipeable { + readonly [ErrorObserverTypeId]: ErrorObserverTypeId + handle(effect: Effect.Effect): Effect.Effect + readonly subscribe: Effect.Effect>, never, Scope.Scope> +} + +export const ErrorObserver = () => Context.Service>( + "@effect-fc/ErrorObserver/ErrorObserver", +) + +export class ErrorObserverImpl extends Pipeable.Class implements ErrorObserver { + readonly [ErrorObserverTypeId]: ErrorObserverTypeId = ErrorObserverTypeId + + constructor(readonly pubsub: PubSub.PubSub>) { + super() + } + + get subscribe(): Effect.Effect>, never, Scope.Scope> { + return PubSub.subscribe(this.pubsub) + } + + handle(effect: Effect.Effect): Effect.Effect { + return Effect.tapCause(effect, cause => Effect.asVoid( + PubSub.publish(this.pubsub, cause as unknown as Cause.Cause), + )) + } +} + +export const isErrorObserver = (u: unknown): u is ErrorObserver => Predicate.hasProperty(u, ErrorObserverTypeId) + +export const layer: Layer.Layer = Layer.effect(ErrorObserver())( + Effect.map(PubSub.unbounded>(), pubsub => new ErrorObserverImpl(pubsub)), +) + +export const handle = (effect: Effect.Effect): Effect.Effect => Effect.flatMap( + Effect.serviceOption(ErrorObserver()), + Option.match({ + onSome: observer => observer.handle(effect), + onNone: () => effect, + }), +) diff --git a/packages/effect-fc-next/src/Form.ts b/packages/effect-fc-next/src/Form.ts new file mode 100644 index 0000000..30039aa --- /dev/null +++ b/packages/effect-fc-next/src/Form.ts @@ -0,0 +1,279 @@ +import { Array, type Cause, Chunk, type Duration, Effect, Equal, Function, identity, Option, Pipeable, Predicate, type Scope, Stream, SubscriptionRef } from "effect" +import type * as React from "react" +import * as Component from "./Component.js" +import * as Lens from "./Lens.js" +import * as Subscribable from "./Subscribable.js" + + +export const FormTypeId: unique symbol = Symbol.for("@effect-fc/Form/Form") +export type FormTypeId = typeof FormTypeId + +export interface FormIssue { + readonly path: readonly PropertyKey[] + readonly message: string +} + +export interface Form +extends Pipeable.Pipeable { + readonly [FormTypeId]: FormTypeId + + readonly path: P + readonly value: Subscribable.Subscribable, ER, never> + readonly encodedValue: Lens.Lens + readonly issues: Subscribable.Subscribable + readonly isValidating: Subscribable.Subscribable + readonly canCommit: Subscribable.Subscribable + readonly isCommitting: Subscribable.Subscribable +} + +export class FormImpl +extends Pipeable.Class implements Form { + readonly [FormTypeId]: FormTypeId = FormTypeId + + constructor( + readonly path: P, + readonly value: Subscribable.Subscribable, ER, never>, + readonly encodedValue: Lens.Lens, + readonly issues: Subscribable.Subscribable, + readonly isValidating: Subscribable.Subscribable, + readonly canCommit: Subscribable.Subscribable, + readonly isCommitting: Subscribable.Subscribable, + ) { + super() + } +} + + +export const isForm = (u: unknown): u is Form => Predicate.hasProperty(u, FormTypeId) + + +const filterIssuesByPath = ( + issues: readonly FormIssue[], + path: readonly PropertyKey[], +): readonly FormIssue[] => Array.filter(issues, issue => + issue.path.length >= path.length && Array.every(path, (p, i) => p === issue.path[i]) +) + +export const focusObjectOn: { +

( + self: Form, + key: K, + ): Form +

( + key: K, + ): (self: Form) => Form +} = Function.dual(2,

( + self: Form, + key: K, +): Form => { + const form = self as unknown as FormImpl + const path = [...form.path, key] as const + + return new FormImpl( + path, + Subscribable.mapOption(form.value, a => a[key]), + Lens.focusObjectOn(form.encodedValue, key), + Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)), + form.isValidating, + form.canCommit, + form.isCommitting, + ) +}) + +export const focusArrayAt: { +

( + self: Form, + index: number, + ): Form +

( + index: number, + ): (self: Form) => Form +} = Function.dual(2,

( + self: Form, + index: number, +): Form => { + const form = self as unknown as FormImpl + const path = [...form.path, index] as const + + return new FormImpl( + path, + Subscribable.mapOptionEffect(form.value, values => Effect.fromOption(Array.get(values, index))), + Lens.focusArrayAt(form.encodedValue, index), + Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)), + form.isValidating, + form.canCommit, + form.isCommitting, + ) +}) + +export const focusTupleAt: { +

( + self: Form, + index: K, + ): Form +

( + index: K, + ): (self: Form) => Form +} = Function.dual(2,

( + self: Form, + index: K, +): Form => { + const form = self as unknown as FormImpl + const path = [...form.path, index] as const + + return new FormImpl( + path, + Subscribable.mapOption(form.value, values => values[index]), + Lens.focusTupleAt(form.encodedValue, index), + Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)), + form.isValidating, + form.canCommit, + form.isCommitting, + ) +}) + +export const focusChunkAt: { +

( + self: Form, Chunk.Chunk, ER, EW>, + index: number, + ): Form +

( + index: number, + ): (self: Form, Chunk.Chunk, ER, EW>) => Form +} = Function.dual(2,

( + self: Form, Chunk.Chunk, ER, EW>, + index: number, +): Form => { + const form = self as unknown as FormImpl, Chunk.Chunk, ER, EW> + const path = [...form.path, index] as const + + return new FormImpl( + path, + Subscribable.mapOptionEffect(form.value, values => Effect.fromOption(Chunk.get(values, index))), + Lens.focusChunkAt(form.encodedValue, index), + Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)), + form.isValidating, + form.canCommit, + form.isCommitting, + ) +}) + + +export namespace useInput { + export interface Options { + readonly debounce?: Duration.Input + } + + export interface Success { + readonly value: T + readonly setValue: React.Dispatch> + } +} + +export const useInput = Effect.fnUntraced(function*

( + form: Form, + options?: useInput.Options, +): Effect.fn.Return, ER, Scope.Scope> { + const internalValueLens = yield* Component.useOnChange(() => Effect.gen(function*() { + const internalValueLens = yield* Lens.get(form.encodedValue).pipe( + Effect.flatMap(SubscriptionRef.make), + Effect.map(Lens.fromSubscriptionRef), + ) + + yield* Effect.forkScoped(Effect.all([ + Stream.runForEach( + Stream.drop(form.encodedValue.changes, 1), + upstreamEncodedValue => Effect.flatMap( + Lens.get(internalValueLens), + internalValue => !Equal.equals(upstreamEncodedValue, internalValue) + ? Lens.set(internalValueLens, upstreamEncodedValue) + : Effect.succeed(undefined), + ), + ), + + Stream.runForEach( + internalValueLens.changes.pipe( + Stream.drop(1), + Stream.changesWith(Equal.asEquivalence()), + options?.debounce ? Stream.debounce(options.debounce) : identity, + ), + internalValue => Lens.set(form.encodedValue, internalValue), + ), + ], { concurrency: "unbounded", discard: true })) + + return internalValueLens + }), [form, options?.debounce]) + + const [value, setValue] = yield* Lens.useState(internalValueLens) + return { value, setValue } +}) + +export namespace useOptionalInput { + export interface Options extends useInput.Options { + readonly defaultValue: T + } + + export interface Success extends useInput.Success { + readonly enabled: boolean + readonly setEnabled: React.Dispatch> + } +} + +export const useOptionalInput = Effect.fnUntraced(function*

( + field: Form, ER, EW>, + options: useOptionalInput.Options, +): Effect.fn.Return, ER, Scope.Scope> { + const [enabledLens, internalValueLens] = yield* Component.useOnChange(() => Effect.gen(function*() { + const [enabledLens, internalValueLens] = yield* Effect.flatMap( + Lens.get(field.encodedValue), + Option.match({ + onSome: v => Effect.all([ + Effect.map(SubscriptionRef.make(true), Lens.fromSubscriptionRef), + Effect.map(SubscriptionRef.make(v), Lens.fromSubscriptionRef), + ]), + onNone: () => Effect.all([ + Effect.map(SubscriptionRef.make(false), Lens.fromSubscriptionRef), + Effect.map(SubscriptionRef.make(options.defaultValue), Lens.fromSubscriptionRef), + ]), + }), + ) + + yield* Effect.forkScoped(Effect.all([ + Stream.runForEach( + Stream.drop(field.encodedValue.changes, 1), + + upstreamEncodedValue => Effect.flatMap( + Effect.all([Lens.get(enabledLens), Lens.get(internalValueLens)]), + ([enabled, internalValue]) => Equal.equals(upstreamEncodedValue, enabled ? Option.some(internalValue) : Option.none()) + ? Effect.succeed(undefined) + : Option.match(upstreamEncodedValue, { + onSome: v => Effect.andThen( + Lens.set(enabledLens, true), + Lens.set(internalValueLens, v), + ), + onNone: () => Effect.andThen( + Lens.set(enabledLens, false), + Lens.set(internalValueLens, options.defaultValue), + ), + }), + ), + ), + + Stream.runForEach( + enabledLens.changes.pipe( + Stream.zipLatest(internalValueLens.changes), + Stream.drop(1), + Stream.changesWith(Equal.asEquivalence()), + options?.debounce ? Stream.debounce(options.debounce) : identity, + ), + ([enabled, internalValue]) => Lens.set(field.encodedValue, enabled ? Option.some(internalValue) : Option.none()), + ), + ], { concurrency: "unbounded" })) + + return [enabledLens, internalValueLens] as const + }), [field, options.debounce]) + + const [enabled, setEnabled] = yield* Lens.useState(enabledLens) + const [value, setValue] = yield* Lens.useState(internalValueLens) + return { enabled, setEnabled, value, setValue } +}) diff --git a/packages/effect-fc-next/src/Lens.ts b/packages/effect-fc-next/src/Lens.ts new file mode 100644 index 0000000..4941dea --- /dev/null +++ b/packages/effect-fc-next/src/Lens.ts @@ -0,0 +1,62 @@ +import { Effect, Equivalence, Stream, SubscriptionRef } from "effect" +import { Lens } from "effect-lens" +import * as React from "react" +import * as Component from "./Component.js" +import * as SetStateAction from "./SetStateAction.js" + + +export * from "effect-lens/Lens" + +export declare namespace useState { + export interface Options { + readonly equivalence?: Equivalence.Equivalence + } +} + +export const useState = Effect.fnUntraced(function* ( + lens: Lens.Lens, + options?: useState.Options>, +): Effect.fn.Return>], ER | EW, RR | RW> { + const [reactStateValue, setReactStateValue] = React.useState(yield* Component.useOnMount(() => Lens.get(lens))) + + yield* Component.useReactEffect(() => Effect.forkScoped( + Stream.runForEach( + Stream.changesWith(lens.changes, options?.equivalence ?? Equivalence.strictEqual()), + v => Effect.sync(() => setReactStateValue(v)), + ) + ), [lens]) + + const setValue = yield* Component.useCallbackSync( + (setStateAction: React.SetStateAction) => Effect.tap( + Lens.updateAndGet(lens, prevState => SetStateAction.value(setStateAction, prevState)), + v => Effect.sync(() => setReactStateValue(v)), + ), + [lens], + ) + + return [reactStateValue, setValue] +}) + +export declare namespace useFromReactState { + export interface Options { + readonly equivalence?: Equivalence.Equivalence + } +} + +export const useFromReactState = Effect.fnUntraced(function* ( + [value, setValue]: readonly [A, React.Dispatch>], + options?: useFromReactState.Options>, +): Effect.fn.Return> { + const lens = yield* Component.useOnMount(() => Effect.map( + SubscriptionRef.make(value), + Lens.fromSubscriptionRef, + )) + + yield* Component.useReactEffect(() => Effect.forkScoped(Stream.runForEach( + Stream.changesWith(lens.changes, options?.equivalence ?? Equivalence.strictEqual()), + v => Effect.sync(() => setValue(v)), + )), [setValue]) + yield* Component.useReactEffect(() => Lens.set(lens, value), [value]) + + return lens +}) diff --git a/packages/effect-fc-next/src/Memoized.ts b/packages/effect-fc-next/src/Memoized.ts new file mode 100644 index 0000000..0c981c8 --- /dev/null +++ b/packages/effect-fc-next/src/Memoized.ts @@ -0,0 +1,112 @@ +/** biome-ignore-all lint/complexity/useArrowFunction: necessary for class prototypes */ +import { type Equivalence, Function, Predicate } from "effect" +import * as React from "react" +import type * as Component from "./Component.js" + + +export const MemoizedTypeId: unique symbol = Symbol.for("@effect-fc/Memoized/Memoized") +export type MemoizedTypeId = typeof MemoizedTypeId + + +/** + * A trait for `Component`'s that uses `React.memo` to optimize re-renders based on prop equality. + * + * @template P The props type of the component + */ +export interface Memoized

extends MemoizedPrototype, MemoizedOptions

{} + +export interface MemoizedPrototype { + readonly [MemoizedTypeId]: MemoizedTypeId +} + +/** + * Configuration options for Memoized components. + * + * @template P The props type of the component + */ +export interface MemoizedOptions

{ + /** + * An optional equivalence function for comparing component props. + * If provided, this function is used by React.memo to determine if props have changed. + * Returns `true` if props are equivalent (no re-render), `false` if they differ (re-render). + */ + readonly propsEquivalence?: Equivalence.Equivalence

+} + + +export const MemoizedPrototype: MemoizedPrototype = Object.freeze({ + [MemoizedTypeId]: MemoizedTypeId, + + transformFunctionComponent

( + this: Memoized

, + f: React.FC

, + ) { + return React.memo(f, this.propsEquivalence) + }, +} as const) + + +export const isMemoized = (u: unknown): u is Memoized => Predicate.hasProperty(u, MemoizedTypeId) + +/** + * Converts a Component into a `Memoized` component that optimizes re-renders using `React.memo`. + * + * @param self - The component to convert to a Memoized component + * @returns A new `Memoized` component with the same body, error, and context types as the input + * + * @example + * ```ts + * const MyMemoizedComponent = MyComponent.pipe( + * Memoized.memoized, + * ) + * ``` + */ +export const memoized = ( + self: T +): T & Memoized> => Object.setPrototypeOf( + Object.assign(function() {}, self), + Object.freeze(Object.setPrototypeOf( + Object.assign({}, MemoizedPrototype), + Object.getPrototypeOf(self), + )), +) + +/** + * Applies options to a Memoized component, returning a new Memoized component with the updated configuration. + * + * Supports both curried and uncurried application styles. + * + * @param self - The Memoized component to apply options to (in uncurried form) + * @param options - The options to apply to the component + * @returns A Memoized component with the applied options + * + * @example + * ```ts + * // Curried + * const MyMemoizedComponent = MyComponent.pipe( + * Memoized.memoized, + * Memoized.withOptions({ propsEquivalence: (a, b) => a.id === b.id }), + * ) + * + * // Uncurried + * const MyMemoizedComponent = Memoized.withOptions( + * Memoized.memoized(MyComponent), + * { propsEquivalence: (a, b) => a.id === b.id }, + * ) + * ``` + */ +export const withOptions: { + >( + options: Partial>> + ): (self: T) => T + >( + self: T, + options: Partial>>, + ): T +} = Function.dual(2, >( + self: T, + options: Partial>>, +): T => Object.setPrototypeOf( + Object.assign(function() {}, self, options), + Object.getPrototypeOf(self), +)) diff --git a/packages/effect-fc-next/src/Mutation.ts b/packages/effect-fc-next/src/Mutation.ts new file mode 100644 index 0000000..0d873eb --- /dev/null +++ b/packages/effect-fc-next/src/Mutation.ts @@ -0,0 +1,146 @@ +import { type Context, Effect, Equal, type Fiber, Option, Pipeable, Predicate, type Scope, Stream, SubscriptionRef } from "effect" +import { Subscribable } from "effect-lens" +import * as Result from "./Result.js" + + +export const MutationTypeId: unique symbol = Symbol.for("@effect-fc/Mutation/Mutation") +export type MutationTypeId = typeof MutationTypeId + +export interface Mutation +extends Pipeable.Pipeable { + readonly [MutationTypeId]: MutationTypeId + + readonly context: Context.Context + readonly f: (key: K) => Effect.Effect + readonly initialProgress: P + + readonly latestKey: Subscribable.Subscribable> + readonly fiber: Subscribable.Subscribable>> + readonly result: Subscribable.Subscribable> + readonly latestFinalResult: Subscribable.Subscribable>> + + mutate(key: K): Effect.Effect> + mutateSubscribable(key: K): Effect.Effect>> +} + +export declare namespace Mutation { + export type AnyKey = readonly any[] +} + +export class MutationImpl +extends Pipeable.Class implements Mutation { + readonly [MutationTypeId]: MutationTypeId = MutationTypeId + readonly latestKey: Subscribable.Subscribable> + readonly fiber: Subscribable.Subscribable>> + readonly result: Subscribable.Subscribable> + readonly latestFinalResult: Subscribable.Subscribable>> + + constructor( + readonly context: Context.Context, + readonly f: (key: K) => Effect.Effect, + readonly initialProgress: P, + + readonly latestKeyRef: SubscriptionRef.SubscriptionRef>, + readonly fiberRef: SubscriptionRef.SubscriptionRef>>, + readonly resultRef: SubscriptionRef.SubscriptionRef>, + readonly latestFinalResultRef: SubscriptionRef.SubscriptionRef>>, + ) { + super() + this.latestKey = fromSubscriptionRef(latestKeyRef) + this.fiber = fromSubscriptionRef(fiberRef) + this.result = fromSubscriptionRef(resultRef) + this.latestFinalResult = fromSubscriptionRef(latestFinalResultRef) + } + + mutate(key: K): Effect.Effect> { + return SubscriptionRef.set(this.latestKeyRef, Option.some(key)).pipe( + Effect.andThen(this.start(key)), + Effect.andThen(sub => this.watch(sub)), + Effect.provide(this.context), + ) + } + mutateSubscribable(key: K): Effect.Effect>> { + return SubscriptionRef.set(this.latestKeyRef, Option.some(key)).pipe( + Effect.andThen(this.start(key)), + Effect.tap(sub => Effect.forkScoped(this.watch(sub))), + Effect.provide(this.context), + ) + } + + start(key: K): Effect.Effect< + Subscribable.Subscribable>, + never, + Scope.Scope | R + > { + const self = this + return Effect.gen(function*() { + const initial = yield* SubscriptionRef.get(self.latestFinalResultRef) + const [sub, fiber] = yield* Result.unsafeForkEffect( + Effect.onExit(self.f(key), () => Effect.andThen( + Effect.all([Effect.fiberId, SubscriptionRef.get(self.fiberRef)]), + ([currentFiberId, fiber]) => Option.match(fiber, { + onSome: v => Equal.equals(currentFiberId, v.id) + ? SubscriptionRef.set(self.fiberRef, Option.none()) + : Effect.succeed(undefined), + onNone: () => Effect.succeed(undefined), + }), + )), + + { + initial: Option.isSome(initial) ? Result.willFetch(initial.value) : Result.initial(), + initialProgress: self.initialProgress, + } as Result.unsafeForkEffect.Options, + ) + yield* SubscriptionRef.set(self.fiberRef, Option.some(fiber)) + return sub + }) + } + + watch( + sub: Subscribable.Subscribable> + ): Effect.Effect> { + return sub.get.pipe( + Effect.andThen(initial => Stream.runFoldEffect( + Stream.takeUntil(sub.changes, result => Result.isFinal(result) && !Result.hasFlag(result)), + () => initial, + (_, result) => Effect.as(SubscriptionRef.set(this.resultRef, result), result), + ) as Effect.Effect>), + Effect.tap(result => SubscriptionRef.set(this.latestFinalResultRef, Option.some(result))), + ) + } +} + + +export const isMutation = (u: unknown): u is Mutation => Predicate.hasProperty(u, MutationTypeId) + + +export declare namespace make { + export interface Options { + readonly f: (key: K) => Effect.Effect>> + readonly initialProgress?: P + } +} + +export const make = Effect.fnUntraced(function* ( + options: make.Options +): Effect.fn.Return< + Mutation, P>, + never, + Scope.Scope | Result.forkEffect.OutputContext +> { + return new MutationImpl( + yield* Effect.context>(), + options.f as any, + options.initialProgress as P, + + yield* SubscriptionRef.make(Option.none()), + yield* SubscriptionRef.make(Option.none>()), + yield* SubscriptionRef.make(Result.initial()), + yield* SubscriptionRef.make(Option.none>()), + ) +}) + +const fromSubscriptionRef = (ref: SubscriptionRef.SubscriptionRef): Subscribable.Subscribable => Subscribable.make({ + get: SubscriptionRef.get(ref), + changes: SubscriptionRef.changes(ref), +}) diff --git a/packages/effect-fc-next/src/PubSub.ts b/packages/effect-fc-next/src/PubSub.ts new file mode 100644 index 0000000..27401bc --- /dev/null +++ b/packages/effect-fc-next/src/PubSub.ts @@ -0,0 +1,17 @@ +import { Effect, PubSub, type Scope } from "effect" +import type * as React from "react" +import * as Component from "./Component.js" + + +export const useFromReactiveValues = Effect.fnUntraced(function* ( + values: A +): Effect.fn.Return, never, Scope.Scope> { + const pubsub = yield* Component.useOnMount(() => Effect.acquireRelease(PubSub.unbounded(), PubSub.shutdown)) + yield* Component.useReactEffect(() => Effect.flatMap( + PubSub.isShutdown(pubsub), + shutdown => shutdown ? Effect.succeed(undefined) : Effect.asVoid(PubSub.publish(pubsub, values)), + ), values) + return pubsub +}) + +export * from "effect/PubSub" diff --git a/packages/effect-fc-next/src/Query.ts b/packages/effect-fc-next/src/Query.ts new file mode 100644 index 0000000..e9e317b --- /dev/null +++ b/packages/effect-fc-next/src/Query.ts @@ -0,0 +1,283 @@ +import { + type Cause, + type Context, + type Duration, + Effect, + Equal, + Fiber, + Option, + Pipeable, + Predicate, + type Scope, + Semaphore, + Stream, + SubscriptionRef, +} from "effect" +import { Subscribable } from "effect-lens" +import * as QueryClient from "./QueryClient.js" +import * as Result from "./Result.js" + + +export const QueryTypeId: unique symbol = Symbol.for("@effect-fc/Query/Query") +export type QueryTypeId = typeof QueryTypeId + +export interface Query +extends Pipeable.Pipeable { + readonly [QueryTypeId]: QueryTypeId + readonly context: Context.Context + readonly key: Stream.Stream + readonly f: (key: K) => Effect.Effect + readonly initialProgress: P + readonly staleTime: Duration.Input + readonly refreshOnWindowFocus: boolean + readonly latestKey: Subscribable.Subscribable> + readonly fiber: Subscribable.Subscribable>> + readonly result: Subscribable.Subscribable> + readonly latestFinalResult: Subscribable.Subscribable>> + readonly run: Effect.Effect + fetch(key: K): Effect.Effect> + fetchSubscribable(key: K): Effect.Effect>> + readonly refresh: Effect.Effect, Cause.NoSuchElementError> + readonly refreshSubscribable: Effect.Effect>, Cause.NoSuchElementError> + readonly invalidateCache: Effect.Effect + invalidateCacheEntry(key: K): Effect.Effect +} + +export declare namespace Query { + export type AnyKey = readonly any[] +} + +export class QueryImpl +extends Pipeable.Class implements Query { + readonly [QueryTypeId]: QueryTypeId = QueryTypeId + readonly latestKey: Subscribable.Subscribable> + readonly fiber: Subscribable.Subscribable>> + readonly result: Subscribable.Subscribable> + readonly latestFinalResult: Subscribable.Subscribable>> + + constructor( + readonly context: Context.Context, + readonly key: Stream.Stream, + readonly f: (key: K) => Effect.Effect, + readonly initialProgress: P, + readonly staleTime: Duration.Input, + readonly refreshOnWindowFocus: boolean, + readonly latestKeyRef: SubscriptionRef.SubscriptionRef>, + readonly fiberRef: SubscriptionRef.SubscriptionRef>>, + readonly resultRef: SubscriptionRef.SubscriptionRef>, + readonly latestFinalResultRef: SubscriptionRef.SubscriptionRef>>, + readonly runSemaphore: Semaphore.Semaphore, + ) { + super() + this.latestKey = fromSubscriptionRef(latestKeyRef) + this.fiber = fromSubscriptionRef(fiberRef) + this.result = fromSubscriptionRef(resultRef) + this.latestFinalResult = fromSubscriptionRef(latestFinalResultRef) + } + + get run(): Effect.Effect { + const focus = this.refreshOnWindowFocus && typeof window !== "undefined" + ? Stream.runForEach(Stream.fromEventListener(window, "focus"), () => this.refreshSubscribable) + : Effect.succeed(undefined) + return Effect.all([ + Stream.runForEach(this.key, key => this.fetchSubscribable(key)), + focus, + ], { concurrency: "unbounded", discard: true }).pipe( + Effect.ignore, + this.runSemaphore.withPermits(1), + Effect.provide(this.context), + ) + } + + get interrupt(): Effect.Effect { + return Effect.flatMap(SubscriptionRef.get(this.fiberRef), Option.match({ + onSome: Fiber.interrupt, + onNone: () => Effect.succeed(undefined), + })) + } + + fetch(key: K): Effect.Effect> { + const self = this + return Effect.gen(function*() { + yield* self.interrupt + yield* SubscriptionRef.set(self.latestKeyRef, Option.some(key)) + const previous = yield* SubscriptionRef.get(self.latestFinalResultRef) + const sub = yield* self.startCached(key, Option.isSome(previous) + ? Result.willFetch(previous.value) as Result.Final + : Result.initial()) + return yield* self.watch(key, sub) + }).pipe(Effect.provide(this.context)) + } + + fetchSubscribable(key: K): Effect.Effect>> { + const self = this + return Effect.gen(function*() { + yield* self.interrupt + yield* SubscriptionRef.set(self.latestKeyRef, Option.some(key)) + const previous = yield* SubscriptionRef.get(self.latestFinalResultRef) + const sub = yield* self.startCached(key, Option.isSome(previous) + ? Result.willFetch(previous.value) as Result.Final + : Result.initial()) + yield* Effect.forkScoped(self.watch(key, sub)) + return sub + }).pipe(Effect.provide(this.context)) + } + + get refresh(): Effect.Effect, Cause.NoSuchElementError> { + const self = this + return Effect.gen(function*() { + yield* self.interrupt + const key = yield* Effect.fromOption(yield* SubscriptionRef.get(self.latestKeyRef)) + const previous = yield* SubscriptionRef.get(self.latestFinalResultRef) + const sub = yield* self.startCached(key, Option.isSome(previous) + ? Result.willRefresh(previous.value) as Result.Final + : Result.initial()) + return yield* self.watch(key, sub) + }).pipe(Effect.provide(this.context)) + } + + get refreshSubscribable(): Effect.Effect>, Cause.NoSuchElementError> { + const self = this + return Effect.gen(function*() { + yield* self.interrupt + const key = yield* Effect.fromOption(yield* SubscriptionRef.get(self.latestKeyRef)) + const previous = yield* SubscriptionRef.get(self.latestFinalResultRef) + const sub = yield* self.startCached(key, Option.isSome(previous) + ? Result.willRefresh(previous.value) as Result.Final + : Result.initial()) + yield* Effect.forkScoped(self.watch(key, sub)) + return sub + }).pipe(Effect.provide(this.context)) + } + + startCached( + key: K, + initial: Result.Initial | Result.Final, + ): Effect.Effect>, never, Scope.Scope | QueryClient.QueryClient | R> { + return Effect.flatMap(this.getCacheEntry(key), Option.match({ + onSome: entry => Effect.flatMap( + QueryClient.isQueryClientCacheEntryStale(entry), + isStale => isStale + ? this.start(key, Result.willRefresh(entry.result) as Result.Final) + : Effect.succeed(Subscribable.make({ + get: Effect.succeed(entry.result as Result.Result), + changes: Stream.make(entry.result as Result.Result), + })), + ), + onNone: () => this.start(key, initial), + })) + } + + start( + key: K, + initial: Result.Initial | Result.Final, + ): Effect.Effect>, never, Scope.Scope | R> { + const self = this + return Effect.gen(function*() { + const [sub, fiber] = yield* Result.unsafeForkEffect( + Effect.onExit(self.f(key), () => Effect.flatMap( + Effect.all([Effect.fiberId, SubscriptionRef.get(self.fiberRef)]), + ([currentFiberId, current]) => Option.match(current, { + onSome: value => Equal.equals(currentFiberId, value.id) + ? SubscriptionRef.set(self.fiberRef, Option.none()) + : Effect.succeed(undefined), + onNone: () => Effect.succeed(undefined), + }), + )), + { initial, initialProgress: self.initialProgress }, + ) + yield* SubscriptionRef.set(self.fiberRef, Option.some(fiber)) + return sub + }) + } + + watch( + key: K, + sub: Subscribable.Subscribable>, + ): Effect.Effect, never, QueryClient.QueryClient> { + return Effect.flatMap(sub.get, initial => Stream.runFoldEffect( + Stream.takeUntil(sub.changes, result => Result.isFinal(result) && !Result.hasFlag(result)), + () => initial, + (_, result) => Effect.as(SubscriptionRef.set(this.resultRef, result), result), + ) as Effect.Effect>).pipe( + Effect.tap(result => SubscriptionRef.set(this.latestFinalResultRef, Option.some(result))), + Effect.tap(result => Result.isSuccess(result) + ? Effect.asVoid(this.setCacheEntry(key, result)) + : Effect.succeed(undefined)), + ) + } + + makeCacheKey(key: K): QueryClient.QueryClientCacheKey { + return new QueryClient.QueryClientCacheKey(key, this.f as (key: Query.AnyKey) => Effect.Effect) + } + + getCacheEntry(key: K): Effect.Effect, never, QueryClient.QueryClient> { + return Effect.flatMap(QueryClient.QueryClient, client => client.getCacheEntry(this.makeCacheKey(key))) + } + + setCacheEntry(key: K, result: Result.Success): Effect.Effect { + return Effect.flatMap(QueryClient.QueryClient, client => client.setCacheEntry(this.makeCacheKey(key), result, this.staleTime)) + } + + get invalidateCache(): Effect.Effect { + return Effect.flatMap( + QueryClient.QueryClient, + client => client.invalidateCacheEntries(this.f as (key: Query.AnyKey) => Effect.Effect), + ).pipe(Effect.provide(this.context)) + } + + invalidateCacheEntry(key: K): Effect.Effect { + return Effect.flatMap( + QueryClient.QueryClient, + client => client.invalidateCacheEntry(this.makeCacheKey(key)), + ).pipe(Effect.provide(this.context)) + } +} + +export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) + +export declare namespace make { + export interface Options { + readonly key: Stream.Stream + readonly f: (key: NoInfer) => Effect.Effect>> + readonly initialProgress?: P + readonly staleTime?: Duration.Input + readonly refreshOnWindowFocus?: boolean + } +} + +export const make = Effect.fnUntraced(function* ( + options: make.Options, +): Effect.fn.Return< + Query, P>, + never, + Scope.Scope | QueryClient.QueryClient | KR | Result.forkEffect.OutputContext +> { + const client = yield* QueryClient.QueryClient + return new QueryImpl, P>( + yield* Effect.context>(), + options.key, + options.f as any, + options.initialProgress as P, + options.staleTime ?? client.defaultStaleTime, + options.refreshOnWindowFocus ?? client.defaultRefreshOnWindowFocus, + yield* SubscriptionRef.make(Option.none()), + yield* SubscriptionRef.make(Option.none>()), + yield* SubscriptionRef.make(Result.initial()), + yield* SubscriptionRef.make(Option.none>()), + yield* Semaphore.make(1), + ) +}) + +export const service = ( + options: make.Options, +): Effect.Effect< + Query, P>, + never, + Scope.Scope | QueryClient.QueryClient | KR | Result.forkEffect.OutputContext +> => Effect.tap(make(options), query => Effect.asVoid(Effect.forkScoped(query.run))) + +const fromSubscriptionRef = (ref: SubscriptionRef.SubscriptionRef): Subscribable.Subscribable => Subscribable.make({ + get: SubscriptionRef.get(ref), + changes: SubscriptionRef.changes(ref), +}) diff --git a/packages/effect-fc-next/src/QueryClient.ts b/packages/effect-fc-next/src/QueryClient.ts new file mode 100644 index 0000000..b811138 --- /dev/null +++ b/packages/effect-fc-next/src/QueryClient.ts @@ -0,0 +1,191 @@ +import { + Context, + DateTime, + Duration, + Effect, + Equal, + Equivalence, + Hash, + HashMap, + Layer, + Option, + Pipeable, + Predicate, + Schedule, + Scope, + Semaphore, + SubscriptionRef, +} from "effect" +import { Subscribable } from "effect-lens" +import type * as Query from "./Query.js" +import type * as Result from "./Result.js" + + +export const QueryClientServiceTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientService") +export type QueryClientServiceTypeId = typeof QueryClientServiceTypeId + +export interface QueryClientService extends Pipeable.Pipeable { + readonly [QueryClientServiceTypeId]: QueryClientServiceTypeId + readonly cache: Subscribable.Subscribable> + readonly cacheGcTime: Duration.Input + readonly defaultStaleTime: Duration.Input + readonly defaultRefreshOnWindowFocus: boolean + readonly run: Effect.Effect + getCacheEntry(key: QueryClientCacheKey): Effect.Effect> + setCacheEntry(key: QueryClientCacheKey, result: Result.Success, staleTime: Duration.Input): Effect.Effect + invalidateCacheEntries(f: (key: Query.Query.AnyKey) => Effect.Effect): Effect.Effect + invalidateCacheEntry(key: QueryClientCacheKey): Effect.Effect +} + +export class QueryClient extends Context.Service()( + "@effect-fc/QueryClient/QueryClient", +) { + static get Default(): Layer.Layer { + return Layer.effect(QueryClient)(service()) + } +} + +export class QueryClientServiceImpl extends Pipeable.Class implements QueryClientService { + readonly [QueryClientServiceTypeId]: QueryClientServiceTypeId = QueryClientServiceTypeId + readonly cache: Subscribable.Subscribable> + + constructor( + readonly cacheRef: SubscriptionRef.SubscriptionRef>, + readonly cacheGcTime: Duration.Input, + readonly defaultStaleTime: Duration.Input, + readonly defaultRefreshOnWindowFocus: boolean, + readonly runSemaphore: Semaphore.Semaphore, + ) { + super() + this.cache = Subscribable.make({ + get: SubscriptionRef.get(cacheRef), + changes: SubscriptionRef.changes(cacheRef), + }) + } + + get run(): Effect.Effect { + return this.runSemaphore.withPermits(1)(Effect.repeat( + Effect.flatMap(DateTime.now, now => SubscriptionRef.update(this.cacheRef, HashMap.filter(entry => + Duration.isLessThan( + DateTime.distance(entry.lastAccessedAt, now), + Duration.sum(Duration.fromInputUnsafe(entry.staleTime), Duration.fromInputUnsafe(this.cacheGcTime)), + ) + ))), + Schedule.spaced("30 seconds"), + )) + } + + getCacheEntry(key: QueryClientCacheKey): Effect.Effect> { + const self = this + return Effect.gen(function*() { + const entry = HashMap.get(yield* SubscriptionRef.get(self.cacheRef), key) + if (Option.isNone(entry)) return Option.none() + const now = yield* DateTime.now + const accessed = new QueryClientCacheEntry( + entry.value.result, + entry.value.staleTime, + entry.value.createdAt, + now, + ) + yield* SubscriptionRef.update(self.cacheRef, HashMap.set(key, accessed)) + return Option.some(accessed) + }) + } + + setCacheEntry( + key: QueryClientCacheKey, + result: Result.Success, + staleTime: Duration.Input, + ): Effect.Effect { + return Effect.flatMap(DateTime.now, now => { + const entry = new QueryClientCacheEntry(result, staleTime, now, now) + return Effect.as(SubscriptionRef.update(this.cacheRef, HashMap.set(key, entry)), entry) + }) + } + + invalidateCacheEntries(f: (key: Query.Query.AnyKey) => Effect.Effect): Effect.Effect { + return SubscriptionRef.update(this.cacheRef, HashMap.filter((_, key) => !Equivalence.strictEqual()(key.f, f))) + } + + invalidateCacheEntry(key: QueryClientCacheKey): Effect.Effect { + return SubscriptionRef.update(this.cacheRef, HashMap.remove(key)) + } +} + +export const isQueryClientService = (u: unknown): u is QueryClientService => Predicate.hasProperty(u, QueryClientServiceTypeId) + +export declare namespace make { + export interface Options { + readonly cacheGcTime?: Duration.Input + readonly defaultStaleTime?: Duration.Input + readonly defaultRefreshOnWindowFocus?: boolean + } +} + +export const make = Effect.fnUntraced(function* (options: make.Options = {}): Effect.fn.Return { + return new QueryClientServiceImpl( + yield* SubscriptionRef.make(HashMap.empty()), + options.cacheGcTime ?? "5 minutes", + options.defaultStaleTime ?? "0 minutes", + options.defaultRefreshOnWindowFocus ?? true, + yield* Semaphore.make(1), + ) +}) + +export declare namespace service { + export interface Options extends make.Options {} +} + +export const service = (options?: service.Options): Effect.Effect => Effect.tap( + make(options), + client => Effect.asVoid(Effect.forkScoped(client.run)), +) + +export const QueryClientCacheKeyTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientCacheKey") +export type QueryClientCacheKeyTypeId = typeof QueryClientCacheKeyTypeId + +export class QueryClientCacheKey extends Pipeable.Class implements Equal.Equal { + readonly [QueryClientCacheKeyTypeId]: QueryClientCacheKeyTypeId = QueryClientCacheKeyTypeId + + constructor( + readonly key: Query.Query.AnyKey, + readonly f: (key: Query.Query.AnyKey) => Effect.Effect, + ) { + super() + } + + [Equal.symbol](that: Equal.Equal): boolean { + return isQueryClientCacheKey(that) + && Equivalence.Array(Equal.asEquivalence())(this.key, that.key) + && Equivalence.strictEqual()(this.f, that.f) + } + + [Hash.symbol](): number { + return Hash.combine(Hash.hash(this.f))(Hash.array(this.key)) + } +} + +export const isQueryClientCacheKey = (u: unknown): u is QueryClientCacheKey => Predicate.hasProperty(u, QueryClientCacheKeyTypeId) + +export const QueryClientCacheEntryTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientCacheEntry") +export type QueryClientCacheEntryTypeId = typeof QueryClientCacheEntryTypeId + +export class QueryClientCacheEntry extends Pipeable.Class { + readonly [QueryClientCacheEntryTypeId]: QueryClientCacheEntryTypeId = QueryClientCacheEntryTypeId + + constructor( + readonly result: Result.Success, + readonly staleTime: Duration.Input, + readonly createdAt: DateTime.DateTime, + readonly lastAccessedAt: DateTime.DateTime, + ) { + super() + } +} + +export const isQueryClientCacheEntry = (u: unknown): u is QueryClientCacheEntry => Predicate.hasProperty(u, QueryClientCacheEntryTypeId) + +export const isQueryClientCacheEntryStale = (self: QueryClientCacheEntry): Effect.Effect => Effect.map( + DateTime.now, + now => Duration.isGreaterThanOrEqualTo(DateTime.distance(self.createdAt, now), Duration.fromInputUnsafe(self.staleTime)), +) diff --git a/packages/effect-fc-next/src/ReactRuntime.ts b/packages/effect-fc-next/src/ReactRuntime.ts new file mode 100644 index 0000000..92f9108 --- /dev/null +++ b/packages/effect-fc-next/src/ReactRuntime.ts @@ -0,0 +1,71 @@ +/** biome-ignore-all lint/complexity/useArrowFunction: React component names are intentional */ +import { Context, Layer, ManagedRuntime, Predicate } from "effect" +import * as React from "react" +import * as ErrorObserver from "./ErrorObserver.js" +import * as QueryClient from "./QueryClient.js" + + +export const TypeId: unique symbol = Symbol.for("@effect-fc/ReactRuntime/ReactRuntime") +export type TypeId = typeof TypeId + +export interface ReactRuntime { + new(_: never): Record + readonly [TypeId]: TypeId + readonly runtime: ManagedRuntime.ManagedRuntime + readonly context: React.Context> +} + +const ReactRuntimeProto = Object.freeze({ [TypeId]: TypeId } as const) + +export const Prelude: Layer.Layer = Layer.merge( + ErrorObserver.layer, + QueryClient.QueryClient.Default, +) + +export const isReactRuntime = (u: unknown): u is ReactRuntime => Predicate.hasProperty(u, TypeId) + +export const make = ( + layer: Layer.Layer, + memoMap?: Layer.MemoMap, +): ReactRuntime => Object.setPrototypeOf( + Object.assign(function() {}, { + runtime: ManagedRuntime.make(Layer.merge(layer, Prelude), { memoMap }), + // biome-ignore lint/style/noNonNullAssertion: initialized by Provider before consumers render + context: React.createContext>(null!), + }), + ReactRuntimeProto, +) + +export namespace Provider { + export interface Props extends React.SuspenseProps { + readonly runtime: ReactRuntime + readonly children?: React.ReactNode + } +} + +export const Provider = ( + { runtime, children, ...suspenseProps }: Provider.Props, +): React.ReactNode => { + const promise = React.useMemo(() => runtime.runtime.context(), [runtime]) + + return React.createElement( + React.Suspense, + suspenseProps, + React.createElement(ProviderInner, { runtime, promise, children }), + ) +} + +const ProviderInner = ( + { runtime, promise, children }: { + readonly runtime: ReactRuntime + readonly promise: Promise> + readonly children?: React.ReactNode + }, +): React.ReactNode => { + const context = React.use(promise) + React.useEffect(() => () => { + void runtime.runtime.dispose() + }, [runtime]) + + return React.createElement(runtime.context, { value: context }, children) +} diff --git a/packages/effect-fc-next/src/Result.ts b/packages/effect-fc-next/src/Result.ts new file mode 100644 index 0000000..672ae18 --- /dev/null +++ b/packages/effect-fc-next/src/Result.ts @@ -0,0 +1,249 @@ +import { Cause, Context, Data, Effect, Equal, Exit, type Fiber, Hash, Layer, Match, Pipeable, Predicate, pipe, type Scope, SubscriptionRef } from "effect" +import { Lens, Subscribable } from "effect-lens" + + +export const ResultTypeId: unique symbol = Symbol.for("@effect-fc/Result/Result") +export type ResultTypeId = typeof ResultTypeId + +export type Result = ( + | Initial + | Running

+ | Final +) + +// biome-ignore lint/complexity/noBannedTypes: "{}" is relevant here +export type Final = (Success | Failure) & ({} | Flags

) +export type Flags

= WillFetch | WillRefresh | Refreshing

+ +export declare namespace Result { + export type Success> = [R] extends [Result] ? A : never + export type Failure> = [R] extends [Result] ? E : never + export type Progress> = [R] extends [Result] ? P : never +} + +export declare namespace Flags { + export type Keys = keyof WillFetch & WillRefresh & Refreshing +} + +export interface Initial extends ResultPrototype { + readonly _tag: "Initial" +} + +export interface Running

extends ResultPrototype { + readonly _tag: "Running" + readonly progress: P +} + +export interface Success extends ResultPrototype { + readonly _tag: "Success" + readonly value: A +} + +export interface Failure extends ResultPrototype { + readonly _tag: "Failure" + readonly cause: Cause.Cause +} + +export interface WillFetch { + readonly _flag: "WillFetch" +} + +export interface WillRefresh { + readonly _flag: "WillRefresh" +} + +export interface Refreshing

{ + readonly _flag: "Refreshing" + readonly progress: P +} + + +export interface ResultPrototype extends Pipeable.Pipeable, Equal.Equal { + readonly [ResultTypeId]: ResultTypeId +} + +export const ResultPrototype: ResultPrototype = Object.freeze({ + ...Pipeable.Prototype, + [ResultTypeId]: ResultTypeId, + + [Equal.symbol](this: Result, that: Result): boolean { + if (this._tag !== that._tag || (this as Flags)._flag !== (that as Flags)._flag) + return false + if (hasRefreshingFlag(this) && !Equal.equals(this.progress, (that as Refreshing).progress)) + return false + return Match.value(this).pipe( + Match.tag("Initial", () => true), + Match.tag("Running", self => Equal.equals(self.progress, (that as Running).progress)), + Match.tag("Success", self => Equal.equals(self.value, (that as Success).value)), + Match.tag("Failure", self => Equal.equals(self.cause, (that as Failure).cause)), + Match.exhaustive, + ) + }, + + [Hash.symbol](this: Result): number { + return pipe(Hash.string(this._tag), + tagHash => Match.value(this).pipe( + Match.tag("Initial", () => tagHash), + Match.tag("Running", self => Hash.combine(Hash.hash(self.progress))(tagHash)), + Match.tag("Success", self => Hash.combine(Hash.hash(self.value))(tagHash)), + Match.tag("Failure", self => Hash.combine(Hash.hash(self.cause))(tagHash)), + Match.exhaustive, + ), + Hash.combine(Hash.hash((this as Flags)._flag)), + hash => hasRefreshingFlag(this) + ? Hash.combine(Hash.hash(this.progress))(hash) + : hash, + ) + }, +} as const) + + +export const isResult = (u: unknown): u is Result => Predicate.hasProperty(u, ResultTypeId) +export const isFinal = (u: unknown): u is Final => isResult(u) && (isSuccess(u) || isFailure(u)) +export const isInitial = (u: unknown): u is Initial => isResult(u) && u._tag === "Initial" +export const isRunning = (u: unknown): u is Running => isResult(u) && u._tag === "Running" +export const isSuccess = (u: unknown): u is Success => isResult(u) && u._tag === "Success" +export const isFailure = (u: unknown): u is Failure => isResult(u) && u._tag === "Failure" +export const hasFlag = (u: unknown): u is Flags => isResult(u) && Predicate.hasProperty(u, "_flag") +export const hasWillFetchFlag = (u: unknown): u is WillFetch => isResult(u) && Predicate.hasProperty(u, "_flag") && u._flag === "WillFetch" +export const hasWillRefreshFlag = (u: unknown): u is WillRefresh => isResult(u) && Predicate.hasProperty(u, "_flag") && u._flag === "WillRefresh" +export const hasRefreshingFlag = (u: unknown): u is Refreshing => isResult(u) && Predicate.hasProperty(u, "_flag") && u._flag === "Refreshing" + +export const initial: { + (): Initial + (): Result +} = (): Initial => Object.setPrototypeOf({ _tag: "Initial" }, ResultPrototype) +export const running =

(progress?: P): Running

=> Object.setPrototypeOf({ _tag: "Running", progress }, ResultPrototype) +export const succeed = (value: A): Success => Object.setPrototypeOf({ _tag: "Success", value }, ResultPrototype) +export const fail = (cause: Cause.Cause ): Failure => Object.setPrototypeOf({ _tag: "Failure", cause }, ResultPrototype) + +export const willFetch = >( + result: R +): Omit & WillFetch => Object.setPrototypeOf( + Object.assign({}, result, { _flag: "WillFetch" }), + Object.getPrototypeOf(result), +) + +export const willRefresh = >( + result: R +): Omit & WillRefresh => Object.setPrototypeOf( + Object.assign({}, result, { _flag: "WillRefresh" }), + Object.getPrototypeOf(result), +) + +export const refreshing = , P = never>( + result: R, + progress?: P, +): Omit & Refreshing

=> Object.setPrototypeOf( + Object.assign({}, result, { _flag: "Refreshing", progress }), + Object.getPrototypeOf(result), +) + +export const fromExit: { + (exit: Exit.Success): Success + (exit: Exit.Failure): Failure + (exit: Exit.Exit): Success | Failure +} = exit => (exit._tag === "Success" ? succeed(exit.value) : fail(exit.cause)) as any + +export const toExit: { + (self: Success): Exit.Success + (self: Failure): Exit.Failure + (self: Final): Exit.Exit + (self: Result): Exit.Exit +} = (self: Result): any => { + switch (self._tag) { + case "Success": + return Exit.succeed(self.value) + case "Failure": + return Exit.failCause(self.cause) + default: + return Exit.fail(new Cause.NoSuchElementError()) + } +} + + +export interface Progress

{ + readonly progress: Lens.Lens +} +export const Progress =

() => Context.Service>("@effect-fc/Result/Progress") + +export class PreviousResultNotRunningNorRefreshing extends Data.TaggedError("@effect-fc/Result/PreviousResultNotRunningNorRefreshing")<{ + readonly previous: Result +}> {} + +export const makeProgressLayer = ( + state: Lens.Lens, never, never, never, never> +): Layer.Layer | Progress, never, never> => Layer.succeed( + Progress

() as Context.Service | Progress, Progress

| Progress>, + { + progress: state.pipe( + Lens.mapEffect( + a => (isRunning(a) || hasRefreshingFlag(a)) + ? Effect.succeed(a) + : Effect.fail(new PreviousResultNotRunningNorRefreshing({ previous: a })), + (_, b) => Effect.succeed(b), + ), + Lens.map( + a => a.progress, + (a, b) => isRunning(a) + ? running(b) + : refreshing(a, b) as Final & Refreshing

, + ), + ) + }, +) + + +export namespace unsafeForkEffect { + export type OutputContext = Exclude | Progress> + + export interface Options { + readonly initial?: Initial | Final + readonly initialProgress?: P + } +} + +export const unsafeForkEffect = Effect.fnUntraced(function* ( + effect: Effect.Effect, + options?: unsafeForkEffect.Options, NoInfer, P>, +): Effect.fn.Return< + readonly [result: Subscribable.Subscribable, never, never>, fiber: Fiber.Fiber], + never, + Scope.Scope | unsafeForkEffect.OutputContext +> { + const state = Lens.fromSubscriptionRef(yield* SubscriptionRef.make>( + options?.initial ?? initial(), + )) + + const fiber = yield* Effect.gen(function*() { + yield* Lens.set( + state, + (isFinal(options?.initial) && hasWillRefreshFlag(options?.initial)) + ? refreshing(options.initial, options?.initialProgress) as Result + : running(options?.initialProgress), + ) + return yield* Effect.onExit(effect, exit => Lens.set(state, fromExit(exit))) + }).pipe( + Effect.forkScoped, + Effect.provide(makeProgressLayer(state)), + ) + + return [state, fiber] as const +}) + +export namespace forkEffect { + export type InputContext = R extends Progress ? [X] extends [P] ? R : never : R + export type OutputContext = unsafeForkEffect.OutputContext + export interface Options extends unsafeForkEffect.Options {} +} + +export const forkEffect: { + ( + effect: Effect.Effect>>, + options?: forkEffect.Options, NoInfer, P>, + ): Effect.Effect< + readonly [result: Subscribable.Subscribable, never, never>, fiber: Fiber.Fiber], + never, + Scope.Scope | forkEffect.OutputContext + > +} = unsafeForkEffect diff --git a/packages/effect-fc-next/src/SetStateAction.ts b/packages/effect-fc-next/src/SetStateAction.ts new file mode 100644 index 0000000..ee5db34 --- /dev/null +++ b/packages/effect-fc-next/src/SetStateAction.ts @@ -0,0 +1,12 @@ +import { Function } from "effect" +import type * as React from "react" + + +export const value: { + (self: React.SetStateAction, prevState: S): S + (prevState: S): (self: React.SetStateAction) => S +} = Function.dual(2, (self: React.SetStateAction, prevState: S): S => + typeof self === "function" + ? (self as (prevState: S) => S)(prevState) + : self +) diff --git a/packages/effect-fc-next/src/Stream.ts b/packages/effect-fc-next/src/Stream.ts new file mode 100644 index 0000000..67bf82e --- /dev/null +++ b/packages/effect-fc-next/src/Stream.ts @@ -0,0 +1,33 @@ +import { Effect, Equivalence, Option, Stream } from "effect" +import * as React from "react" +import * as Component from "./Component.js" + + +export const use: { + ( + stream: Stream.Stream + ): Effect.Effect, never, R> + , E, R>( + stream: Stream.Stream, + initialValue: A, + ): Effect.Effect, never, R> +} = Effect.fnUntraced(function* , E, R>( + stream: Stream.Stream, + initialValue?: A, +) { + const [reactStateValue, setReactStateValue] = React.useState(() => initialValue + ? Option.some(initialValue) + : Option.none() + ) + + yield* Component.useReactEffect(() => Effect.forkScoped( + Stream.runForEach( + Stream.changesWith(stream, Equivalence.strictEqual()), + v => Effect.sync(() => setReactStateValue(Option.some(v))), + ) + ), [stream]) + + return reactStateValue as Option.Some +}) + +export * from "effect/Stream" diff --git a/packages/effect-fc-next/src/SubmittableForm.ts b/packages/effect-fc-next/src/SubmittableForm.ts new file mode 100644 index 0000000..79dfe46 --- /dev/null +++ b/packages/effect-fc-next/src/SubmittableForm.ts @@ -0,0 +1,212 @@ +import { + Array, + Cause, + type Context, + Effect, + Fiber, + Option, + Pipeable, + Predicate, + Schema, + SchemaIssue, + SchemaParser, + type Scope, + Semaphore, + SubscriptionRef, +} from "effect" +import * as Form from "./Form.js" +import * as Lens from "./Lens.js" +import * as Mutation from "./Mutation.js" +import * as Result from "./Result.js" +import * as Subscribable from "./Subscribable.js" + + +type FormSchema = Schema.Top & { + readonly Type: A + readonly Encoded: I + readonly DecodingServices: R +} + +export const SubmittableFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SubmittableForm") +export type SubmittableFormTypeId = typeof SubmittableFormTypeId + +export interface SubmittableForm +extends Form.Form { + readonly [SubmittableFormTypeId]: SubmittableFormTypeId + readonly schema: FormSchema + readonly context: Context.Context + readonly mutation: Mutation.Mutation< + readonly [value: A, form: SubmittableForm], + MA, ME, MR, MP + > + readonly validationFiber: Subscribable.Subscribable>, never, never> + readonly run: Effect.Effect + readonly submit: Effect.Effect>, Cause.NoSuchElementError> +} + +export class SubmittableFormImpl +extends Pipeable.Class implements SubmittableForm { + readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId + readonly [SubmittableFormTypeId]: SubmittableFormTypeId = SubmittableFormTypeId + readonly path = [] as const + readonly encodedValue: Lens.Lens + readonly isValidating: Subscribable.Subscribable + readonly canCommit: Subscribable.Subscribable + readonly isCommitting: Subscribable.Subscribable + + constructor( + readonly schema: FormSchema, + readonly context: Context.Context, + readonly mutation: Mutation.Mutation< + readonly [value: A, form: SubmittableForm], + MA, ME, MR, MP + >, + readonly value: Lens.Lens, never, never, never, never>, + readonly internalEncodedValue: Lens.Lens, + readonly issues: Lens.Lens, + readonly validationFiber: Lens.Lens>, never, never, never, never>, + readonly runSemaphore: Semaphore.Semaphore, + ) { + super() + this.encodedValue = Lens.make({ + get: Lens.get(internalEncodedValue), + changes: internalEncodedValue.changes, + commit: encoded => Effect.andThen( + Lens.set(internalEncodedValue, encoded), + this.synchronizeEncodedValue(encoded), + ), + lock: Lens.asLensImpl(internalEncodedValue).lock, + }) + this.isValidating = Subscribable.map(validationFiber, Option.isSome) + const commitState = Subscribable.zipLatestAll( + value as any, + issues as any, + validationFiber as any, + mutation.result as any, + ) as unknown as Subscribable.Subscribable, + readonly Form.FormIssue[], + Option.Option>, + Result.Result, + ]> + this.canCommit = Subscribable.map( + commitState, + ([current, currentIssues, fiber, result]: readonly [Option.Option, readonly Form.FormIssue[], Option.Option>, Result.Result]) => Option.isSome(current) + && currentIssues.length === 0 + && Option.isNone(fiber) + && !(Result.isRunning(result) || Result.hasRefreshingFlag(result)), + ) + this.isCommitting = Subscribable.map( + mutation.result, + result => Result.isRunning(result) || Result.hasRefreshingFlag(result), + ) + } + + synchronizeEncodedValue(encodedValue: I): Effect.Effect { + const self = this + return Effect.gen(function*() { + const current = yield* Lens.get(self.validationFiber) + if (Option.isSome(current)) yield* Fiber.interrupt(current.value) + const fiber = yield* Effect.forkScoped( + Effect.ensuring( + SchemaParser.decodeEffect(self.schema)(encodedValue), + Lens.set(self.validationFiber, Option.none()), + ), + ) + yield* Lens.set(self.validationFiber, Option.some(fiber)) + const decoded = yield* Fiber.join(fiber).pipe( + Effect.tap(value => Effect.andThen( + Lens.set(self.issues, Array.empty()), + Lens.set(self.value, Option.some(value)), + )), + Effect.catchIf(SchemaIssue.isIssue, issue => Lens.set(self.issues, formatIssue(issue))), + ) + void decoded + }).pipe(Effect.provide(this.context)) as Effect.Effect + } + + get run(): Effect.Effect { + return Effect.flatMap( + Lens.get(this.encodedValue), + SchemaParser.decodeEffect(this.schema), + ).pipe( + Effect.option, + Effect.flatMap(value => Lens.set(this.value, value)), + Effect.provide(this.context), + this.runSemaphore.withPermits(1), + ) + } + + get submit(): Effect.Effect>, Cause.NoSuchElementError> { + return Effect.flatMap(Lens.get(this.value), value => Effect.flatMap(Effect.fromOption(value), decoded => this.submitValue(decoded))) + } + + submitValue(value: A): Effect.Effect>> { + return Effect.flatMap(this.canCommit.get, canCommit => { + if (!canCommit) return Effect.succeed(Option.none()) + return Effect.map( + Effect.tap(this.mutation.mutate([value, this as any]), result => { + if (!Result.isFailure(result)) return Effect.succeed(undefined) + const issue = Cause.findErrorOption(result.cause) + return Option.isSome(issue) && SchemaIssue.isIssue(issue.value) + ? Lens.set(this.issues, formatIssue(issue.value)) + : Effect.succeed(undefined) + }), + Option.some, + ) + }) + } +} + +const formatIssue = (issue: SchemaIssue.Issue): readonly Form.FormIssue[] => { + const formatted = SchemaIssue.makeFormatterStandardSchemaV1()(issue) + return formatted.issues.map(item => ({ + path: (item.path ?? []) as readonly PropertyKey[], + message: item.message, + })) +} + +export const isSubmittableForm = (u: unknown): u is SubmittableForm => Predicate.hasProperty(u, SubmittableFormTypeId) + +export declare namespace make { + export interface Options + extends Mutation.make.Options< + readonly [value: NoInfer, form: SubmittableForm, NoInfer, NoInfer, unknown, unknown, unknown>], + MA, ME, MR, MP + > { + readonly schema: FormSchema + readonly initialEncodedValue: NoInfer + } +} + +export const make = Effect.fnUntraced(function* ( + options: make.Options, +): Effect.fn.Return< + SubmittableForm, MP>, + never, + Scope.Scope | R | Result.forkEffect.OutputContext +> { + return new SubmittableFormImpl( + options.schema, + yield* Effect.context(), + yield* Mutation.make(options), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(options.initialEncodedValue)), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Array.empty())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), + yield* Semaphore.make(1), + ) +}) + +export declare namespace service { + export interface Options + extends make.Options {} +} + +export const service = ( + options: service.Options, +): Effect.Effect< + SubmittableForm, MP>, + never, + Scope.Scope | R | Result.forkEffect.OutputContext +> => Effect.tap(make(options), form => Effect.asVoid(Effect.forkScoped(form.run))) diff --git a/packages/effect-fc-next/src/Subscribable.ts b/packages/effect-fc-next/src/Subscribable.ts new file mode 100644 index 0000000..e8fafe6 --- /dev/null +++ b/packages/effect-fc-next/src/Subscribable.ts @@ -0,0 +1,53 @@ +import { Effect, Equivalence, Stream } from "effect" +import { Subscribable } from "effect-lens" +import * as React from "react" +import * as Component from "./Component.js" + + +export * from "effect-lens/Subscribable" + +export const zipLatestAll = []>( + ...elements: T +): Subscribable.Subscribable< + [T[number]] extends [never] + ? never + : { [K in keyof T]: T[K] extends Subscribable.Subscribable ? A : never }, + [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? E : never, + [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? R : never +> => Subscribable.make({ + get: Effect.all(elements.map(v => v.get)), + changes: Stream.zipLatestAll(...elements.map(v => v.changes)), +}) as any + +export declare namespace useAll { + export type Success[]> = [T[number]] extends [never] + ? never + : { [K in keyof T]: T[K] extends Subscribable.Subscribable ? A : never } + + export interface Options { + readonly equivalence?: Equivalence.Equivalence + } +} + +export const useAll = Effect.fnUntraced(function* []>( + elements: T, + options?: useAll.Options>>, +): Effect.fn.Return< + useAll.Success, + [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? E : never, + [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? R : never +> { + const [reactStateValue, setReactStateValue] = React.useState( + yield* Component.useOnMount(() => Effect.all(elements.map(v => v.get))) + ) + + yield* Component.useReactEffect(() => Stream.zipLatestAll(...elements.map(ref => ref.changes)).pipe( + Stream.changesWith((options?.equivalence as Equivalence.Equivalence | undefined) ?? Equivalence.Array(Equivalence.strictEqual())), + Stream.runForEach(v => + Effect.sync(() => setReactStateValue(v)) + ), + Effect.forkScoped, + ), elements) + + return reactStateValue as any +}) diff --git a/packages/effect-fc-next/src/SynchronizedForm.ts b/packages/effect-fc-next/src/SynchronizedForm.ts new file mode 100644 index 0000000..330628a --- /dev/null +++ b/packages/effect-fc-next/src/SynchronizedForm.ts @@ -0,0 +1,204 @@ +import { + Array, + type Context, + Effect, + Equal, + Fiber, + Option, + Pipeable, + Predicate, + Schema, + SchemaIssue, + SchemaParser, + type Scope, + Semaphore, + Stream, + SubscriptionRef, +} from "effect" +import * as Form from "./Form.js" +import * as Lens from "./Lens.js" +import * as Subscribable from "./Subscribable.js" + + +type FormSchema = Schema.Top & { + readonly Type: A + readonly Encoded: I + readonly DecodingServices: R + readonly EncodingServices: R +} + +export const SynchronizedFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SynchronizedForm") +export type SynchronizedFormTypeId = typeof SynchronizedFormTypeId + +export interface SynchronizedForm< + in out A, + in out I = A, + in out R = never, + in out TER = never, + in out TEW = never, + in out TRR = never, + in out TRW = never, +> extends Form.Form { + readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId + readonly schema: FormSchema + readonly context: Context.Context + readonly target: Lens.Lens + readonly validationFiber: Subscribable.Subscribable>, never, never> + readonly run: Effect.Effect +} + +export class SynchronizedFormImpl< + in out A, + in out I = A, + in out R = never, + in out TER = never, + in out TEW = never, + in out TRR = never, + in out TRW = never, +> extends Pipeable.Class implements SynchronizedForm { + readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId + readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId = SynchronizedFormTypeId + readonly path = [] as const + readonly value: Subscribable.Subscribable, TER, never> + readonly encodedValue: Lens.Lens + readonly isValidating: Subscribable.Subscribable + readonly canCommit: Subscribable.Subscribable + + constructor( + readonly schema: FormSchema, + readonly context: Context.Context, + readonly target: Lens.Lens, + readonly internalEncodedValue: Lens.Lens, + readonly issues: Lens.Lens, + readonly validationFiber: Lens.Lens>, never, never, never, never>, + readonly isCommitting: Lens.Lens, + readonly runSemaphore: Semaphore.Semaphore, + ) { + super() + this.value = Subscribable.make({ + get: Effect.provide(Effect.map(target.get, Option.some), context), + changes: Stream.provideContext( + target.changes.pipe( + Stream.map(Option.some), + Stream.catchCause(() => Stream.make(Option.none())), + ), + context, + ), + }) + this.encodedValue = Lens.make({ + get: Lens.get(internalEncodedValue), + changes: internalEncodedValue.changes, + commit: encoded => Effect.andThen( + Lens.set(internalEncodedValue, encoded), + this.synchronizeEncodedValue(encoded), + ), + lock: Lens.asLensImpl(internalEncodedValue).lock, + }) as unknown as Lens.Lens + this.isValidating = Subscribable.map(validationFiber, Option.isSome) + const commitState = Subscribable.zipLatestAll(issues as any, validationFiber as any, isCommitting as any) as unknown as Subscribable.Subscribable>, + boolean, + ]> + this.canCommit = Subscribable.map( + commitState, + ([currentIssues, fiber, committing]) => currentIssues.length === 0 && Option.isNone(fiber) && !committing, + ) + } + + synchronizeEncodedValue(encodedValue: I): Effect.Effect { + const self = this + return Effect.gen(function*() { + const current = yield* Lens.get(self.validationFiber) + if (Option.isSome(current)) yield* Fiber.interrupt(current.value) + const fiber = yield* Effect.forkScoped( + Effect.ensuring( + SchemaParser.decodeEffect(self.schema)(encodedValue), + Lens.set(self.validationFiber, Option.none()), + ), + ) + yield* Lens.set(self.validationFiber, Option.some(fiber)) + yield* Fiber.join(fiber).pipe( + Effect.flatMap(value => Effect.ensuring( + Effect.andThen( + Lens.set(self.isCommitting, true), + Effect.andThen(Lens.set(self.issues, Array.empty()), Lens.set(self.target, value)), + ), + Lens.set(self.isCommitting, false), + )), + Effect.catchIf(SchemaIssue.isIssue, issue => Lens.set(self.issues, formatIssue(issue))), + ) + }).pipe(Effect.provide(this.context)) as Effect.Effect + } + + get run(): Effect.Effect { + return this.runSemaphore.withPermits(1)(Effect.provide( + Stream.runForEach(Stream.drop(this.target.changes, 1), targetValue => Effect.ignore( + Effect.flatMap(SchemaParser.encodeEffect(this.schema)(targetValue), encodedValue => Effect.flatMap( + Lens.get(this.internalEncodedValue), + current => Equal.equals(encodedValue, current) + ? Effect.succeed(undefined) + : Effect.andThen( + Lens.set(this.issues, Array.empty()), + Lens.set(this.internalEncodedValue, encodedValue), + ), + )), + )), + this.context, + )) + } +} + +const formatIssue = (issue: SchemaIssue.Issue): readonly Form.FormIssue[] => { + const formatted = SchemaIssue.makeFormatterStandardSchemaV1()(issue) + return formatted.issues.map(item => ({ + path: (item.path ?? []) as readonly PropertyKey[], + message: item.message, + })) +} + +export const isSynchronizedForm = (u: unknown): u is SynchronizedForm => Predicate.hasProperty(u, SynchronizedFormTypeId) + +export declare namespace make { + export interface Options { + readonly schema: FormSchema + readonly target: Lens.Lens + readonly initialEncodedValue?: NoInfer + } +} + +export const make = Effect.fnUntraced(function* ( + options: make.Options, +): Effect.fn.Return< + SynchronizedForm, + SchemaIssue.Issue | TER, + Scope.Scope | R | TRR | TRW +> { + const initialEncodedValue = options.initialEncodedValue !== undefined + ? options.initialEncodedValue + : yield* Effect.flatMap(Lens.get(options.target), SchemaParser.encodeEffect(options.schema)) + + return new SynchronizedFormImpl( + options.schema, + yield* Effect.context(), + options.target, + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(initialEncodedValue)), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Array.empty())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(false)), + yield* Semaphore.make(1), + ) +}) + +export declare namespace service { + export interface Options + extends make.Options {} +} + +export const service = ( + options: service.Options, +): Effect.Effect< + SynchronizedForm, + SchemaIssue.Issue | TER, + Scope.Scope | R | TRR | TRW +> => Effect.tap(make(options), form => Effect.asVoid(Effect.forkScoped(form.run))) diff --git a/packages/effect-fc-next/src/index.ts b/packages/effect-fc-next/src/index.ts new file mode 100644 index 0000000..8829e81 --- /dev/null +++ b/packages/effect-fc-next/src/index.ts @@ -0,0 +1,17 @@ +export * as Async from "./Async.js" +export * as Component from "./Component.js" +export * as ErrorObserver from "./ErrorObserver.js" +export * as Form from "./Form.js" +export * as Lens from "./Lens.js" +export * as Memoized from "./Memoized.js" +export * as Mutation from "./Mutation.js" +export * as PubSub from "./PubSub.js" +export * as Query from "./Query.js" +export * as QueryClient from "./QueryClient.js" +export * as ReactRuntime from "./ReactRuntime.js" +export * as Result from "./Result.js" +export * as SetStateAction from "./SetStateAction.js" +export * as Stream from "./Stream.js" +export * as SubmittableForm from "./SubmittableForm.js" +export * as Subscribable from "./Subscribable.js" +export * as SynchronizedForm from "./SynchronizedForm.js" diff --git a/packages/effect-fc-next/src/utils.ts b/packages/effect-fc-next/src/utils.ts new file mode 100644 index 0000000..44ed408 --- /dev/null +++ b/packages/effect-fc-next/src/utils.ts @@ -0,0 +1,3 @@ +export type ExcludeKeys = K extends keyof T ? ( + { [P in K]?: never } & Omit +) : T diff --git a/packages/effect-fc-next/test/Component.test.tsx b/packages/effect-fc-next/test/Component.test.tsx new file mode 100644 index 0000000..9401608 --- /dev/null +++ b/packages/effect-fc-next/test/Component.test.tsx @@ -0,0 +1,354 @@ +import { render, screen, waitFor } from "@testing-library/react" +import { Context, Effect, Layer } from "effect" +import * as React from "react" +import { afterEach, describe, expect, it, vi } from "vitest" +import * as Component from "../src/Component.js" +import * as ReactRuntime from "../src/ReactRuntime.js" + + +class ValueService extends Context.Service()("ValueService") {} + +afterEach(() => { + vi.useRealTimers() +}) + +describe("Component", () => { + it("runs useOnMount only once across rerenders", async () => { + const onMount = vi.fn(() => Effect.succeed("mounted")) + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await runtime.runtime.context() + + const Probe = Component.makeUntraced("UseOnMountProbe")(function*() { + const value = yield* Component.useOnMount(onMount) + return

+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("mounted") + expect(onMount).toHaveBeenCalledTimes(1) + + view.rerender( + + + + ) + expect(await screen.findByText("mounted")).toBeTruthy() + expect(onMount).toHaveBeenCalledTimes(1) + + view.unmount() + await runtime.runtime.dispose() + }) + + it("recomputes useOnChange only when dependencies change", async () => { + const onChange = vi.fn((value: number) => Effect.succeed(`value:${value}`)) + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await runtime.runtime.context() + + const Probe = Component.makeUntraced("UseOnChangeProbe")(function*(props: { readonly value: number }) { + const result = yield* Component.useOnChange(() => onChange(props.value), [props.value], { + finalizerExecutionDebounce: 0, + }) + + return
{result}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("value:1") + expect(onChange).toHaveBeenCalledTimes(1) + + view.rerender( + + + + ) + + expect(await screen.findByText("value:1")).toBeTruthy() + expect(onChange).toHaveBeenCalledTimes(1) + + view.rerender( + + + + ) + + await screen.findByText("value:2") + expect(onChange).toHaveBeenCalledTimes(2) + + view.unmount() + await runtime.runtime.dispose() + }) + + it("closes the previous scope on dependency changes and unmount", async () => { + const cleanup = vi.fn() + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await runtime.runtime.context() + + const Probe = Component.makeUntraced("ScopeCleanupProbe")(function*(props: { readonly value: string }) { + const result = yield* Component.useOnChange( + () => Effect.gen(function*() { + yield* Effect.addFinalizer(() => Effect.sync(() => cleanup(props.value))) + return props.value + }), + [props.value], + { finalizerExecutionDebounce: 0 }, + ) + + return
{result}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + expect(cleanup).not.toHaveBeenCalled() + + view.rerender( + + + + ) + + await screen.findByText("second") + await waitFor(() => expect(cleanup).toHaveBeenCalledWith("first")) + expect(cleanup).toHaveBeenCalledTimes(1) + + view.unmount() + + await waitFor(() => expect(cleanup).toHaveBeenCalledWith("second")) + expect(cleanup).toHaveBeenCalledTimes(2) + await runtime.runtime.dispose() + }) + + it("runs useReactEffect setup and cleanup when dependencies change", async () => { + const lifecycle = vi.fn<(message: string) => void>() + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await runtime.runtime.context() + + const Probe = Component.makeUntraced("UseReactEffectProbe")(function*(props: { readonly value: string }) { + yield* Component.useReactEffect(() => + Effect.gen(function*() { + yield* Effect.sync(() => lifecycle(`mount:${props.value}`)) + yield* Effect.addFinalizer(() => Effect.sync(() => lifecycle(`cleanup:${props.value}`))) + }), + [props.value]) + + return
{props.value}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + await waitFor(() => expect(lifecycle).toHaveBeenCalledWith("mount:first")) + + view.rerender( + + + + ) + + await screen.findByText("second") + await waitFor(() => expect(lifecycle).toHaveBeenCalledWith("cleanup:first")) + await waitFor(() => expect(lifecycle).toHaveBeenCalledWith("mount:second")) + + view.unmount() + + await waitFor(() => expect(lifecycle).toHaveBeenCalledWith("cleanup:second")) + expect(lifecycle.mock.calls.map(([message]) => message)).toEqual([ + "mount:first", + "cleanup:first", + "mount:second", + "cleanup:second", + ]) + await runtime.runtime.dispose() + }) + + it("keeps useCallbackSync stable until dependencies change", async () => { + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await runtime.runtime.context() + const seenCallbacks: Array<(value: number) => string> = [] + + const Probe = Component.makeUntraced("UseCallbackSyncProbe")(function*(props: { readonly prefix: string }) { + const callback = yield* Component.useCallbackSync( + (value: number) => Effect.succeed(`${props.prefix}:${value}`), + [props.prefix], + ) + + yield* Component.useOnMount(() => Effect.sync(() => { + seenCallbacks.push(callback) + })) + + React.useEffect(() => { + seenCallbacks.push(callback) + }, [callback]) + + return
{callback(1)}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("a:1") + expect(seenCallbacks).toHaveLength(2) + expect(seenCallbacks[0]).toBe(seenCallbacks[1]) + expect(seenCallbacks[0]?.(2)).toBe("a:2") + + view.rerender( + + + + ) + + await screen.findByText("a:1") + expect(seenCallbacks).toHaveLength(2) + + view.rerender( + + + + ) + + await screen.findByText("b:1") + await waitFor(() => expect(seenCallbacks).toHaveLength(3)) + expect(seenCallbacks[2]).not.toBe(seenCallbacks[1]) + expect(seenCallbacks[2]?.(2)).toBe("b:2") + + view.unmount() + await runtime.runtime.dispose() + }) + + it("delays cleanup according to finalizerExecutionDebounce", async () => { + const cleanup = vi.fn() + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await runtime.runtime.context() + + const Probe = Component.makeUntraced("DebouncedCleanupProbe")(function*(props: { readonly value: string }) { + const result = yield* Component.useOnChange( + () => Effect.gen(function*() { + yield* Effect.addFinalizer(() => Effect.sync(() => cleanup(props.value))) + return props.value + }), + [props.value], + { finalizerExecutionDebounce: "20 millis" }, + ) + + return
{result}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + + view.rerender( + + + + ) + + await screen.findByText("second") + expect(cleanup).not.toHaveBeenCalled() + + await new Promise(resolve => setTimeout(resolve, 5)) + expect(cleanup).not.toHaveBeenCalled() + + await waitFor(() => expect(cleanup).toHaveBeenCalledWith("first"), { timeout: 100 }) + + view.unmount() + await waitFor(() => expect(cleanup).toHaveBeenCalledWith("second"), { timeout: 100 }) + await runtime.runtime.dispose() + }) + + it("does not remount a component when only nonReactiveTags change", async () => { + const mounts = vi.fn() + const unmounts = vi.fn() + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await runtime.runtime.context() + + const SubComponent = Component.makeUntraced("NonReactiveSubComponent")(function*() { + const service = yield* ValueService + + yield* Component.useOnMount(() => Effect.gen(function*() { + yield* Effect.sync(() => mounts()) + yield* Effect.addFinalizer(() => Effect.sync(() => unmounts())) + })) + + return
{service.value}
+ }).pipe( + Component.withOptions({ nonReactiveTags: [ValueService] }) + ) + + const Parent = Component.makeUntraced("NonReactiveParent")(function*(props: { readonly value: string }) { + const serviceLayer = React.useMemo( + () => Layer.succeed(ValueService, { value: props.value }), + [props.value], + ) + const context = yield* Component.useContextFromLayer(serviceLayer, { + finalizerExecutionDebounce: 0, + }) + const Child = yield* Effect.provide(SubComponent.use, context) + + return + }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + expect(mounts).toHaveBeenCalledTimes(1) + expect(unmounts).not.toHaveBeenCalled() + + view.rerender( + + + + ) + + await screen.findByText("second") + expect(mounts).toHaveBeenCalledTimes(1) + expect(unmounts).not.toHaveBeenCalled() + + view.unmount() + await waitFor(() => expect(unmounts).toHaveBeenCalledTimes(1)) + await runtime.runtime.dispose() + }) +}) diff --git a/packages/effect-fc-next/test/Lens.test.tsx b/packages/effect-fc-next/test/Lens.test.tsx new file mode 100644 index 0000000..3407f14 --- /dev/null +++ b/packages/effect-fc-next/test/Lens.test.tsx @@ -0,0 +1,165 @@ +import { fireEvent, render, screen, waitFor } from "@testing-library/react" +import { Effect, Layer, SubscriptionRef } from "effect" +import * as React from "react" +import { describe, expect, it } from "vitest" +import * as Component from "../src/Component.js" +import * as Lens from "../src/Lens.js" +import * as ReactRuntime from "../src/ReactRuntime.js" + + +const makeRuntime = async () => { + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await runtime.runtime.context() + + return { + runtime, + effectRuntime, + dispose: () => runtime.runtime.dispose(), + } +} + +describe("Lens", () => { + it("useState stays in sync with lens updates in both directions", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + const ref = await Effect.runPromise(SubscriptionRef.make(0)) + const lens = Lens.fromSubscriptionRef(ref) + + const Probe = Component.makeUntraced("LensUseStateProbe")(function*() { + const [value, setValue] = yield* Lens.useState(lens) + + return ( + <> +
{value}
+ + + ) + }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("0") + + await Effect.runPromise(Lens.set(lens, 5)) + await screen.findByText("5") + + fireEvent.click(screen.getByRole("button", { name: "increment" })) + await screen.findByText("6") + expect(await Effect.runPromise(Lens.get(lens))).toBe(6) + + view.unmount() + await dispose() + }) + + it("useState respects the provided equivalence when subscribing to lens changes", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + const ref = await Effect.runPromise(SubscriptionRef.make({ id: 1, label: "first" })) + const lens = Lens.fromSubscriptionRef(ref) + + const Probe = Component.makeUntraced("LensUseStateEquivalenceProbe")(function*() { + const [value] = yield* Lens.useState(lens, { + equivalence: (self, that) => self.id === that.id, + }) + + return
{value.label}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + + await Effect.runPromise(Lens.set(lens, { id: 1, label: "ignored" })) + await waitFor(() => expect(screen.getByText("first")).toBeTruthy()) + expect(screen.queryByText("ignored")).toBeNull() + + await Effect.runPromise(Lens.set(lens, { id: 2, label: "updated" })) + await screen.findByText("updated") + + view.unmount() + await dispose() + }) + + it("useFromReactState writes React state changes into the returned lens", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + let lens: Lens.Lens | undefined + + const Probe = Component.makeUntraced("LensUseFromReactStateProbe")(function*() { + const [value, setValue] = React.useState("hello") + const reactLens = yield* Lens.useFromReactState([value, setValue]) + + yield* Component.useOnMount(() => Effect.sync(() => { + lens = reactLens + })) + + return + }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("hello") + await waitFor(() => expect(lens).toBeDefined()) + + fireEvent.click(screen.getByRole("button", { name: "hello" })) + await screen.findByText("hello!") + await waitFor(async () => expect(await Effect.runPromise(Lens.get(lens!))).toBe("hello!")) + + view.unmount() + await dispose() + }) + + it("useFromReactState respects equivalence when lens updates flow back into React state", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + let lens: Lens.Lens<{ readonly id: number; readonly label: string }, never, never, never, never> | undefined + + const Probe = Component.makeUntraced("LensUseFromReactStateEquivalenceProbe")(function*() { + const [value, setValue] = React.useState({ id: 1, label: "first" }) + const reactLens = yield* Lens.useFromReactState([value, setValue], { + equivalence: (self, that) => self.id === that.id, + }) + + yield* Component.useOnMount(() => Effect.sync(() => { + lens = reactLens + })) + + return
{value.label}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first") + await waitFor(() => expect(lens).toBeDefined()) + + await Effect.runPromise(Lens.set(lens!, { id: 1, label: "ignored" })) + await waitFor(() => expect(screen.getByText("first")).toBeTruthy()) + expect(screen.queryByText("ignored")).toBeNull() + + await Effect.runPromise(Lens.set(lens!, { id: 2, label: "updated" })) + await screen.findByText("updated") + + view.unmount() + await dispose() + }) +}) diff --git a/packages/effect-fc-next/test/Query.test.ts b/packages/effect-fc-next/test/Query.test.ts new file mode 100644 index 0000000..ee6544f --- /dev/null +++ b/packages/effect-fc-next/test/Query.test.ts @@ -0,0 +1,169 @@ +import { Effect, Option, type Scope, Stream } from "effect" +import { describe, expect, it } from "vitest" +import * as Query from "../src/Query.js" +import * as QueryClient from "../src/QueryClient.js" +import * as Result from "../src/Result.js" + + +const runQueryTest = (effect: Effect.Effect) => + Effect.runPromise(Effect.scoped(effect.pipe( + Effect.provide(QueryClient.QueryClient.Default), + ))) + +const expectSuccessValue = ( + result: Result.Result, +): A => { + expect(Result.isSuccess(result)).toBe(true) + + if (!Result.isSuccess(result)) + throw new Error(`Expected Success result, received ${result._tag}`) + + return result.value +} + +const expectSomeValue =
(option: Option.Option): A => { + expect(Option.isSome(option)).toBe(true) + + if (!Option.isSome(option)) + throw new Error("Expected Some option, received None") + + return option.value +} + +describe("Query", () => { + it("fetch caches successful results until they are invalidated or stale", async () => { + let calls = 0 + const key = Stream.empty as Stream.Stream + + const result = await runQueryTest(Effect.gen(function*() { + const query = yield* Query.make({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "1 minute", + }) + + const first = yield* query.fetch([1]) + const second = yield* query.fetch([1]) + + return [first, second] as const + })) + + expect(calls).toBe(1) + expect(result[0]._tag).toBe("Success") + expect(result[1]._tag).toBe("Success") + expect(expectSuccessValue(result[0])).toBe("value:1:1") + expect(expectSuccessValue(result[1])).toBe("value:1:1") + }) + + it("refresh reruns the latest query key", async () => { + let calls = 0 + const key = Stream.empty as Stream.Stream + + const result = await runQueryTest(Effect.gen(function*() { + const query = yield* Query.make({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "0 millis", + }) + + const first = yield* query.fetch([1]) + yield* Effect.sleep("1 millis") + const refreshed = yield* query.refresh + + return [first, refreshed] as const + })) + + expect(calls).toBe(2) + expect(expectSuccessValue(result[0])).toBe("value:1:1") + expect(expectSuccessValue(result[1])).toBe("value:1:2") + }) + + it("invalidateCacheEntry forces the next fetch for that key to rerun", async () => { + let calls = 0 + const key = Stream.empty as Stream.Stream + + const result = await runQueryTest(Effect.gen(function*() { + const query = yield* Query.make({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "1 minute", + }) + + const first = yield* query.fetch([1]) + yield* query.invalidateCacheEntry([1]) + const second = yield* query.fetch([1]) + + return [first, second] as const + })) + + expect(calls).toBe(2) + expect(expectSuccessValue(result[0])).toBe("value:1:1") + expect(expectSuccessValue(result[1])).toBe("value:1:2") + }) + + it("invalidateCache clears cached entries for the query function", async () => { + let calls = 0 + const key = Stream.empty as Stream.Stream + + const result = await runQueryTest(Effect.gen(function*() { + const query = yield* Query.make({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "1 minute", + }) + + const first = yield* query.fetch([1]) + yield* query.invalidateCache + const second = yield* query.fetch([1]) + + return [first, second] as const + })) + + expect(calls).toBe(2) + expect(expectSuccessValue(result[0])).toBe("value:1:1") + expect(expectSuccessValue(result[1])).toBe("value:1:2") + }) + + it("service starts the key stream automatically and updates latest state", async () => { + let calls = 0 + const key = Stream.make([1] as const) as Stream.Stream + + const effect = Effect.gen(function*() { + const query = yield* Query.service({ + key, + f: ([id]: readonly [number]) => Effect.sync(() => { + calls += 1 + return `value:${id}:${calls}` + }), + staleTime: "1 minute", + }) + + yield* Effect.sleep("10 millis") + + return { + final: yield* query.result.get, + latestKey: yield* query.latestKey.get, + latestFinalResult: yield* query.latestFinalResult.get, + } + }) + + const result = await runQueryTest(effect) + + expect(calls).toBe(1) + expect(expectSuccessValue(result.final)).toBe("value:1:1") + expect(expectSomeValue(result.latestKey)).toEqual([1]) + expect(expectSuccessValue(expectSomeValue(result.latestFinalResult))).toBe("value:1:1") + }) +}) diff --git a/packages/effect-fc-next/test/Subscribable.test.tsx b/packages/effect-fc-next/test/Subscribable.test.tsx new file mode 100644 index 0000000..5641d1b --- /dev/null +++ b/packages/effect-fc-next/test/Subscribable.test.tsx @@ -0,0 +1,129 @@ +import { render, screen, waitFor } from "@testing-library/react" +import { Effect, Fiber, Layer, Stream, SubscriptionRef } from "effect" +import { Lens } from "effect-lens" +import { describe, expect, it } from "vitest" +import * as Component from "../src/Component.js" +import * as ReactRuntime from "../src/ReactRuntime.js" +import * as Subscribable from "../src/Subscribable.js" + + +const makeRuntime = async () => { + const runtime = ReactRuntime.make(Layer.empty) + const effectRuntime = await runtime.runtime.context() + + return { + runtime, + effectRuntime, + dispose: () => runtime.runtime.dispose(), + } +} + +describe("Subscribable", () => { + it("zipLatestAll reads current values from all inputs", async () => { + const leftRef = await Effect.runPromise(SubscriptionRef.make(1)) + const rightRef = await Effect.runPromise(SubscriptionRef.make("a")) + const left = Lens.fromSubscriptionRef(leftRef) + const right = Lens.fromSubscriptionRef(rightRef) + + const zipped = Subscribable.zipLatestAll(left, right) + + expect(await Effect.runPromise(zipped.get)).toEqual([1, "a"]) + }) + + it("zipLatestAll emits updates when any input changes", async () => { + const leftRef = await Effect.runPromise(SubscriptionRef.make(1)) + const rightRef = await Effect.runPromise(SubscriptionRef.make("a")) + const left = Lens.fromSubscriptionRef(leftRef) + const right = Lens.fromSubscriptionRef(rightRef) + + const zipped = Subscribable.zipLatestAll(left, right) + const values: Array = [] + + const collector = Effect.runFork(Effect.scoped(zipped.changes.pipe( + Stream.runForEach(value => Effect.sync(() => { + values.push(value as readonly [number, string]) + })), + ))) + + await Effect.runPromise(Lens.set(left, 2)) + await waitFor(() => expect(values).toContainEqual([2, "a"])) + + await Effect.runPromise(Lens.set(right, "b")) + await waitFor(() => expect(values).toContainEqual([2, "b"])) + + await Effect.runPromise(Fiber.interrupt(collector)) + }) + + it("useAll returns the latest values and rerenders when any input changes", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + const countRef = await Effect.runPromise(SubscriptionRef.make(1)) + const labelRef = await Effect.runPromise(SubscriptionRef.make("a")) + const count = Lens.fromSubscriptionRef(countRef) + const label = Lens.fromSubscriptionRef(labelRef) + + const Probe = Component.makeUntraced("SubscribableUseAllProbe")(function*() { + const [currentCount, currentLabel] = yield* Subscribable.useAll([count, label]) + + return
{`${currentCount}:${currentLabel}`}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("1:a") + + await Effect.runPromise(Lens.set(count, 2)) + await screen.findByText("2:a") + + await Effect.runPromise(Lens.set(label, "b")) + await screen.findByText("2:b") + + view.unmount() + await dispose() + }) + + it("useAll respects the provided equivalence when processing updates", async () => { + const { runtime, effectRuntime, dispose } = await makeRuntime() + const itemRef = await Effect.runPromise(SubscriptionRef.make({ id: 1, label: "first" })) + const flagRef = await Effect.runPromise(SubscriptionRef.make(true)) + const item = Lens.fromSubscriptionRef(itemRef) + const flag = Lens.fromSubscriptionRef(flagRef) + + const Probe = Component.makeUntraced("SubscribableUseAllEquivalenceProbe")(function*() { + const [currentItem, currentFlag] = yield* Subscribable.useAll([item, flag], { + equivalence: ([selfItem, selfFlag], [thatItem, thatFlag]) => + selfItem.id === thatItem.id && selfFlag === thatFlag, + }) + + return
{`${currentItem.label}:${currentFlag ? "on" : "off"}`}
+ }).pipe( + Component.withRuntime(runtime.context) + ) + + const view = render( + + + + ) + + await screen.findByText("first:on") + + await Effect.runPromise(Lens.set(item, { id: 1, label: "ignored" })) + await waitFor(() => expect(screen.getByText("first:on")).toBeTruthy()) + expect(screen.queryByText("ignored:on")).toBeNull() + + await Effect.runPromise(Lens.set(flag, false)) + await screen.findByText("ignored:off") + + await Effect.runPromise(Lens.set(item, { id: 2, label: "updated" })) + await screen.findByText("updated:off") + + view.unmount() + await dispose() + }) +}) diff --git a/packages/effect-fc-next/tsconfig.json b/packages/effect-fc-next/tsconfig.json new file mode 100644 index 0000000..6ad0810 --- /dev/null +++ b/packages/effect-fc-next/tsconfig.json @@ -0,0 +1,40 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "NodeNext", + "moduleDetection": "force", + "jsx": "react-jsx", + // "allowJs": true, + + // Bundler mode + "moduleResolution": "NodeNext", + // "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + // "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false, + + // Build + "rootDir": "./src", + "outDir": "./dist", + "declaration": true, + "sourceMap": true, + + "plugins": [ + { "name": "@effect/language-service" } + ] + }, + + "include": ["./src"], + "exclude": ["**/*.test.ts", "**/*.spec.ts"] +} diff --git a/packages/effect-fc-next/vitest.config.ts b/packages/effect-fc-next/vitest.config.ts new file mode 100644 index 0000000..cec0e39 --- /dev/null +++ b/packages/effect-fc-next/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config" + + +export default defineConfig({ + test: { + environment: "jsdom", + include: ["test/**/*.test.ts?(x)"], + }, +}) diff --git a/packages/example-next/.gitignore b/packages/example-next/.gitignore new file mode 100644 index 0000000..a014dba --- /dev/null +++ b/packages/example-next/.gitignore @@ -0,0 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +.tanstack diff --git a/packages/example-next/README.md b/packages/example-next/README.md new file mode 100644 index 0000000..aef5174 --- /dev/null +++ b/packages/example-next/README.md @@ -0,0 +1,10 @@ +# Effect FC Next Example + +Minimal React example for `effect-fc-next`, Effect V4, and `effect-lens@2`. + +```bash +bun run dev +``` + +The counter demonstrates a V4 `SubscriptionRef` exposed as an Effect Lens and +rendered through an Effect-FC component. diff --git a/packages/example-next/biome.json b/packages/example-next/biome.json new file mode 100644 index 0000000..77ba81c --- /dev/null +++ b/packages/example-next/biome.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://biomejs.dev/schemas/latest/schema.json", + "root": false, + "extends": "//", + "files": { + "includes": ["./src/**", "!src/routeTree.gen.ts"] + } +} diff --git a/packages/example-next/index.html b/packages/example-next/index.html new file mode 100644 index 0000000..e7e38b3 --- /dev/null +++ b/packages/example-next/index.html @@ -0,0 +1,13 @@ + + + + + + + Effect FC Next Example + + +
+ + + diff --git a/packages/example-next/package.json b/packages/example-next/package.json new file mode 100644 index 0000000..a37ebbd --- /dev/null +++ b/packages/example-next/package.json @@ -0,0 +1,34 @@ +{ + "name": "@effect-fc/example-next", + "version": "0.0.0", + "type": "module", + "private": true, + "scripts": { + "build": "tsc -b && vite build", + "dev": "vite", + "lint:tsc": "tsc --noEmit", + "lint:biome": "biome lint", + "preview": "vite preview", + "clean:cache": "rm -rf .turbo node_modules/.tmp node_modules/.vite* .tanstack", + "clean:dist": "rm -rf dist", + "clean:modules": "rm -rf node_modules" + }, + "devDependencies": { + "@types/react": "^19.2.15", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.2", + "globals": "^17.6.0", + "react": "^19.2.6", + "react-dom": "^19.2.6", + "vite": "^8.0.16" + }, + "dependencies": { + "effect": "4.0.0-beta.85", + "effect-fc-next": "workspace:*" + }, + "overrides": { + "@types/react": "^19.2.15", + "effect": "4.0.0-beta.85", + "react": "^19.2.6" + } +} diff --git a/packages/example-next/src/index.css b/packages/example-next/src/index.css new file mode 100644 index 0000000..8f84e7d --- /dev/null +++ b/packages/example-next/src/index.css @@ -0,0 +1,28 @@ +:root { + color: #17202a; + font-family: system-ui, sans-serif; + background: #f4f6f7; +} + +body { + display: grid; + min-width: 320px; + min-height: 100vh; + margin: 0; + place-items: center; +} + +main { + padding: 2rem; + text-align: center; +} + +button { + padding: 0.65rem 1rem; + border: 0; + border-radius: 0.5rem; + color: white; + font: inherit; + background: #7d3c98; + cursor: pointer; +} diff --git a/packages/example-next/src/main.tsx b/packages/example-next/src/main.tsx new file mode 100644 index 0000000..125ca5b --- /dev/null +++ b/packages/example-next/src/main.tsx @@ -0,0 +1,40 @@ +import { Effect, Layer, SubscriptionRef } from "effect" +import { Component, Lens, ReactRuntime, Subscribable } from "effect-fc-next" +import { StrictMode } from "react" +import { createRoot } from "react-dom/client" +import "./index.css" + + +const Counter = Component.make("Counter")(function*() { + const count = yield* Component.useOnMount(() => Effect.map( + SubscriptionRef.make(0), + Lens.fromSubscriptionRef, + )) + const [value] = yield* Subscribable.useAll([count]) + const increment = yield* Component.useCallbackSync( + () => Lens.update(count, n => n + 1), + [count], + ) + + return ( +
+

Effect FC Next

+

Running on Effect V4.

+ +
+ ) +}) + +const runtime = ReactRuntime.make(Layer.empty) +const CounterApp = Counter.pipe(Component.withRuntime(runtime.context)) + +// biome-ignore lint/style/noNonNullAssertion: the Vite template provides this element +createRoot(document.getElementById("root")!).render( + + + + + , +) diff --git a/packages/example-next/src/vite-env.d.ts b/packages/example-next/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/packages/example-next/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/example-next/tsconfig.app.json b/packages/example-next/tsconfig.app.json new file mode 100644 index 0000000..f95336a --- /dev/null +++ b/packages/example-next/tsconfig.app.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + + "plugins": [ + { "name": "@effect/language-service" } + ] + }, + + "include": ["src"] +} diff --git a/packages/example-next/tsconfig.json b/packages/example-next/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/packages/example-next/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/packages/example-next/tsconfig.node.json b/packages/example-next/tsconfig.node.json new file mode 100644 index 0000000..0d067e8 --- /dev/null +++ b/packages/example-next/tsconfig.node.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + + "include": ["vite.config.ts"] +} diff --git a/packages/example-next/vite.config.ts b/packages/example-next/vite.config.ts new file mode 100644 index 0000000..5c94b15 --- /dev/null +++ b/packages/example-next/vite.config.ts @@ -0,0 +1,10 @@ +import react from "@vitejs/plugin-react" +import { defineConfig } from "vite" + + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [ + react(), + ], +}) -- 2.52.0 From a38be0b1722c299e4b555142e5f8ed28eed7a3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 22 Jun 2026 06:36:32 +0200 Subject: [PATCH 38/61] Component v4 migration work --- packages/effect-fc-next/src/Component.new.ts | 385 ++++++ packages/effect-fc-next/src/Component.ts | 1193 ++++++++++++++---- 2 files changed, 1354 insertions(+), 224 deletions(-) create mode 100644 packages/effect-fc-next/src/Component.new.ts diff --git a/packages/effect-fc-next/src/Component.new.ts b/packages/effect-fc-next/src/Component.new.ts new file mode 100644 index 0000000..a8f3d4a --- /dev/null +++ b/packages/effect-fc-next/src/Component.new.ts @@ -0,0 +1,385 @@ +/** biome-ignore-all lint/complexity/noBannedTypes: {} is the default type for React props */ +import { + type Context, + type Duration, + Effect, + Exit, + Function, + identity, + Layer, + Pipeable, + Predicate, + Scope, + Tracer, +} from "effect" +import * as React from "react" + + +export const ComponentTypeId: unique symbol = Symbol.for("@effect-fc/Component/Component") +export type ComponentTypeId = typeof ComponentTypeId + +export interface Component

+extends ComponentPrototype, ComponentOptions { + new(_: never): Record + readonly [ComponentTypeId]: ComponentTypeId + readonly "~Props": P + readonly "~Success": A + readonly "~Error": E + readonly "~Context": R + readonly "~Function": F + readonly body: (props: P) => Effect.Effect +} + +export declare namespace Component { + export type Default

= Component> + export type Any = Component + export type Signature = (props: any) => React.ReactNode + export type DefaultSignature

= (props: P) => A + export type Props = T["~Props"] + export type Success = T["~Success"] + export type Error = T["~Error"] + export type Context = T["~Context"] + export type Function = T["~Function"] + export type AsComponent = Component, Success, Error, Context, Function> +} + +export interface ComponentOptions { + readonly displayName?: string + readonly nonReactiveTags: readonly Context.Key[] + readonly finalizerExecutionStrategy: "sequential" | "parallel" + readonly finalizerExecutionDebounce: Duration.Input +} + +export const defaultOptions: ComponentOptions = { + nonReactiveTags: [Tracer.ParentSpan], + finalizerExecutionStrategy: "sequential", + finalizerExecutionDebounce: "100 millis", +} + +export interface ComponentPrototype extends Pipeable.Pipeable { + readonly [ComponentTypeId]: ComponentTypeId + readonly use: Effect.Effect> +} + +type ComponentImpl = Component + +const makeFunctionComponent = ( + self: ComponentImpl, + contextRef: React.RefObject>, +): Component.Signature => { + if ("asFunctionComponent" in self && typeof self.asFunctionComponent === "function") { + return self.asFunctionComponent(contextRef) + } + const FunctionComponent = (props: {}) => Effect.runSyncWith(contextRef.current)( + Effect.flatMap( + useScope([], self), + scope => Effect.provideService(self.body(props), Scope.Scope, scope), + ), + ) + FunctionComponent.displayName = self.displayName ?? "Anonymous" + return "transformFunctionComponent" in self && typeof self.transformFunctionComponent === "function" + ? self.transformFunctionComponent(FunctionComponent) + : FunctionComponent +} + +const use = Effect.fnUntraced(function* (self: ComponentImpl) { + const context = yield* Effect.context() + const cached = componentCache.get(self) + if (cached !== undefined) { + cached.contextRef.current = context + return cached.component + } + const contextRef = { current: context } + const component = makeFunctionComponent(self, contextRef) + componentCache.set(self, { contextRef, component }) + return component +}) + +const componentCache = new WeakMap } + readonly component: Component.Signature +}>() + +export const ComponentPrototype = Object.freeze({ + [ComponentTypeId]: ComponentTypeId, + ...Pipeable.Prototype, + get use() { + return use(this as ComponentImpl) + }, +}) as unknown as ComponentPrototype + +export const isComponent = (u: unknown): u is Component.Any => Predicate.hasProperty(u, ComponentTypeId) + +type GeneratorBody

= ( + props: P, +) => Effect.fn.Return + +type EffectBody

= ( + props: P, +) => Effect.Effect + +export interface Make { +

( + body: GeneratorBody | EffectBody, + ...pipeables: readonly Function[] + ): Component.Default + (name: string, options?: Tracer.SpanOptionsNoTrace):

( + body: GeneratorBody | EffectBody, + ...pipeables: readonly Function[] + ) => Component.Default +} + +const component = ( + body: Function, + displayName: string | undefined, + traced: boolean, + pipeables: readonly Function[], +): Component.Any => Object.setPrototypeOf( + Object.assign(() => {}, defaultOptions, { + body: traced && displayName + ? Effect.fn(displayName)(body as never, ...pipeables as []) + : Effect.fnUntraced(body as never, ...pipeables as []), + displayName, + }), + ComponentPrototype, +) + +export const make: Make = ((nameOrBody: string | Function, ...args: readonly unknown[]) => { + if (typeof nameOrBody === "string") { + return (body: Function, ...pipeables: readonly Function[]) => component(body, nameOrBody, true, pipeables) + } + return component(nameOrBody, undefined, true, args as readonly Function[]) +}) as Make + +export const makeUntraced: Make = ((nameOrBody: string | Function, ...args: readonly unknown[]) => { + if (typeof nameOrBody === "string") { + return (body: Function, ...pipeables: readonly Function[]) => component(body, nameOrBody, false, pipeables) + } + return component(nameOrBody, undefined, false, args as readonly Function[]) +}) as Make + +export declare namespace withSignature { + export type Result = ( + & Omit> + & Component, Component.Success, Component.Error, Component.Context, F> + ) +} + +export const withSignature: { + (): (self: T) => withSignature.Result + (self: T): withSignature.Result +} = (self?: Component.Any): any => self === undefined ? identity : self + +export const withOptions: { + (options: Partial): (self: T) => T + (self: T, options: Partial): T +} = Function.dual(2, (self: T, options: Partial): T => Object.setPrototypeOf( + Object.assign(() => {}, self, options), + Object.getPrototypeOf(self), +)) + +export const withRuntime: { +

( + context: React.Context>, + ): (self: Component, F>) => F +

( + self: Component, F>, + context: React.Context>, + ): F +} = Function.dual(2,

( + self: Component, + context: React.Context>, +) => function WithRuntime(props: P) { + return React.createElement( + Effect.runSyncWith(React.useContext(context))(self.use) as React.FC

, + props, + ) +}) + +export declare namespace useScope { + export interface Options { + readonly finalizerExecutionStrategy?: "sequential" | "parallel" + readonly finalizerExecutionDebounce?: Duration.Input + } +} + +export const useScope = Effect.fnUntraced(function* ( + deps: React.DependencyList, + options?: useScope.Options, +): Effect.fn.Return { + const context = yield* Effect.context() + const contextRef = React.useRef(context) + contextRef.current = context + const scope = React.useMemo( + () => Scope.makeUnsafe(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy), + // biome-ignore lint/correctness/useExhaustiveDependencies: caller controls scope lifetime + deps, + ) + + React.useEffect(() => { + const pending = scopeCleanupTimers.get(scope) + if (pending !== undefined) clearTimeout(pending) + return () => { + const timer = setTimeout(() => { + Effect.runSyncWith(contextRef.current)(Scope.close(scope, Exit.succeed(undefined))) + scopeCleanupTimers.delete(scope) + }, durationMillis(options?.finalizerExecutionDebounce ?? defaultOptions.finalizerExecutionDebounce)) + scopeCleanupTimers.set(scope, timer) + } + }, [scope, options?.finalizerExecutionDebounce]) + + return scope +}) + +const scopeCleanupTimers = new WeakMap>() + +const durationMillis = (input: Duration.Input): number => { + if (typeof input === "number") return input + return Number(Effect.runSync(Effect.map(Effect.succeed(input), value => { + const match = typeof value === "string" ? /([\d.]+)\s*(millis|seconds?)/.exec(value) : undefined + if (!match) return 0 + return Number(match[1]) * (match[2].startsWith("second") ? 1_000 : 1) + }))) +} + +export const useOnMount = Effect.fnUntraced(function* ( + f: () => Effect.Effect, +): Effect.fn.Return { + const context = yield* Effect.context() + const id = React.useId() + let cached = mountCache.get(id) + if (cached === undefined) { + cached = { + effect: Effect.runSyncWith(context)(Effect.cached(f())), + } + mountCache.set(id, cached) + } + React.useEffect(() => { + if (cached?.cleanup !== undefined) clearTimeout(cached.cleanup) + const entry = cached + return () => { + entry.cleanup = setTimeout(() => mountCache.delete(id), 0) + } + }, [id, cached]) + return yield* cached.effect as Effect.Effect +}) + +const mountCache = new Map + cleanup?: ReturnType +}>() + +export declare namespace useOnChange { + export interface Options extends useScope.Options {} +} + +export const useOnChange = Effect.fnUntraced(function* ( + f: () => Effect.Effect, + deps: React.DependencyList, + options?: useOnChange.Options, +): Effect.fn.Return> { + const context = yield* Effect.context>() + const scope = yield* useScope(deps, options) + const cached = + // biome-ignore lint/correctness/useExhaustiveDependencies: scope tracks the caller-provided dependency list + React.useMemo( + () => Effect.runSyncWith(context)(Effect.cached(Effect.provideService(f(), Scope.Scope, scope))), + [scope], + ) + return yield* cached +}) + +export declare namespace useReactEffect { + export interface Options { + readonly finalizerExecutionMode?: "sync" | "fork" + readonly finalizerExecutionStrategy?: "sequential" | "parallel" + } +} + +const runReactEffect = ( + context: Context.Context>, + f: () => Effect.Effect, + options?: useReactEffect.Options, +): (() => void) => { + const scope = Scope.makeUnsafe(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy) + Effect.runSyncWith(context)(Effect.exit(Effect.provideService(f(), Scope.Scope, scope))) + return () => { + const close = Scope.close(scope, Exit.succeed(undefined)) + if ((options?.finalizerExecutionMode ?? "fork") === "sync") Effect.runSyncWith(context)(close) + else Effect.runForkWith(context)(close) + } +} + +export const useReactEffect = Effect.fnUntraced(function* ( + f: () => Effect.Effect, + deps?: React.DependencyList, + options?: useReactEffect.Options, +): Effect.fn.Return> { + const context = yield* Effect.context>() + // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + React.useEffect(() => runReactEffect(context, f, options), deps) +}) + +export declare namespace useReactLayoutEffect { + export interface Options extends useReactEffect.Options {} +} + +export const useReactLayoutEffect = Effect.fnUntraced(function* ( + f: () => Effect.Effect, + deps?: React.DependencyList, + options?: useReactLayoutEffect.Options, +): Effect.fn.Return> { + const context = yield* Effect.context>() + // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + React.useLayoutEffect(() => runReactEffect(context, f, options), deps) +}) + +export const useRunSync = (): Effect.Effect< + (effect: Effect.Effect) => A, + never, + R +> => Effect.map(Effect.context(), Effect.runSyncWith) + +export const useRunPromise = (): Effect.Effect< + (effect: Effect.Effect) => Promise, + never, + R +> => Effect.map(Effect.context(), Effect.runPromiseWith) + +export const useCallbackSync = Effect.fnUntraced(function* ( + f: (...args: Args) => Effect.Effect, + deps: React.DependencyList, +): Effect.fn.Return<(...args: Args) => A, never, R> { + const context = yield* Effect.context() + const contextRef = React.useRef(context) + contextRef.current = context + // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + return React.useCallback((...args: Args) => Effect.runSyncWith(contextRef.current)(f(...args)), deps) +}) + +export const useCallbackPromise = Effect.fnUntraced(function* ( + f: (...args: Args) => Effect.Effect, + deps: React.DependencyList, +): Effect.fn.Return<(...args: Args) => Promise, never, R> { + const context = yield* Effect.context() + const contextRef = React.useRef(context) + contextRef.current = context + // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + return React.useCallback((...args: Args) => Effect.runPromiseWith(contextRef.current)(f(...args)), deps) +}) + +export declare namespace useContext { + export interface Options extends useOnChange.Options {} +} + +export const useContextFromLayer = ( + layer: Layer.Layer, + options?: useContext.Options, +): Effect.Effect, E, RIn | Scope.Scope> => useOnChange( + () => Effect.flatMap( + Effect.context(), + context => Layer.build(Layer.provide(layer, Layer.succeedContext(context))), + ), + [layer], + options, +) diff --git a/packages/effect-fc-next/src/Component.ts b/packages/effect-fc-next/src/Component.ts index 6bf9d93..ed24870 100644 --- a/packages/effect-fc-next/src/Component.ts +++ b/packages/effect-fc-next/src/Component.ts @@ -1,23 +1,15 @@ /** biome-ignore-all lint/complexity/noBannedTypes: {} is the default type for React props */ -import { - Context, - type Duration, - Effect, - Exit, - Function, - identity, - Layer, - Pipeable, - Predicate, - Scope, - Tracer, -} from "effect" +/** biome-ignore-all lint/complexity/useArrowFunction: necessary for class prototypes */ +import { Context, type Duration, Effect, Equivalence, ExecutionStrategy, Exit, Fiber, Function, HashMap, identity, Layer, Option, Pipeable, Predicate, Ref, Runtime, Scope, Tracer, type Utils } from "effect" import * as React from "react" export const ComponentTypeId: unique symbol = Symbol.for("@effect-fc/Component/Component") export type ComponentTypeId = typeof ComponentTypeId +/** + * Represents an Effect-based React Component that integrates the Effect system with React. + */ export interface Component

extends ComponentPrototype, ComponentOptions { new(_: never): Record @@ -27,137 +19,507 @@ extends ComponentPrototype, ComponentOptions { readonly "~Error": E readonly "~Context": R readonly "~Function": F + readonly body: (props: P) => Effect.Effect } export declare namespace Component { export type Default

= Component> export type Any = Component + export type Signature = (props: any) => React.ReactNode export type DefaultSignature

= (props: P) => A - export type Props = T["~Props"] - export type Success = T["~Success"] - export type Error = T["~Error"] - export type Context = T["~Context"] - export type Function = T["~Function"] + + export type Props = [T] extends [Component] ? P : never + export type Success = [T] extends [Component] ? A : never + export type Error = [T] extends [Component] ? E : never + export type Context = [T] extends [Component] ? R : never + export type Function = [T] extends [Component] ? F : never + export type AsComponent = Component, Success, Error, Context, Function> } + +export interface ComponentImpl

+extends Component, ComponentImplPrototype {} + +export interface ComponentImplPrototype { + readonly use: Effect.Effect> + + asFunctionComponent(contextRef: React.Ref>>): F + setFunctionComponentName(f: F): void + transformFunctionComponent(f: F): F +} + +export const ComponentImplPrototype: ComponentImplPrototype = Object.freeze({ + get use() { return use(this) }, + + asFunctionComponent

( + this: ComponentImpl, + contextRef: React.RefObject>>, + ) { + return (props: P) => Effect.runSyncWith(contextRef.current)( + Effect.andThen( + useScope([], this), + scope => Effect.provideService(this.body(props), Scope.Scope, scope), + ) + ) + }, + + setFunctionComponentName

( + this: ComponentImpl, + f: React.FC

, + ) { + f.displayName = this.displayName ?? "Anonymous" + }, + + transformFunctionComponent: identity, +} as const) + +const use = Effect.fnUntraced(function*

( + self: ComponentImpl +) { + // biome-ignore lint/style/noNonNullAssertion: React ref initialization + const contextRef = React.useRef>>(null!) + contextRef.current = yield* Effect.context>() + + return yield* React.useState(() => Effect.runSyncWith(contextRef.current)(Effect.cachedFunction( + (_services: readonly any[]) => Effect.sync(() => { + const f = self.asFunctionComponent(contextRef) + self.setFunctionComponentName(f) + return self.transformFunctionComponent(f) + }), + Equivalence.array(Equivalence.strictEqual()), + )))[0](Array.from( + Context.omit(...self.nonReactiveTags)(contextRef.current).mapUnsafe.values() + )) +}) + + +export interface ComponentPrototype +extends Pipeable.Pipeable { + readonly [ComponentTypeId]: ComponentTypeId + readonly use: Effect.Effect> +} + +export const ComponentPrototype: ComponentPrototype = Object.freeze( + Object.defineProperties( + { + [ComponentTypeId]: ComponentTypeId, + ...Pipeable.Prototype, + }, + Object.getOwnPropertyDescriptors(ComponentImplPrototype), + ) as ComponentPrototype +) + + export interface ComponentOptions { + /** + * Custom display name for the component in React DevTools and debugging utilities. + */ readonly displayName?: string + + /** + * Context tags that should not trigger component remount when their values change. + * + * @default [Tracer.ParentSpan] + */ readonly nonReactiveTags: readonly Context.Key[] - readonly finalizerExecutionStrategy: "sequential" | "parallel" + + /** + * Specifies the execution strategy for finalizers when the component unmounts or its scope closes. + * Determines whether finalizers execute sequentially or in parallel. + * + * @default ExecutionStrategy.sequential + */ + readonly finalizerExecutionStrategy: ExecutionStrategy.ExecutionStrategy + + /** + * Debounce duration before executing finalizers after component unmount. + * Prevents unnecessary cleanup work during rapid remount/unmount cycles, + * which is common in development and certain UI patterns. + * + * @default "100 millis" + */ readonly finalizerExecutionDebounce: Duration.Input } export const defaultOptions: ComponentOptions = { nonReactiveTags: [Tracer.ParentSpan], - finalizerExecutionStrategy: "sequential", + finalizerExecutionStrategy: ExecutionStrategy.sequential, finalizerExecutionDebounce: "100 millis", } -export interface ComponentPrototype extends Pipeable.Pipeable { - readonly [ComponentTypeId]: ComponentTypeId - readonly use: Effect.Effect> -} -type ComponentImpl = Component +export const isComponent = (u: unknown): u is Component.Default<{}, React.ReactNode, unknown, unknown> => Predicate.hasProperty(u, ComponentTypeId) -const makeFunctionComponent = ( - self: ComponentImpl, - contextRef: React.RefObject>, -): Component.Signature => { - if ("asFunctionComponent" in self && typeof self.asFunctionComponent === "function") { - return self.asFunctionComponent(contextRef) +export declare namespace make { + export type Gen = { + >, A extends React.ReactNode, P extends {} = {}>( + body: (props: P) => Generator + ): Component.Default< + P, A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + > + >, A, B extends Effect.Effect, P extends {} = {}>( + body: (props: P) => Generator, + a: ( + _: Effect.Effect< + A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + >, + props: NoInfer

, + ) => B, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + >, A, B, C extends Effect.Effect, P extends {} = {}>( + body: (props: P) => Generator, + a: ( + _: Effect.Effect< + A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + >, + props: NoInfer

, + ) => B, + b: (_: B, props: NoInfer

) => C, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + >, A, B, C, D extends Effect.Effect, P extends {} = {}>( + body: (props: P) => Generator, + a: ( + _: Effect.Effect< + A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + >, + props: NoInfer

, + ) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + >, A, B, C, D, E extends Effect.Effect, P extends {} = {}>( + body: (props: P) => Generator, + a: ( + _: Effect.Effect< + A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + >, + props: NoInfer

, + ) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + >, A, B, C, D, E, F extends Effect.Effect, P extends {} = {}>( + body: (props: P) => Generator, + a: ( + _: Effect.Effect< + A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + >, + props: NoInfer

, + ) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => F, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + >, A, B, C, D, E, F, G extends Effect.Effect, P extends {} = {}>( + body: (props: P) => Generator, + a: ( + _: Effect.Effect< + A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + >, + props: NoInfer

, + ) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => F, + f: (_: F, props: NoInfer

) => G, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + >, A, B, C, D, E, F, G, H extends Effect.Effect, P extends {} = {}>( + body: (props: P) => Generator, + a: ( + _: Effect.Effect< + A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + >, + props: NoInfer

, + ) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => F, + f: (_: F, props: NoInfer

) => G, + g: (_: G, props: NoInfer

) => H, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + >, A, B, C, D, E, F, G, H, I extends Effect.Effect, P extends {} = {}>( + body: (props: P) => Generator, + a: ( + _: Effect.Effect< + A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + >, + props: NoInfer

, + ) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => F, + f: (_: F, props: NoInfer

) => G, + g: (_: G, props: NoInfer

) => H, + h: (_: H, props: NoInfer

) => I, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + >, A, B, C, D, E, F, G, H, I, J extends Effect.Effect, P extends {} = {}>( + body: (props: P) => Generator, + a: ( + _: Effect.Effect< + A, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + >, + props: NoInfer

, + ) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => F, + f: (_: F, props: NoInfer

) => G, + g: (_: G, props: NoInfer

) => H, + h: (_: H, props: NoInfer

) => I, + i: (_: I, props: NoInfer

) => J, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> } - const FunctionComponent = (props: {}) => Effect.runSyncWith(contextRef.current)( - Effect.flatMap( - useScope([], self), - scope => Effect.provideService(self.body(props), Scope.Scope, scope), - ), - ) - FunctionComponent.displayName = self.displayName ?? "Anonymous" - return "transformFunctionComponent" in self && typeof self.transformFunctionComponent === "function" - ? self.transformFunctionComponent(FunctionComponent) - : FunctionComponent -} -const use = Effect.fnUntraced(function* (self: ComponentImpl) { - const context = yield* Effect.context() - const cached = componentCache.get(self) - if (cached !== undefined) { - cached.contextRef.current = context - return cached.component + export type NonGen = { + , P extends {} = {}>( + body: (props: P) => Eff + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + , A, P extends {} = {}>( + body: (props: P) => A, + a: (_: A, props: NoInfer

) => Eff, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + , A, B, P extends {} = {}>( + body: (props: P) => A, + a: (_: A, props: NoInfer

) => B, + b: (_: B, props: NoInfer

) => Eff, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + , A, B, C, P extends {} = {}>( + body: (props: P) => A, + a: (_: A, props: NoInfer

) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => Eff, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + , A, B, C, D, P extends {} = {}>( + body: (props: P) => A, + a: (_: A, props: NoInfer

) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => Eff, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + , A, B, C, D, E, P extends {} = {}>( + body: (props: P) => A, + a: (_: A, props: NoInfer

) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => Eff, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + , A, B, C, D, E, F, P extends {} = {}>( + body: (props: P) => A, + a: (_: A, props: NoInfer

) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => F, + f: (_: F, props: NoInfer

) => Eff, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + , A, B, C, D, E, F, G, P extends {} = {}>( + body: (props: P) => A, + a: (_: A, props: NoInfer

) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => F, + f: (_: F, props: NoInfer

) => G, + g: (_: G, props: NoInfer

) => Eff, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + , A, B, C, D, E, F, G, H, P extends {} = {}>( + body: (props: P) => A, + a: (_: A, props: NoInfer

) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => F, + f: (_: F, props: NoInfer

) => G, + g: (_: G, props: NoInfer

) => H, + h: (_: H, props: NoInfer

) => Eff, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + , A, B, C, D, E, F, G, H, I, P extends {} = {}>( + body: (props: P) => A, + a: (_: A, props: NoInfer

) => B, + b: (_: B, props: NoInfer

) => C, + c: (_: C, props: NoInfer

) => D, + d: (_: D, props: NoInfer

) => E, + e: (_: E, props: NoInfer

) => F, + f: (_: F, props: NoInfer

) => G, + g: (_: G, props: NoInfer

) => H, + h: (_: H, props: NoInfer

) => I, + i: (_: I, props: NoInfer

) => Eff, + ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> } - const contextRef = { current: context } - const component = makeFunctionComponent(self, contextRef) - componentCache.set(self, { contextRef, component }) - return component -}) - -const componentCache = new WeakMap } - readonly component: Component.Signature -}>() - -export const ComponentPrototype = Object.freeze({ - [ComponentTypeId]: ComponentTypeId, - ...Pipeable.Prototype, - get use() { - return use(this as ComponentImpl) - }, -}) as unknown as ComponentPrototype - -export const isComponent = (u: unknown): u is Component.Any => Predicate.hasProperty(u, ComponentTypeId) - -type GeneratorBody

= ( - props: P, -) => Effect.fn.Return - -type EffectBody

= ( - props: P, -) => Effect.Effect - -export interface Make { -

( - body: GeneratorBody | EffectBody, - ...pipeables: readonly Function[] - ): Component.Default - (name: string, options?: Tracer.SpanOptionsNoTrace):

( - body: GeneratorBody | EffectBody, - ...pipeables: readonly Function[] - ) => Component.Default } -const component = ( - body: Function, - displayName: string | undefined, - traced: boolean, - pipeables: readonly Function[], -): Component.Any => Object.setPrototypeOf( - Object.assign(function() {}, defaultOptions, { - body: traced && displayName - ? Effect.fn(displayName)(body as never, ...pipeables as []) - : Effect.fnUntraced(body as never, ...pipeables as []), - displayName, - }), - ComponentPrototype, +/** + * Creates an Effect-FC Component using the same overloads and pipeline composition style as `Effect.fn`. + * + * This is the **recommended** approach for defining Effect-FC components. It provides comprehensive + * support for multiple component definition patterns: + * + * - **Generator syntax** (yield* style): Most ergonomic and readable approach for sequential operations + * - **Direct Effect return**: For simple components that return an Effect directly + * - **Chained transformation functions**: Enables Effect.fn-style pipelines for composable transformations + * - **Automatic tracing**: Optional tracing span creation with automatic `displayName` assignment + * + * When a `spanName` string is provided, the following occurs automatically: + * 1. A distributed tracing span is created with the specified name + * 2. The resulting React component receives `displayName = spanName` for DevTools visibility + * + * @example + * ```tsx + * const MyComponent = Component.make("MyComponent")(function* (props: { count: number }) { + * const value = yield* someEffect + * return

+ * }) + * ``` + * + * @example As an opaque type using class syntax + * ```tsx + * class MyComponent extends Component.make("MyComponent")(function* (props: { count: number }) { + * const value = yield* someEffect + * return
{value}
+ * }) {} + * ``` + * + * @example Without name + * ```tsx + * class MyComponent extends Component.make(function* (props: { count: number }) { + * const value = yield* someEffect + * return
{value}
+ * }) {} + * ``` + * + * @example Using pipeline + * ```tsx + * class MyComponent extends Component.make("MyComponent")( + * (props: { count: number }) => someEffect, + * Effect.map(value =>
{value}
), + * ) {} + * ``` + */ +export const make: ( + & make.Gen + & make.NonGen + & (( + spanName: string, + spanOptions?: Tracer.SpanOptions, + ) => make.Gen & make.NonGen) +) = (spanNameOrBody: Function | string, ...pipeables: any[]): any => { + if (typeof spanNameOrBody !== "string") { + return Object.setPrototypeOf( + Object.assign(function() {}, defaultOptions, { + body: Effect.fn(spanNameOrBody as any, ...pipeables), + }), + ComponentPrototype, + ) + } + else { + const spanOptions = pipeables[0] + return (body: any, ...pipeables: any[]) => Object.setPrototypeOf( + Object.assign(function() {}, defaultOptions, { + body: Effect.fn(spanNameOrBody, spanOptions)(body, ...pipeables as []), + displayName: spanNameOrBody, + }), + ComponentPrototype, + ) + } +} + +/** + * Creates an Effect-FC Component without automatic distributed tracing. + * + * This function provides the same API surface as `make`, but does not create automatic tracing spans. + * It follows the exact same overload structure as `Effect.fnUntraced`. + * + * Use this variant when you need: + * - Full manual control over tracing instrumentation + * - To reduce tracing overhead in deeply nested component hierarchies + * - To avoid span noise in performance-sensitive applications + * + * When a `spanName` string is provided, it is used **exclusively** as the React component's + * `displayName` for DevTools identification. No tracing span is created. + * + * @example + * ```tsx + * const MyComponent = Component.makeUntraced("MyComponent")(function* (props: { count: number }) { + * const value = yield* someEffect + * return
{value}
+ * }) + * ``` + * + * @example As an opaque type using class syntax + * ```tsx + * class MyComponent extends Component.makeUntraced("MyComponent")(function* (props: { count: number }) { + * const value = yield* someEffect + * return
{value}
+ * }) {} + * ``` + * + * @example Without name + * ```tsx + * class MyComponent extends Component.makeUntraced(function* (props: { count: number }) { + * const value = yield* someEffect + * return
{value}
+ * }) {} + * ``` + * + * @example Using pipeline + * ```tsx + * class MyComponent extends Component.makeUntraced("MyComponent")( + * (props: { count: number }) => someEffect, + * Effect.map(value =>
{value}
), + * ) {} + * ``` + */ +export const makeUntraced: ( + & make.Gen + & make.NonGen + & ((name: string) => make.Gen & make.NonGen) +) = (spanNameOrBody: Function | string, ...pipeables: any[]): any => ( + typeof spanNameOrBody !== "string" + ? Object.setPrototypeOf( + Object.assign(function() {}, defaultOptions, { + body: Effect.fnUntraced(spanNameOrBody as any, ...pipeables as []), + }), + ComponentPrototype, + ) + : (body: any, ...pipeables: any[]) => Object.setPrototypeOf( + Object.assign(function() {}, defaultOptions, { + body: Effect.fnUntraced(body, ...pipeables as []), + displayName: spanNameOrBody, + }), + ComponentPrototype, + ) ) -export const make: Make = ((nameOrBody: string | Function, ...args: readonly unknown[]) => { - if (typeof nameOrBody === "string") { - return (body: Function, ...pipeables: readonly Function[]) => component(body, nameOrBody, true, pipeables) - } - return component(nameOrBody, undefined, true, args as readonly Function[]) -}) as Make - -export const makeUntraced: Make = ((nameOrBody: string | Function, ...args: readonly unknown[]) => { - if (typeof nameOrBody === "string") { - return (body: Function, ...pipeables: readonly Function[]) => component(body, nameOrBody, false, pipeables) - } - return component(nameOrBody, undefined, false, args as readonly Function[]) -}) as Make - export declare namespace withSignature { export type Result = ( & Omit> @@ -166,113 +528,266 @@ export declare namespace withSignature { } export const withSignature: { - (): (self: T) => withSignature.Result - (self: T): withSignature.Result -} = (self?: Component.Any): any => self === undefined ? identity : self + (): ( + self: T + ) => withSignature.Result + ( + self: T + ): withSignature.Result +} = (self?: Component.Any): any => self === undefined + ? identity + : self +/** + * Creates a new component with modified configuration options while preserving all original behavior. + * + * This function allows you to customize component-level options such as finalizer execution strategy + * and debounce timing. + * + * @example + * ```tsx + * const MyComponentWithCustomOptions = MyComponent.pipe( + * Component.withOptions({ + * finalizerExecutionStrategy: ExecutionStrategy.parallel, + * finalizerExecutionDebounce: "50 millis", + * }) + * ) + * ``` + */ export const withOptions: { - (options: Partial): (self: T) => T - (self: T, options: Partial): T -} = Function.dual(2, (self: T, options: Partial): T => Object.setPrototypeOf( + ( + options: Partial + ): (self: T) => T + ( + self: T, + options: Partial, + ): T +} = Function.dual(2, ( + self: T, + options: Partial, +): T => Object.setPrototypeOf( Object.assign(function() {}, self, options), Object.getPrototypeOf(self), )) +/** + * Wraps an Effect-FC Component and converts it into a standard React function component, + * serving as an **entrypoint** into an Effect-FC component hierarchy. + * + * This is how Effect-FC components are integrated with the broader React ecosystem, + * particularly when: + * - Using client-side routers (TanStack Router, React Router, etc.) + * - Implementing lazy-loaded or code-split routes + * - Connecting to third-party libraries expecting standard React components + * - Creating component boundaries between Effect-FC and non-Effect-FC code + * + * The Effect runtime is obtained from the provided React Context. + * + * @param self - The Effect-FC Component to be rendered as a standard React component + * @param context - React Context providing the Effect Runtime for this component tree. + * Create this using the `ReactRuntime` module. + * + * @example Integration with TanStack Router + * ```tsx + * // Application root + * export const runtime = ReactRuntime.make(Layer.empty) + * + * function App() { + * return ( + * + * + * + * ) + * } + * + * // Route definition + * export const Route = createFileRoute("/")({ + * component: Component.withRuntime(HomePage, runtime.context) + * }) + * ``` + * + */ export const withRuntime: {

( - context: React.Context>, + context: React.Context>, ): (self: Component, F>) => F

( self: Component, F>, - context: React.Context>, + context: React.Context>, ): F } = Function.dual(2,

( - self: Component, - context: React.Context>, + self: Component, + context: React.Context>, ) => function WithRuntime(props: P) { return React.createElement( - Effect.runSyncWith(React.useContext(context))(self.use) as React.FC

, + Runtime.runSync(React.useContext(context))(self.use) as React.FC

, props, ) }) + +/** + * Internal Effect service that maintains a registry of scopes associated with React component instances. + * + * This service is used internally by the `useScope` hook to manage the lifecycle of component scopes, + * including tracking active scopes and coordinating their cleanup when components unmount or dependencies change. + */ +export class ScopeMap extends Context.Service> +}>()( + "@effect-fc/Component/ScopeMap" +) { + static readonly layer = Layer.effect(ScopeMap, Effect.map( + Ref.make(HashMap.empty()), + ref => ({ ref }), + )) +} + +export declare namespace ScopeMap { + export interface Entry { + readonly scope: Scope.Closeable + readonly closeFiber: Option.Option> + } +} + + export declare namespace useScope { export interface Options { - readonly finalizerExecutionStrategy?: "sequential" | "parallel" + readonly finalizerExecutionStrategy?: ExecutionStrategy.ExecutionStrategy readonly finalizerExecutionDebounce?: Duration.Input } } -export const useScope = Effect.fnUntraced(function* ( +/** + * Effect hook that creates and manages a `Scope` for the current component instance. + * + * This hook establishes a new scope that is automatically closed when: + * - The component unmounts + * - The dependency array `deps` changes + * + * The scope provides a resource management boundary for any Effects executed within the component, + * ensuring proper cleanup of resources and execution of finalizers. + * + * @param deps - Dependency array following React.useEffect semantics. The scope is recreated + * whenever any dependency changes. + * @param options - Configuration for finalizer execution behavior, including execution strategy + * and debounce timing. + * + * @returns An Effect that produces a `Scope` for resource management +*/ +export const useScope = Effect.fnUntraced(function*( deps: React.DependencyList, options?: useScope.Options, ): Effect.fn.Return { - const context = yield* Effect.context() - const contextRef = React.useRef(context) - contextRef.current = context - const scope = React.useMemo( - () => Scope.makeUnsafe(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy), - // biome-ignore lint/correctness/useExhaustiveDependencies: caller controls scope lifetime - deps, - ) + // biome-ignore lint/style/noNonNullAssertion: context initialization + const contextRef = React.useRef>(null!) + contextRef.current = yield* Effect.context() - React.useEffect(() => { - const pending = scopeCleanupTimers.get(scope) - if (pending !== undefined) clearTimeout(pending) - return () => { - const timer = setTimeout(() => { - Effect.runSyncWith(contextRef.current)(Scope.close(scope, Exit.succeed(undefined))) - scopeCleanupTimers.delete(scope) - }, durationMillis(options?.finalizerExecutionDebounce ?? defaultOptions.finalizerExecutionDebounce)) - scopeCleanupTimers.set(scope, timer) - } - }, [scope, options?.finalizerExecutionDebounce]) + const { key, scope } = React.useMemo(() => Effect.runSyncWith(contextRef.current)(Effect.Do.pipe( + Effect.bind("scopeMapRef", () => Effect.map( + ScopeMap as unknown as Effect.Effect, + scopeMap => scopeMap.ref, + )), + Effect.let("key", () => ({})), + Effect.bind("scope", () => Scope.make(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy)), + Effect.tap(({ scopeMapRef, key, scope }) => + Ref.update(scopeMapRef, HashMap.set(key, { + scope, + closeFiber: Option.none(), + })) + ), + // biome-ignore lint/correctness/useExhaustiveDependencies: use of React.DependencyList + )), deps) + + // biome-ignore lint/correctness/useExhaustiveDependencies: only reactive on "key" + React.useEffect(() => Effect.runSyncWith(contextRef.current)( + (ScopeMap as unknown as Effect.Effect).pipe( + Effect.map(scopeMap => scopeMap.ref), + Effect.tap(ref => Ref.get(ref).pipe( + Effect.flatMap(map => Effect.fromOption(HashMap.get(map, key))), + Effect.flatMap(entry => Option.match(entry.closeFiber, { + onSome: fiber => Effect.forkDetach(Fiber.interrupt(fiber)), + onNone: () => Effect.void, + })), + )), + Effect.map(ref => + () => Effect.runSyncWith(contextRef.current)(Effect.flatMap( + Effect.sleep(options?.finalizerExecutionDebounce ?? defaultOptions.finalizerExecutionDebounce).pipe( + Effect.andThen(Scope.close(scope, Exit.void)), + Effect.onExit(() => Ref.update(ref, HashMap.remove(key))), + Effect.forkDetach, + ), + fiber => Ref.update(ref, HashMap.set(key, { + scope, + closeFiber: Option.some(fiber), + })), + )) + ), + ) + ), [key]) return scope }) -const scopeCleanupTimers = new WeakMap>() - -const durationMillis = (input: Duration.Input): number => { - if (typeof input === "number") return input - return Number(Effect.runSync(Effect.map(Effect.succeed(input), value => { - const match = typeof value === "string" ? /([\d.]+)\s*(millis|seconds?)/.exec(value) : undefined - if (!match) return 0 - return Number(match[1]) * (match[2].startsWith("second") ? 1_000 : 1) - }))) -} - +/** + * Effect hook that executes an Effect once when the component mounts and caches the result. + * + * This hook is useful for one-time initialization logic that should not be re-executed + * when the component re-renders. The Effect is executed exactly once during the component's + * initial mount, and the cached result is returned on all subsequent renders. + * + * @param f - A function that returns the Effect to execute on mount + * + * @returns An Effect that produces the cached result of the Effect + * + * @example + * ```tsx + * const MyComponent = Component.make(function*() { + * const initialData = yield* Component.useOnMount(() => getData) + * return

{initialData}
+ * }) + * ``` + */ export const useOnMount = Effect.fnUntraced(function* ( - f: () => Effect.Effect, + f: () => Effect.Effect ): Effect.fn.Return { const context = yield* Effect.context() - const id = React.useId() - let cached = mountCache.get(id) - if (cached === undefined) { - cached = { - effect: Effect.runSyncWith(context)(Effect.cached(f())), - } - mountCache.set(id, cached) - } - React.useEffect(() => { - if (cached?.cleanup !== undefined) clearTimeout(cached.cleanup) - const entry = cached - return () => { - entry.cleanup = setTimeout(() => mountCache.delete(id), 0) - } - }, [id, cached]) - return yield* cached.effect as Effect.Effect + return yield* React.useState(() => Effect.runSyncWith(context)(Effect.cached(f())))[0] }) -const mountCache = new Map - cleanup?: ReturnType -}>() - export declare namespace useOnChange { export interface Options extends useScope.Options {} } +/** + * Effect hook that executes an Effect whenever dependencies change and caches the result. + * + * This hook combines the dependency-tracking behavior of React.useEffect with Effect caching. + * The Effect is re-executed whenever any dependency in the `deps` array changes, and the result + * is cached until the next dependency change. + * + * A dedicated scope is created for each dependency change, ensuring proper resource cleanup: + * - The scope closes when dependencies change + * - The scope closes when the component unmounts + * - All finalizers are executed according to the configured execution strategy + * + * @param f - A function that returns the Effect to execute + * @param deps - Dependency array following React.useEffect semantics + * @param options - Configuration for scope and finalizer behavior + * + * @returns An Effect that produces the cached result of the Effect + * + * @example + * ```tsx + * const MyComponent = Component.make(function* (props: { userId: string }) { + * const userData = yield* Component.useOnChange( + * getUser(props.userId), + * [props.userId], + * ) + * return
{userData.name}
+ * }) + * ``` + */ export const useOnChange = Effect.fnUntraced(function* ( f: () => Effect.Effect, deps: React.DependencyList, @@ -280,91 +795,264 @@ export const useOnChange = Effect.fnUntraced(function* ( ): Effect.fn.Return> { const context = yield* Effect.context>() const scope = yield* useScope(deps, options) - const cached = - // biome-ignore lint/correctness/useExhaustiveDependencies: scope tracks the caller-provided dependency list - React.useMemo( - () => Effect.runSyncWith(context)(Effect.cached(Effect.provideService(f(), Scope.Scope, scope))), - [scope], - ) - return yield* cached + + // biome-ignore lint/correctness/useExhaustiveDependencies: only reactive on "scope" + return yield* React.useMemo(() => Effect.runSyncWith(context)( + Effect.cached(Effect.provideService(f(), Scope.Scope, scope)) + ), [scope]) }) export declare namespace useReactEffect { export interface Options { readonly finalizerExecutionMode?: "sync" | "fork" - readonly finalizerExecutionStrategy?: "sequential" | "parallel" - } -} - -const runReactEffect = ( - context: Context.Context>, - f: () => Effect.Effect, - options?: useReactEffect.Options, -): (() => void) => { - const scope = Scope.makeUnsafe(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy) - Effect.runSyncWith(context)(Effect.exit(Effect.provideService(f(), Scope.Scope, scope))) - return () => { - const close = Scope.close(scope, Exit.succeed(undefined)) - if ((options?.finalizerExecutionMode ?? "fork") === "sync") Effect.runSyncWith(context)(close) - else Effect.runForkWith(context)(close) + readonly finalizerExecutionStrategy?: ExecutionStrategy.ExecutionStrategy } } +/** + * Effect hook that provides Effect-based semantics for React.useEffect. + * + * This hook bridges React's useEffect with the Effect system, allowing you to use Effects + * for React side effects while maintaining React's dependency tracking and lifecycle semantics. + * + * Unlike React.useEffect which uses imperative cleanup functions, this hook leverages the + * Effect Scope API for resource management. Cleanup logic is expressed declaratively through + * finalizers registered with the scope, providing better composability and error handling. + * + * @param f - A function that returns an Effect to execute as a side effect + * @param deps - Optional dependency array following React.useEffect semantics. + * If omitted, the effect runs after every render. + * @param options - Configuration for finalizer execution mode (sync or fork) and strategy + * + * @returns An Effect that produces void + * + * @example + * ```tsx + * const MyComponent = Component.make(function* (props: { id: string }) { + * yield* Component.useReactEffect( + * () => getNotificationStreamForUser(props.id).pipe( + * Stream.unwrap, + * Stream.runForEach(notification => Console.log(`Notification received: ${ notification }`), + * Effect.forkScoped, + * ), + * [props.id], + * ) + * return
Subscribed to notifications for {props.id}
+ * }) + * ``` + */ export const useReactEffect = Effect.fnUntraced(function* ( f: () => Effect.Effect, deps?: React.DependencyList, options?: useReactEffect.Options, ): Effect.fn.Return> { const context = yield* Effect.context>() - // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + // biome-ignore lint/correctness/useExhaustiveDependencies: use of React.DependencyList React.useEffect(() => runReactEffect(context, f, options), deps) }) +const runReactEffect = ( + context: Context.Context>, + f: () => Effect.Effect, + options?: useReactEffect.Options, +) => Effect.Do.pipe( + Effect.bind("scope", () => Scope.make(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy)), + Effect.bind("exit", ({ scope }) => Effect.exit(Effect.provideService(f(), Scope.Scope, scope))), + Effect.map(({ scope }) => + () => { + switch (options?.finalizerExecutionMode ?? "fork") { + case "sync": + Effect.runSyncWith(context)(Scope.close(scope, Exit.void)) + break + case "fork": + Effect.runForkWith(context)(Scope.close(scope, Exit.void)) + break + } + } + ), + Effect.runSyncWith(context), +) + export declare namespace useReactLayoutEffect { export interface Options extends useReactEffect.Options {} } +/** + * Effect hook that provides Effect-based semantics for React.useLayoutEffect. + * + * This hook is identical to `useReactEffect` but executes synchronously after DOM mutations + * but before the browser paints, following React.useLayoutEffect semantics. + * + * Use this hook when you need to: + * - Measure DOM elements (e.g., for layout calculations) + * - Synchronously update state based on DOM measurements + * - Avoid visual flicker from asynchronous updates + * + * Like `useReactEffect`, cleanup logic is handled through the Effect Scope API rather than + * imperative cleanup functions, providing declarative and composable resource management. + * + * @param f - A function that returns an Effect to execute as a layout side effect + * @param deps - Optional dependency array following React.useLayoutEffect semantics. + * If omitted, the effect runs after every render. + * @param options - Configuration for finalizer execution mode (sync or fork) and strategy + * + * @returns An Effect that produces void + * + * @example + * ```tsx + * const MyComponent = Component.make(function*() { + * const ref = React.useRef(null) + * yield* Component.useReactLayoutEffect( + * () => Effect.gen(function* () { + * const element = ref.current + * if (element) { + * const rect = element.getBoundingClientRect() + * yield* Console.log(`Element dimensions: ${ rect.width }x${ rect.height }`) + * } + * }), + * [], + * ) + * return
Content
+ * }) + * ``` + */ export const useReactLayoutEffect = Effect.fnUntraced(function* ( f: () => Effect.Effect, deps?: React.DependencyList, options?: useReactLayoutEffect.Options, ): Effect.fn.Return> { const context = yield* Effect.context>() - // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + // biome-ignore lint/correctness/useExhaustiveDependencies: use of React.DependencyList React.useLayoutEffect(() => runReactEffect(context, f, options), deps) }) +/** + * Effect hook that provides a synchronous function to execute Effects within the current runtime context. + * + * This hook returns a function that can execute Effects synchronously, blocking until completion. + * Use this when you need to run Effects from non-Effect code (e.g., event handlers, callbacks) + * within a component. + * + * @returns An Effect that produces a function capable of synchronously executing Effects + * + * @example + * ```tsx + * const MyComponent = Component.make(function*() { + * const runSync = yield* Component.useRunSync() // Specify required services + * const runSync = yield* Component.useRunSync() // Or no service requirements + * + * return + * }) + * ``` + */ export const useRunSync = (): Effect.Effect< - (effect: Effect.Effect) => A, + (effect: Effect.Effect) => A, never, - R -> => Effect.map(Effect.context(), Effect.runSyncWith) + Scope.Scope | R +> => Effect.map(Effect.context(), Effect.runSyncWith) +/** + * Effect hook that provides an asynchronous function to execute Effects within the current runtime context. + * + * This hook returns a function that executes Effects asynchronously, returning a Promise that resolves + * with the Effect's result. Use this when you need to run Effects from non-Effect code (e.g., event handlers, + * async callbacks) and want to handle the result asynchronously. + * + * @returns An Effect that produces a function capable of asynchronously executing Effects + * + * @example + * ```tsx + * const MyComponent = Component.make(function*() { + * const runPromise = yield* Component.useRunPromise() // Specify required services + * const runPromise = yield* Component.useRunPromise() // Or no service requirements + * + * return + * }) + * ``` + */ export const useRunPromise = (): Effect.Effect< - (effect: Effect.Effect) => Promise
, + (effect: Effect.Effect) => Promise, never, - R -> => Effect.map(Effect.context(), Effect.runPromiseWith) + Scope.Scope | R +> => Effect.map(Effect.context(), Effect.runPromiseWith) +/** + * Effect hook that memoizes a function that returns an Effect, providing synchronous execution. + * + * This hook wraps a function that returns an Effect and returns a memoized version that: + * - Executes the Effect synchronously when called + * - Is memoized based on the provided dependency array + * - Maintains referential equality across renders when dependencies don't change + * + * Use this to create stable callback references for event handlers and other scenarios + * where you need to execute Effects synchronously from non-Effect code. + * + * @param f - A function that accepts arguments and returns an Effect + * @param deps - Dependency array. The memoized function is recreated when dependencies change. + * + * @returns An Effect that produces a memoized function with the same signature as `f` + * + * @example + * ```tsx + * const MyComponent = Component.make(function* (props: { onSave: (data: Data) => void }) { + * const handleSave = yield* Component.useCallbackSync( + * (data: Data) => Effect.sync(() => props.onSave(data)), + * [props.onSave], + * ) + * + * return + * }) + * ``` + */ export const useCallbackSync = Effect.fnUntraced(function* ( f: (...args: Args) => Effect.Effect, deps: React.DependencyList, ): Effect.fn.Return<(...args: Args) => A, never, R> { - const context = yield* Effect.context() - const contextRef = React.useRef(context) - contextRef.current = context - // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + // biome-ignore lint/style/noNonNullAssertion: context initialization + const contextRef = React.useRef>(null!) + contextRef.current = yield* Effect.context() + + // biome-ignore lint/correctness/useExhaustiveDependencies: use of React.DependencyList return React.useCallback((...args: Args) => Effect.runSyncWith(contextRef.current)(f(...args)), deps) }) +/** + * Effect hook that memoizes a function that returns an Effect, providing asynchronous execution. + * + * This hook wraps a function that returns an Effect and returns a memoized version that: + * - Executes the Effect asynchronously when called, returning a Promise + * - Is memoized based on the provided dependency array + * - Maintains referential equality across renders when dependencies don't change + * + * Use this to create stable callback references for async event handlers and other scenarios + * where you need to execute Effects asynchronously from non-Effect code. + * + * @param f - A function that accepts arguments and returns an Effect + * @param deps - Dependency array. The memoized function is recreated when dependencies change. + * + * @returns An Effect that produces a memoized function that returns a Promise + * + * @example + * ```tsx + * const MyComponent = Component.make(function* (props: { onSave: (data: Data) => void }) { + * const handleSave = yield* Component.useCallbackPromise( + * (data: Data) => Effect.promise(() => props.onSave(data)), + * [props.onSave], + * ) + * + * return + * }) + * ``` + */ export const useCallbackPromise = Effect.fnUntraced(function* ( f: (...args: Args) => Effect.Effect, deps: React.DependencyList, ): Effect.fn.Return<(...args: Args) => Promise, never, R> { - const context = yield* Effect.context() - const contextRef = React.useRef(context) - contextRef.current = context - // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies + // biome-ignore lint/style/noNonNullAssertion: context initialization + const contextRef = React.useRef>(null!) + contextRef.current = yield* Effect.context() + + // biome-ignore lint/correctness/useExhaustiveDependencies: use of React.DependencyList return React.useCallback((...args: Args) => Effect.runPromiseWith(contextRef.current)(f(...args)), deps) }) @@ -372,14 +1060,71 @@ export declare namespace useContext { export interface Options extends useOnChange.Options {} } +/** + * Effect hook that constructs an Effect Layer and returns the resulting context. + * + * This hook creates a managed runtime from the provided layer and returns the context it produces. + * The layer is reconstructed whenever its value changes, so ensure the layer reference is stable + * (typically by memoizing it or defining it outside the component). + * + * The hook automatically manages the layer's lifecycle: + * - The layer is built when the component mounts or when the layer reference changes + * - Resources are properly released when the component unmounts or dependencies change + * - Finalizers are executed according to the configured execution strategy + * + * @param layer - The Effect Layer to construct. Should be a stable reference to avoid unnecessary + * reconstruction. Consider memoizing with React.useMemo if defined inline. + * @param options - Configuration for scope and finalizer behavior + * + * @returns An Effect that produces the context created by the layer + * + * @throws If the layer contains asynchronous effects, the component must be wrapped with `Async.async` + * + * @example + * ```tsx + * const MyLayer = Layer.succeed(MyService, new MyServiceImpl()) + * const MyComponent = Component.make(function*() { + * const context = yield* Component.useContextFromLayer(MyLayer) + * const Sub = yield* SubComponent.use.pipe( + * Effect.provide(context) + * ) + * + * return + * }) + * ``` + * + * @example With memoized layer + * ```tsx + * const MyComponent = Component.make(function*(props: { id: string })) { + * const context = yield* Component.useContextFromLayer( + * React.useMemo(() => Layer.succeed(MyService, new MyServiceImpl(props.id)), [props.id]) + * ) + * const Sub = yield* SubComponent.use.pipe( + * Effect.provide(context) + * ) + * + * return + * }) + * ``` + * + * @example With async layer + * ```tsx + * const MyAsyncLayer = Layer.effect(MyService, someAsyncEffect) + * const MyComponent = Component.make(function*() { + * const context = yield* Component.useContextFromLayer(MyAsyncLayer) + * const Sub = yield* SubComponent.use.pipe( + * Effect.provide(context) + * ) + * + * return + * }).pipe( + * Async.async // Required to handle async layer effects + * ) + */ export const useContextFromLayer = ( layer: Layer.Layer, options?: useContext.Options, -): Effect.Effect, E, RIn | Scope.Scope> => useOnChange( - () => Effect.flatMap( - Effect.context(), - context => Layer.build(Layer.provide(layer, Layer.succeedContext(context))), - ), - [layer], - options, -) +): Effect.Effect, E, RIn | Scope.Scope> => useOnChange(() => Effect.flatMap( + Effect.context(), + context => Layer.build(Layer.provide(layer, Layer.succeedContext(context))), +), [layer], options) -- 2.52.0 From c8df30480a1f19da5d82d500cbf38a0bb734a45d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 22 Jun 2026 06:44:31 +0200 Subject: [PATCH 39/61] Fix --- packages/effect-fc-next/src/Component.ts | 100 +++++++++++------------ 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/packages/effect-fc-next/src/Component.ts b/packages/effect-fc-next/src/Component.ts index ed24870..a651525 100644 --- a/packages/effect-fc-next/src/Component.ts +++ b/packages/effect-fc-next/src/Component.ts @@ -1,6 +1,6 @@ /** biome-ignore-all lint/complexity/noBannedTypes: {} is the default type for React props */ /** biome-ignore-all lint/complexity/useArrowFunction: necessary for class prototypes */ -import { Context, type Duration, Effect, Equivalence, ExecutionStrategy, Exit, Fiber, Function, HashMap, identity, Layer, Option, Pipeable, Predicate, Ref, Runtime, Scope, Tracer, type Utils } from "effect" +import { Context, type Duration, Effect, Equivalence, ExecutionStrategy, Exit, Fiber, Function, HashMap, identity, Layer, Option, Pipeable, Predicate, Ref, Runtime, Scope, Tracer } from "effect" import * as React from "react" @@ -155,70 +155,70 @@ export const isComponent = (u: unknown): u is Component.Default<{}, React.ReactN export declare namespace make { export type Gen = { - >, A extends React.ReactNode, P extends {} = {}>( + , A extends React.ReactNode, P extends {} = {}>( body: (props: P) => Generator ): Component.Default< P, A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never > - >, A, B extends Effect.Effect, P extends {} = {}>( + , A, B extends Effect.Effect, P extends {} = {}>( body: (props: P) => Generator, a: ( _: Effect.Effect< A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never >, props: NoInfer

, ) => B, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> - >, A, B, C extends Effect.Effect, P extends {} = {}>( + ): Component.Default, Effect.Error, Effect.Services> + , A, B, C extends Effect.Effect, P extends {} = {}>( body: (props: P) => Generator, a: ( _: Effect.Effect< A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never >, props: NoInfer

, ) => B, b: (_: B, props: NoInfer

) => C, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> - >, A, B, C, D extends Effect.Effect, P extends {} = {}>( + ): Component.Default, Effect.Error, Effect.Services> + , A, B, C, D extends Effect.Effect, P extends {} = {}>( body: (props: P) => Generator, a: ( _: Effect.Effect< A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never >, props: NoInfer

, ) => B, b: (_: B, props: NoInfer

) => C, c: (_: C, props: NoInfer

) => D, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> - >, A, B, C, D, E extends Effect.Effect, P extends {} = {}>( + ): Component.Default, Effect.Error, Effect.Services> + , A, B, C, D, E extends Effect.Effect, P extends {} = {}>( body: (props: P) => Generator, a: ( _: Effect.Effect< A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never >, props: NoInfer

, ) => B, b: (_: B, props: NoInfer

) => C, c: (_: C, props: NoInfer

) => D, d: (_: D, props: NoInfer

) => E, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> - >, A, B, C, D, E, F extends Effect.Effect, P extends {} = {}>( + ): Component.Default, Effect.Error, Effect.Services> + , A, B, C, D, E, F extends Effect.Effect, P extends {} = {}>( body: (props: P) => Generator, a: ( _: Effect.Effect< A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never >, props: NoInfer

, ) => B, @@ -226,14 +226,14 @@ export declare namespace make { c: (_: C, props: NoInfer

) => D, d: (_: D, props: NoInfer

) => E, e: (_: E, props: NoInfer

) => F, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> - >, A, B, C, D, E, F, G extends Effect.Effect, P extends {} = {}>( + ): Component.Default, Effect.Error, Effect.Services> + , A, B, C, D, E, F, G extends Effect.Effect, P extends {} = {}>( body: (props: P) => Generator, a: ( _: Effect.Effect< A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never >, props: NoInfer

, ) => B, @@ -242,14 +242,14 @@ export declare namespace make { d: (_: D, props: NoInfer

) => E, e: (_: E, props: NoInfer

) => F, f: (_: F, props: NoInfer

) => G, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> - >, A, B, C, D, E, F, G, H extends Effect.Effect, P extends {} = {}>( + ): Component.Default, Effect.Error, Effect.Services> + , A, B, C, D, E, F, G, H extends Effect.Effect, P extends {} = {}>( body: (props: P) => Generator, a: ( _: Effect.Effect< A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never >, props: NoInfer

, ) => B, @@ -259,14 +259,14 @@ export declare namespace make { e: (_: E, props: NoInfer

) => F, f: (_: F, props: NoInfer

) => G, g: (_: G, props: NoInfer

) => H, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> - >, A, B, C, D, E, F, G, H, I extends Effect.Effect, P extends {} = {}>( + ): Component.Default, Effect.Error, Effect.Services> + , A, B, C, D, E, F, G, H, I extends Effect.Effect, P extends {} = {}>( body: (props: P) => Generator, a: ( _: Effect.Effect< A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never >, props: NoInfer

, ) => B, @@ -277,14 +277,14 @@ export declare namespace make { f: (_: F, props: NoInfer

) => G, g: (_: G, props: NoInfer

) => H, h: (_: H, props: NoInfer

) => I, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> - >, A, B, C, D, E, F, G, H, I, J extends Effect.Effect, P extends {} = {}>( + ): Component.Default, Effect.Error, Effect.Services> + , A, B, C, D, E, F, G, H, I, J extends Effect.Effect, P extends {} = {}>( body: (props: P) => Generator, a: ( _: Effect.Effect< A, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? E : never, - [Eff] extends [never] ? never : [Eff] extends [Utils.YieldWrap>] ? R : never + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? E : never, + [Eff] extends [never] ? never : [Eff] extends [Effect.Effect] ? R : never >, props: NoInfer

, ) => B, @@ -296,35 +296,35 @@ export declare namespace make { g: (_: G, props: NoInfer

) => H, h: (_: H, props: NoInfer

) => I, i: (_: I, props: NoInfer

) => J, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> } export type NonGen = { , P extends {} = {}>( body: (props: P) => Eff - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> , A, P extends {} = {}>( body: (props: P) => A, a: (_: A, props: NoInfer

) => Eff, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> , A, B, P extends {} = {}>( body: (props: P) => A, a: (_: A, props: NoInfer

) => B, b: (_: B, props: NoInfer

) => Eff, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> , A, B, C, P extends {} = {}>( body: (props: P) => A, a: (_: A, props: NoInfer

) => B, b: (_: B, props: NoInfer

) => C, c: (_: C, props: NoInfer

) => Eff, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> , A, B, C, D, P extends {} = {}>( body: (props: P) => A, a: (_: A, props: NoInfer

) => B, b: (_: B, props: NoInfer

) => C, c: (_: C, props: NoInfer

) => D, d: (_: D, props: NoInfer

) => Eff, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> , A, B, C, D, E, P extends {} = {}>( body: (props: P) => A, a: (_: A, props: NoInfer

) => B, @@ -332,7 +332,7 @@ export declare namespace make { c: (_: C, props: NoInfer

) => D, d: (_: D, props: NoInfer

) => E, e: (_: E, props: NoInfer

) => Eff, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> , A, B, C, D, E, F, P extends {} = {}>( body: (props: P) => A, a: (_: A, props: NoInfer

) => B, @@ -341,7 +341,7 @@ export declare namespace make { d: (_: D, props: NoInfer

) => E, e: (_: E, props: NoInfer

) => F, f: (_: F, props: NoInfer

) => Eff, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> , A, B, C, D, E, F, G, P extends {} = {}>( body: (props: P) => A, a: (_: A, props: NoInfer

) => B, @@ -351,7 +351,7 @@ export declare namespace make { e: (_: E, props: NoInfer

) => F, f: (_: F, props: NoInfer

) => G, g: (_: G, props: NoInfer

) => Eff, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> , A, B, C, D, E, F, G, H, P extends {} = {}>( body: (props: P) => A, a: (_: A, props: NoInfer

) => B, @@ -362,7 +362,7 @@ export declare namespace make { f: (_: F, props: NoInfer

) => G, g: (_: G, props: NoInfer

) => H, h: (_: H, props: NoInfer

) => Eff, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> , A, B, C, D, E, F, G, H, I, P extends {} = {}>( body: (props: P) => A, a: (_: A, props: NoInfer

) => B, @@ -374,7 +374,7 @@ export declare namespace make { g: (_: G, props: NoInfer

) => H, h: (_: H, props: NoInfer

) => I, i: (_: I, props: NoInfer

) => Eff, - ): Component.Default>, Effect.Effect.Error, Effect.Effect.Context> + ): Component.Default, Effect.Error, Effect.Services> } } -- 2.52.0 From 6b5c501a98bb63ec56688525d90718577f361b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 23 Jun 2026 03:25:58 +0200 Subject: [PATCH 40/61] Refactor --- packages/effect-fc-next/src/Component.ts | 10 ++-- packages/effect-fc-next/src/ReactRuntime.ts | 51 ++++++++++++--------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/packages/effect-fc-next/src/Component.ts b/packages/effect-fc-next/src/Component.ts index a651525..12002ad 100644 --- a/packages/effect-fc-next/src/Component.ts +++ b/packages/effect-fc-next/src/Component.ts @@ -1,6 +1,6 @@ /** biome-ignore-all lint/complexity/noBannedTypes: {} is the default type for React props */ /** biome-ignore-all lint/complexity/useArrowFunction: necessary for class prototypes */ -import { Context, type Duration, Effect, Equivalence, ExecutionStrategy, Exit, Fiber, Function, HashMap, identity, Layer, Option, Pipeable, Predicate, Ref, Runtime, Scope, Tracer } from "effect" +import { Context, type Duration, Effect, Equivalence, ExecutionStrategy, Exit, Fiber, Function, HashMap, identity, Layer, Option, Pipeable, Predicate, Ref, Scope, Tracer } from "effect" import * as React from "react" @@ -609,18 +609,18 @@ export const withOptions: { */ export const withRuntime: {

( - context: React.Context>, + context: React.Context>, ): (self: Component, F>) => F

( self: Component, F>, - context: React.Context>, + context: React.Context>, ): F } = Function.dual(2,

( self: Component, - context: React.Context>, + context: React.Context>, ) => function WithRuntime(props: P) { return React.createElement( - Runtime.runSync(React.useContext(context))(self.use) as React.FC

, + Effect.runSyncWith(React.useContext(context))(self.use) as React.FC

, props, ) }) diff --git a/packages/effect-fc-next/src/ReactRuntime.ts b/packages/effect-fc-next/src/ReactRuntime.ts index 92f9108..2c40a78 100644 --- a/packages/effect-fc-next/src/ReactRuntime.ts +++ b/packages/effect-fc-next/src/ReactRuntime.ts @@ -1,41 +1,52 @@ -/** biome-ignore-all lint/complexity/useArrowFunction: React component names are intentional */ -import { Context, Layer, ManagedRuntime, Predicate } from "effect" +/** biome-ignore-all lint/complexity/useArrowFunction: necessary for class prototypes */ +import { type Context, Effect, Layer, ManagedRuntime, Predicate } from "effect" import * as React from "react" +import * as Component from "./Component.js" import * as ErrorObserver from "./ErrorObserver.js" import * as QueryClient from "./QueryClient.js" -export const TypeId: unique symbol = Symbol.for("@effect-fc/ReactRuntime/ReactRuntime") -export type TypeId = typeof TypeId +export const ReactRuntimeTypeId: unique symbol = Symbol.for("@effect-fc/ReactRuntime/ReactRuntime") +export type ReactRuntimeTypeId = typeof ReactRuntimeTypeId export interface ReactRuntime { new(_: never): Record - readonly [TypeId]: TypeId + readonly [ReactRuntimeTypeId]: ReactRuntimeTypeId readonly runtime: ManagedRuntime.ManagedRuntime readonly context: React.Context> } -const ReactRuntimeProto = Object.freeze({ [TypeId]: TypeId } as const) +const ReactRuntimeProto = Object.freeze({ [ReactRuntimeTypeId]: ReactRuntimeTypeId } as const) -export const Prelude: Layer.Layer = Layer.merge( +export const preludeLayer: Layer.Layer< + | Component.ScopeMap + | ErrorObserver.ErrorObserver + | QueryClient.QueryClient +> = Layer.mergeAll( + Component.ScopeMap.layer, ErrorObserver.layer, QueryClient.QueryClient.Default, ) + export const isReactRuntime = (u: unknown): u is ReactRuntime => Predicate.hasProperty(u, TypeId) export const make = ( layer: Layer.Layer, memoMap?: Layer.MemoMap, -): ReactRuntime => Object.setPrototypeOf( +): ReactRuntime | R, ER> => Object.setPrototypeOf( Object.assign(function() {}, { - runtime: ManagedRuntime.make(Layer.merge(layer, Prelude), { memoMap }), - // biome-ignore lint/style/noNonNullAssertion: initialized by Provider before consumers render - context: React.createContext>(null!), + runtime: ManagedRuntime.make( + Layer.merge(layer, preludeLayer), + memoMap, + ), + // biome-ignore lint/style/noNonNullAssertion: context initialization + context: React.createContext>(null!), }), ReactRuntimeProto, ) + export namespace Provider { export interface Props extends React.SuspenseProps { readonly runtime: ReactRuntime @@ -44,8 +55,13 @@ export namespace Provider { } export const Provider = ( - { runtime, children, ...suspenseProps }: Provider.Props, + { runtime, children, ...suspenseProps }: Provider.Props ): React.ReactNode => { + Effect.runSync(Component.useOnChange( + () => Effect.addFinalizer(() => runtime.runtime.disposeEffect), + [runtime], + )) + const promise = React.useMemo(() => runtime.runtime.context(), [runtime]) return React.createElement( @@ -60,12 +76,5 @@ const ProviderInner = ( readonly runtime: ReactRuntime readonly promise: Promise> readonly children?: React.ReactNode - }, -): React.ReactNode => { - const context = React.use(promise) - React.useEffect(() => () => { - void runtime.runtime.dispose() - }, [runtime]) - - return React.createElement(runtime.context, { value: context }, children) -} + } +): React.ReactNode => React.createElement(runtime.context, { value: React.use(promise) }, children) -- 2.52.0 From 24ce5430924e2279f5369e4c3982ac65026b9c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 23 Jun 2026 03:32:13 +0200 Subject: [PATCH 41/61] Fix --- packages/effect-fc-next/src/Component.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/effect-fc-next/src/Component.ts b/packages/effect-fc-next/src/Component.ts index 12002ad..37b7cb8 100644 --- a/packages/effect-fc-next/src/Component.ts +++ b/packages/effect-fc-next/src/Component.ts @@ -1,6 +1,6 @@ /** biome-ignore-all lint/complexity/noBannedTypes: {} is the default type for React props */ /** biome-ignore-all lint/complexity/useArrowFunction: necessary for class prototypes */ -import { Context, type Duration, Effect, Equivalence, ExecutionStrategy, Exit, Fiber, Function, HashMap, identity, Layer, Option, Pipeable, Predicate, Ref, Scope, Tracer } from "effect" +import { Context, type Duration, Effect, Equivalence, Exit, Fiber, Function, HashMap, identity, Layer, Option, Pipeable, Predicate, Ref, Scope, Tracer } from "effect" import * as React from "react" @@ -130,9 +130,9 @@ export interface ComponentOptions { * Specifies the execution strategy for finalizers when the component unmounts or its scope closes. * Determines whether finalizers execute sequentially or in parallel. * - * @default ExecutionStrategy.sequential + * @default "sequential" */ - readonly finalizerExecutionStrategy: ExecutionStrategy.ExecutionStrategy + readonly finalizerExecutionStrategy: "sequential" | "parallel" /** * Debounce duration before executing finalizers after component unmount. @@ -146,7 +146,7 @@ export interface ComponentOptions { export const defaultOptions: ComponentOptions = { nonReactiveTags: [Tracer.ParentSpan], - finalizerExecutionStrategy: ExecutionStrategy.sequential, + finalizerExecutionStrategy: "sequential", finalizerExecutionDebounce: "100 millis", } @@ -653,7 +653,7 @@ export declare namespace ScopeMap { export declare namespace useScope { export interface Options { - readonly finalizerExecutionStrategy?: ExecutionStrategy.ExecutionStrategy + readonly finalizerExecutionStrategy?: "sequential" | "parallel" readonly finalizerExecutionDebounce?: Duration.Input } } @@ -805,7 +805,7 @@ export const useOnChange = Effect.fnUntraced(function* ( export declare namespace useReactEffect { export interface Options { readonly finalizerExecutionMode?: "sync" | "fork" - readonly finalizerExecutionStrategy?: ExecutionStrategy.ExecutionStrategy + readonly finalizerExecutionStrategy?: "sequential" | "parallel" } } -- 2.52.0 From a86cb7e024de92dbbfaf5c8b1797417c71f0e0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 23 Jun 2026 03:57:56 +0200 Subject: [PATCH 42/61] Refactor Component --- packages/effect-fc-next/src/Component.new.ts | 385 ------------------- packages/effect-fc-next/src/Component.ts | 28 +- 2 files changed, 19 insertions(+), 394 deletions(-) delete mode 100644 packages/effect-fc-next/src/Component.new.ts diff --git a/packages/effect-fc-next/src/Component.new.ts b/packages/effect-fc-next/src/Component.new.ts deleted file mode 100644 index a8f3d4a..0000000 --- a/packages/effect-fc-next/src/Component.new.ts +++ /dev/null @@ -1,385 +0,0 @@ -/** biome-ignore-all lint/complexity/noBannedTypes: {} is the default type for React props */ -import { - type Context, - type Duration, - Effect, - Exit, - Function, - identity, - Layer, - Pipeable, - Predicate, - Scope, - Tracer, -} from "effect" -import * as React from "react" - - -export const ComponentTypeId: unique symbol = Symbol.for("@effect-fc/Component/Component") -export type ComponentTypeId = typeof ComponentTypeId - -export interface Component

-extends ComponentPrototype, ComponentOptions { - new(_: never): Record - readonly [ComponentTypeId]: ComponentTypeId - readonly "~Props": P - readonly "~Success": A - readonly "~Error": E - readonly "~Context": R - readonly "~Function": F - readonly body: (props: P) => Effect.Effect -} - -export declare namespace Component { - export type Default

= Component> - export type Any = Component - export type Signature = (props: any) => React.ReactNode - export type DefaultSignature

= (props: P) => A - export type Props = T["~Props"] - export type Success = T["~Success"] - export type Error = T["~Error"] - export type Context = T["~Context"] - export type Function = T["~Function"] - export type AsComponent = Component, Success, Error, Context, Function> -} - -export interface ComponentOptions { - readonly displayName?: string - readonly nonReactiveTags: readonly Context.Key[] - readonly finalizerExecutionStrategy: "sequential" | "parallel" - readonly finalizerExecutionDebounce: Duration.Input -} - -export const defaultOptions: ComponentOptions = { - nonReactiveTags: [Tracer.ParentSpan], - finalizerExecutionStrategy: "sequential", - finalizerExecutionDebounce: "100 millis", -} - -export interface ComponentPrototype extends Pipeable.Pipeable { - readonly [ComponentTypeId]: ComponentTypeId - readonly use: Effect.Effect> -} - -type ComponentImpl = Component - -const makeFunctionComponent = ( - self: ComponentImpl, - contextRef: React.RefObject>, -): Component.Signature => { - if ("asFunctionComponent" in self && typeof self.asFunctionComponent === "function") { - return self.asFunctionComponent(contextRef) - } - const FunctionComponent = (props: {}) => Effect.runSyncWith(contextRef.current)( - Effect.flatMap( - useScope([], self), - scope => Effect.provideService(self.body(props), Scope.Scope, scope), - ), - ) - FunctionComponent.displayName = self.displayName ?? "Anonymous" - return "transformFunctionComponent" in self && typeof self.transformFunctionComponent === "function" - ? self.transformFunctionComponent(FunctionComponent) - : FunctionComponent -} - -const use = Effect.fnUntraced(function* (self: ComponentImpl) { - const context = yield* Effect.context() - const cached = componentCache.get(self) - if (cached !== undefined) { - cached.contextRef.current = context - return cached.component - } - const contextRef = { current: context } - const component = makeFunctionComponent(self, contextRef) - componentCache.set(self, { contextRef, component }) - return component -}) - -const componentCache = new WeakMap } - readonly component: Component.Signature -}>() - -export const ComponentPrototype = Object.freeze({ - [ComponentTypeId]: ComponentTypeId, - ...Pipeable.Prototype, - get use() { - return use(this as ComponentImpl) - }, -}) as unknown as ComponentPrototype - -export const isComponent = (u: unknown): u is Component.Any => Predicate.hasProperty(u, ComponentTypeId) - -type GeneratorBody

= ( - props: P, -) => Effect.fn.Return - -type EffectBody

= ( - props: P, -) => Effect.Effect - -export interface Make { -

( - body: GeneratorBody | EffectBody, - ...pipeables: readonly Function[] - ): Component.Default - (name: string, options?: Tracer.SpanOptionsNoTrace):

( - body: GeneratorBody | EffectBody, - ...pipeables: readonly Function[] - ) => Component.Default -} - -const component = ( - body: Function, - displayName: string | undefined, - traced: boolean, - pipeables: readonly Function[], -): Component.Any => Object.setPrototypeOf( - Object.assign(() => {}, defaultOptions, { - body: traced && displayName - ? Effect.fn(displayName)(body as never, ...pipeables as []) - : Effect.fnUntraced(body as never, ...pipeables as []), - displayName, - }), - ComponentPrototype, -) - -export const make: Make = ((nameOrBody: string | Function, ...args: readonly unknown[]) => { - if (typeof nameOrBody === "string") { - return (body: Function, ...pipeables: readonly Function[]) => component(body, nameOrBody, true, pipeables) - } - return component(nameOrBody, undefined, true, args as readonly Function[]) -}) as Make - -export const makeUntraced: Make = ((nameOrBody: string | Function, ...args: readonly unknown[]) => { - if (typeof nameOrBody === "string") { - return (body: Function, ...pipeables: readonly Function[]) => component(body, nameOrBody, false, pipeables) - } - return component(nameOrBody, undefined, false, args as readonly Function[]) -}) as Make - -export declare namespace withSignature { - export type Result = ( - & Omit> - & Component, Component.Success, Component.Error, Component.Context, F> - ) -} - -export const withSignature: { - (): (self: T) => withSignature.Result - (self: T): withSignature.Result -} = (self?: Component.Any): any => self === undefined ? identity : self - -export const withOptions: { - (options: Partial): (self: T) => T - (self: T, options: Partial): T -} = Function.dual(2, (self: T, options: Partial): T => Object.setPrototypeOf( - Object.assign(() => {}, self, options), - Object.getPrototypeOf(self), -)) - -export const withRuntime: { -

( - context: React.Context>, - ): (self: Component, F>) => F -

( - self: Component, F>, - context: React.Context>, - ): F -} = Function.dual(2,

( - self: Component, - context: React.Context>, -) => function WithRuntime(props: P) { - return React.createElement( - Effect.runSyncWith(React.useContext(context))(self.use) as React.FC

, - props, - ) -}) - -export declare namespace useScope { - export interface Options { - readonly finalizerExecutionStrategy?: "sequential" | "parallel" - readonly finalizerExecutionDebounce?: Duration.Input - } -} - -export const useScope = Effect.fnUntraced(function* ( - deps: React.DependencyList, - options?: useScope.Options, -): Effect.fn.Return { - const context = yield* Effect.context() - const contextRef = React.useRef(context) - contextRef.current = context - const scope = React.useMemo( - () => Scope.makeUnsafe(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy), - // biome-ignore lint/correctness/useExhaustiveDependencies: caller controls scope lifetime - deps, - ) - - React.useEffect(() => { - const pending = scopeCleanupTimers.get(scope) - if (pending !== undefined) clearTimeout(pending) - return () => { - const timer = setTimeout(() => { - Effect.runSyncWith(contextRef.current)(Scope.close(scope, Exit.succeed(undefined))) - scopeCleanupTimers.delete(scope) - }, durationMillis(options?.finalizerExecutionDebounce ?? defaultOptions.finalizerExecutionDebounce)) - scopeCleanupTimers.set(scope, timer) - } - }, [scope, options?.finalizerExecutionDebounce]) - - return scope -}) - -const scopeCleanupTimers = new WeakMap>() - -const durationMillis = (input: Duration.Input): number => { - if (typeof input === "number") return input - return Number(Effect.runSync(Effect.map(Effect.succeed(input), value => { - const match = typeof value === "string" ? /([\d.]+)\s*(millis|seconds?)/.exec(value) : undefined - if (!match) return 0 - return Number(match[1]) * (match[2].startsWith("second") ? 1_000 : 1) - }))) -} - -export const useOnMount = Effect.fnUntraced(function* ( - f: () => Effect.Effect, -): Effect.fn.Return { - const context = yield* Effect.context() - const id = React.useId() - let cached = mountCache.get(id) - if (cached === undefined) { - cached = { - effect: Effect.runSyncWith(context)(Effect.cached(f())), - } - mountCache.set(id, cached) - } - React.useEffect(() => { - if (cached?.cleanup !== undefined) clearTimeout(cached.cleanup) - const entry = cached - return () => { - entry.cleanup = setTimeout(() => mountCache.delete(id), 0) - } - }, [id, cached]) - return yield* cached.effect as Effect.Effect -}) - -const mountCache = new Map - cleanup?: ReturnType -}>() - -export declare namespace useOnChange { - export interface Options extends useScope.Options {} -} - -export const useOnChange = Effect.fnUntraced(function* ( - f: () => Effect.Effect, - deps: React.DependencyList, - options?: useOnChange.Options, -): Effect.fn.Return> { - const context = yield* Effect.context>() - const scope = yield* useScope(deps, options) - const cached = - // biome-ignore lint/correctness/useExhaustiveDependencies: scope tracks the caller-provided dependency list - React.useMemo( - () => Effect.runSyncWith(context)(Effect.cached(Effect.provideService(f(), Scope.Scope, scope))), - [scope], - ) - return yield* cached -}) - -export declare namespace useReactEffect { - export interface Options { - readonly finalizerExecutionMode?: "sync" | "fork" - readonly finalizerExecutionStrategy?: "sequential" | "parallel" - } -} - -const runReactEffect = ( - context: Context.Context>, - f: () => Effect.Effect, - options?: useReactEffect.Options, -): (() => void) => { - const scope = Scope.makeUnsafe(options?.finalizerExecutionStrategy ?? defaultOptions.finalizerExecutionStrategy) - Effect.runSyncWith(context)(Effect.exit(Effect.provideService(f(), Scope.Scope, scope))) - return () => { - const close = Scope.close(scope, Exit.succeed(undefined)) - if ((options?.finalizerExecutionMode ?? "fork") === "sync") Effect.runSyncWith(context)(close) - else Effect.runForkWith(context)(close) - } -} - -export const useReactEffect = Effect.fnUntraced(function* ( - f: () => Effect.Effect, - deps?: React.DependencyList, - options?: useReactEffect.Options, -): Effect.fn.Return> { - const context = yield* Effect.context>() - // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies - React.useEffect(() => runReactEffect(context, f, options), deps) -}) - -export declare namespace useReactLayoutEffect { - export interface Options extends useReactEffect.Options {} -} - -export const useReactLayoutEffect = Effect.fnUntraced(function* ( - f: () => Effect.Effect, - deps?: React.DependencyList, - options?: useReactLayoutEffect.Options, -): Effect.fn.Return> { - const context = yield* Effect.context>() - // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies - React.useLayoutEffect(() => runReactEffect(context, f, options), deps) -}) - -export const useRunSync = (): Effect.Effect< - (effect: Effect.Effect) => A, - never, - R -> => Effect.map(Effect.context(), Effect.runSyncWith) - -export const useRunPromise = (): Effect.Effect< - (effect: Effect.Effect) => Promise, - never, - R -> => Effect.map(Effect.context(), Effect.runPromiseWith) - -export const useCallbackSync = Effect.fnUntraced(function* ( - f: (...args: Args) => Effect.Effect, - deps: React.DependencyList, -): Effect.fn.Return<(...args: Args) => A, never, R> { - const context = yield* Effect.context() - const contextRef = React.useRef(context) - contextRef.current = context - // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies - return React.useCallback((...args: Args) => Effect.runSyncWith(contextRef.current)(f(...args)), deps) -}) - -export const useCallbackPromise = Effect.fnUntraced(function* ( - f: (...args: Args) => Effect.Effect, - deps: React.DependencyList, -): Effect.fn.Return<(...args: Args) => Promise, never, R> { - const context = yield* Effect.context() - const contextRef = React.useRef(context) - contextRef.current = context - // biome-ignore lint/correctness/useExhaustiveDependencies: caller supplies React dependencies - return React.useCallback((...args: Args) => Effect.runPromiseWith(contextRef.current)(f(...args)), deps) -}) - -export declare namespace useContext { - export interface Options extends useOnChange.Options {} -} - -export const useContextFromLayer = ( - layer: Layer.Layer, - options?: useContext.Options, -): Effect.Effect, E, RIn | Scope.Scope> => useOnChange( - () => Effect.flatMap( - Effect.context(), - context => Layer.build(Layer.provide(layer, Layer.succeedContext(context))), - ), - [layer], - options, -) diff --git a/packages/effect-fc-next/src/Component.ts b/packages/effect-fc-next/src/Component.ts index 37b7cb8..aadc0a9 100644 --- a/packages/effect-fc-next/src/Component.ts +++ b/packages/effect-fc-next/src/Component.ts @@ -83,16 +83,26 @@ const use = Effect.fnUntraced(function*

>>(null!) contextRef.current = yield* Effect.context>() - return yield* React.useState(() => Effect.runSyncWith(contextRef.current)(Effect.cachedFunction( - (_services: readonly any[]) => Effect.sync(() => { - const f = self.asFunctionComponent(contextRef) - self.setFunctionComponentName(f) - return self.transformFunctionComponent(f) - }), - Equivalence.array(Equivalence.strictEqual()), - )))[0](Array.from( + const componentRef = React.useRef(null) + const previousServicesRef = React.useRef(null) + + const services = Array.from( Context.omit(...self.nonReactiveTags)(contextRef.current).mapUnsafe.values() - )) + ) + + if ( + !componentRef.current || + !previousServicesRef.current || + services.length !== previousServicesRef.current.length || + !Equivalence.Array(Equivalence.strictEqual())(services, previousServicesRef.current) + ) { + previousServicesRef.current = services + const f = self.asFunctionComponent(contextRef) + self.setFunctionComponentName(f) + componentRef.current = self.transformFunctionComponent(f) + } + + return componentRef.current }) -- 2.52.0 From 65fcfb395eca66c28728080501dc544ded11ef55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 23 Jun 2026 04:08:49 +0200 Subject: [PATCH 43/61] Refactor --- packages/effect-fc-next/src/Async.ts | 4 ++-- packages/effect-fc-next/src/Component.ts | 2 +- packages/effect-fc-next/src/ReactRuntime.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/effect-fc-next/src/Async.ts b/packages/effect-fc-next/src/Async.ts index 6495308..58b7f5a 100644 --- a/packages/effect-fc-next/src/Async.ts +++ b/packages/effect-fc-next/src/Async.ts @@ -1,5 +1,5 @@ /** biome-ignore-all lint/complexity/useArrowFunction: necessary for class prototypes */ -import { Context, Effect, type Equivalence, Function, Predicate, Scope } from "effect" +import { type Context, Effect, type Equivalence, Function, Predicate, Scope } from "effect" import * as React from "react" import * as Component from "./Component.js" @@ -45,7 +45,7 @@ export const AsyncPrototype: AsyncPrototype = Object.freeze({ return ({ fallback, name, ...props }: AsyncProps) => { const promise = Effect.runPromiseWith(contextRef.current)( - Effect.andThen( + Effect.flatMap( Component.useScope([], this), scope => Effect.provideService(this.body(props as P), Scope.Scope, scope), ) diff --git a/packages/effect-fc-next/src/Component.ts b/packages/effect-fc-next/src/Component.ts index aadc0a9..bec0610 100644 --- a/packages/effect-fc-next/src/Component.ts +++ b/packages/effect-fc-next/src/Component.ts @@ -59,7 +59,7 @@ export const ComponentImplPrototype: ComponentImplPrototype = Object.f contextRef: React.RefObject>>, ) { return (props: P) => Effect.runSyncWith(contextRef.current)( - Effect.andThen( + Effect.flatMap( useScope([], this), scope => Effect.provideService(this.body(props), Scope.Scope, scope), ) diff --git a/packages/effect-fc-next/src/ReactRuntime.ts b/packages/effect-fc-next/src/ReactRuntime.ts index 2c40a78..4413e3e 100644 --- a/packages/effect-fc-next/src/ReactRuntime.ts +++ b/packages/effect-fc-next/src/ReactRuntime.ts @@ -29,16 +29,16 @@ export const preludeLayer: Layer.Layer< ) -export const isReactRuntime = (u: unknown): u is ReactRuntime => Predicate.hasProperty(u, TypeId) +export const isReactRuntime = (u: unknown): u is ReactRuntime => Predicate.hasProperty(u, ReactRuntimeTypeId) export const make = ( layer: Layer.Layer, memoMap?: Layer.MemoMap, -): ReactRuntime | R, ER> => Object.setPrototypeOf( +): ReactRuntime | R, ER> => Object.setPrototypeOf( Object.assign(function() {}, { runtime: ManagedRuntime.make( Layer.merge(layer, preludeLayer), - memoMap, + { memoMap }, ), // biome-ignore lint/style/noNonNullAssertion: context initialization context: React.createContext>(null!), -- 2.52.0 From 5945953555685d5288b2588b70303490282ea84e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 24 Jun 2026 00:54:10 +0200 Subject: [PATCH 44/61] Refactor QueryClient --- packages/effect-fc-next/src/QueryClient.ts | 167 ++++++++++----------- 1 file changed, 79 insertions(+), 88 deletions(-) diff --git a/packages/effect-fc-next/src/QueryClient.ts b/packages/effect-fc-next/src/QueryClient.ts index b811138..61dcf59 100644 --- a/packages/effect-fc-next/src/QueryClient.ts +++ b/packages/effect-fc-next/src/QueryClient.ts @@ -1,24 +1,8 @@ -import { - Context, - DateTime, - Duration, - Effect, - Equal, - Equivalence, - Hash, - HashMap, - Layer, - Option, - Pipeable, - Predicate, - Schedule, - Scope, - Semaphore, - SubscriptionRef, -} from "effect" -import { Subscribable } from "effect-lens" +import { type Cause, Context, DateTime, Duration, Effect, Equal, Equivalence, Hash, HashMap, type Option, Pipeable, Predicate, Schedule, type Scope, Semaphore, SubscriptionRef } from "effect" +import type { AsyncResult } from "effect/unstable/reactivity" +import * as Lens from "./Lens.js" import type * as Query from "./Query.js" -import type * as Result from "./Result.js" +import type * as Subscribable from "./Subscribable.js" export const QueryClientServiceTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientService") @@ -26,89 +10,87 @@ export type QueryClientServiceTypeId = typeof QueryClientServiceTypeId export interface QueryClientService extends Pipeable.Pipeable { readonly [QueryClientServiceTypeId]: QueryClientServiceTypeId + readonly cache: Subscribable.Subscribable> - readonly cacheGcTime: Duration.Input - readonly defaultStaleTime: Duration.Input + readonly cacheGcTime: Duration.Duration + readonly defaultStaleTime: Duration.Duration readonly defaultRefreshOnWindowFocus: boolean - readonly run: Effect.Effect + + readonly run: Effect.Effect getCacheEntry(key: QueryClientCacheKey): Effect.Effect> - setCacheEntry(key: QueryClientCacheKey, result: Result.Success, staleTime: Duration.Input): Effect.Effect + setCacheEntry( + key: QueryClientCacheKey, + result: AsyncResult.Success, + staleTime: Duration.Duration, + ): Effect.Effect invalidateCacheEntries(f: (key: Query.Query.AnyKey) => Effect.Effect): Effect.Effect invalidateCacheEntry(key: QueryClientCacheKey): Effect.Effect } export class QueryClient extends Context.Service()( - "@effect-fc/QueryClient/QueryClient", -) { - static get Default(): Layer.Layer { - return Layer.effect(QueryClient)(service()) - } -} + "@effect-fc/QueryClient/QueryClient" +) {} -export class QueryClientServiceImpl extends Pipeable.Class implements QueryClientService { +export class QueryClientServiceImpl +extends Pipeable.Class +implements QueryClientService { readonly [QueryClientServiceTypeId]: QueryClientServiceTypeId = QueryClientServiceTypeId - readonly cache: Subscribable.Subscribable> constructor( - readonly cacheRef: SubscriptionRef.SubscriptionRef>, - readonly cacheGcTime: Duration.Input, - readonly defaultStaleTime: Duration.Input, + readonly cache: Lens.Lens>, + readonly cacheGcTime: Duration.Duration, + readonly defaultStaleTime: Duration.Duration, readonly defaultRefreshOnWindowFocus: boolean, readonly runSemaphore: Semaphore.Semaphore, ) { super() - this.cache = Subscribable.make({ - get: SubscriptionRef.get(cacheRef), - changes: SubscriptionRef.changes(cacheRef), - }) } - get run(): Effect.Effect { + get run(): Effect.Effect { return this.runSemaphore.withPermits(1)(Effect.repeat( - Effect.flatMap(DateTime.now, now => SubscriptionRef.update(this.cacheRef, HashMap.filter(entry => - Duration.isLessThan( - DateTime.distance(entry.lastAccessedAt, now), - Duration.sum(Duration.fromInputUnsafe(entry.staleTime), Duration.fromInputUnsafe(this.cacheGcTime)), - ) - ))), - Schedule.spaced("30 seconds"), + Effect.flatMap( + DateTime.now, + now => Lens.update(this.cache, HashMap.filter(entry => + Duration.isLessThan( + DateTime.distance(entry.lastAccessedAt, now), + Duration.sum(entry.staleTime, this.cacheGcTime), + ) + )), + ), + Schedule.spaced("30 second"), )) } getCacheEntry(key: QueryClientCacheKey): Effect.Effect> { - const self = this - return Effect.gen(function*() { - const entry = HashMap.get(yield* SubscriptionRef.get(self.cacheRef), key) - if (Option.isNone(entry)) return Option.none() - const now = yield* DateTime.now - const accessed = new QueryClientCacheEntry( - entry.value.result, - entry.value.staleTime, - entry.value.createdAt, - now, - ) - yield* SubscriptionRef.update(self.cacheRef, HashMap.set(key, accessed)) - return Option.some(accessed) - }) + return Effect.all([ + DateTime.now, + Effect.flatMap( + Effect.map(Lens.get(this.cache), HashMap.get(key)), + Effect.fromOption, + ), + ]).pipe( + Effect.map(([now, entry]) => new QueryClientCacheEntry(entry.result, entry.staleTime, entry.createdAt, now)), + Effect.tap(entry => Lens.update(this.cache, HashMap.set(key, entry))), + Effect.option, + ) } setCacheEntry( key: QueryClientCacheKey, - result: Result.Success, - staleTime: Duration.Input, + result: AsyncResult.Success, + staleTime: Duration.Duration, ): Effect.Effect { - return Effect.flatMap(DateTime.now, now => { - const entry = new QueryClientCacheEntry(result, staleTime, now, now) - return Effect.as(SubscriptionRef.update(this.cacheRef, HashMap.set(key, entry)), entry) - }) + return DateTime.now.pipe( + Effect.map(now => new QueryClientCacheEntry(result, staleTime, now, now)), + Effect.tap(entry => Lens.update(this.cache, HashMap.set(key, entry))), + ) } invalidateCacheEntries(f: (key: Query.Query.AnyKey) => Effect.Effect): Effect.Effect { - return SubscriptionRef.update(this.cacheRef, HashMap.filter((_, key) => !Equivalence.strictEqual()(key.f, f))) + return Lens.update(this.cache, HashMap.filter((_, key) => !Equivalence.strictEqual()(key.f, f))) } - invalidateCacheEntry(key: QueryClientCacheKey): Effect.Effect { - return SubscriptionRef.update(this.cacheRef, HashMap.remove(key)) + return Lens.update(this.cache, HashMap.remove(key)) } } @@ -122,11 +104,13 @@ export declare namespace make { } } -export const make = Effect.fnUntraced(function* (options: make.Options = {}): Effect.fn.Return { +export const make = Effect.fnUntraced(function* ( + options: make.Options = {} +): Effect.fn.Return { return new QueryClientServiceImpl( - yield* SubscriptionRef.make(HashMap.empty()), - options.cacheGcTime ?? "5 minutes", - options.defaultStaleTime ?? "0 minutes", + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(HashMap.empty())), + yield* Effect.fromOption(Duration.fromInput(options.cacheGcTime ?? "5 minutes")), + yield* Effect.fromOption(Duration.fromInput(options.defaultStaleTime ?? "0 minutes")), options.defaultRefreshOnWindowFocus ?? true, yield* Semaphore.make(1), ) @@ -136,15 +120,20 @@ export declare namespace service { export interface Options extends make.Options {} } -export const service = (options?: service.Options): Effect.Effect => Effect.tap( +export const service = ( + options?: service.Options +): Effect.Effect => Effect.tap( make(options), - client => Effect.asVoid(Effect.forkScoped(client.run)), + client => Effect.forkScoped(client.run), ) + export const QueryClientCacheKeyTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientCacheKey") export type QueryClientCacheKeyTypeId = typeof QueryClientCacheKeyTypeId -export class QueryClientCacheKey extends Pipeable.Class implements Equal.Equal { +export class QueryClientCacheKey +extends Pipeable.Class +implements Pipeable.Pipeable, Equal.Equal { readonly [QueryClientCacheKeyTypeId]: QueryClientCacheKeyTypeId = QueryClientCacheKeyTypeId constructor( @@ -154,28 +143,28 @@ export class QueryClientCacheKey extends Pipeable.Class implements Equal.Equal { super() } - [Equal.symbol](that: Equal.Equal): boolean { - return isQueryClientCacheKey(that) - && Equivalence.Array(Equal.asEquivalence())(this.key, that.key) - && Equivalence.strictEqual()(this.f, that.f) + [Equal.symbol](that: Equal.Equal) { + return isQueryClientCacheKey(that) && Equivalence.Array(Equal.asEquivalence())(this.key, that.key) && Equivalence.strictEqual()(this.f, that.f) } - - [Hash.symbol](): number { + [Hash.symbol]() { return Hash.combine(Hash.hash(this.f))(Hash.array(this.key)) } } export const isQueryClientCacheKey = (u: unknown): u is QueryClientCacheKey => Predicate.hasProperty(u, QueryClientCacheKeyTypeId) + export const QueryClientCacheEntryTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientCacheEntry") export type QueryClientCacheEntryTypeId = typeof QueryClientCacheEntryTypeId -export class QueryClientCacheEntry extends Pipeable.Class { +export class QueryClientCacheEntry +extends Pipeable.Class +implements Pipeable.Pipeable { readonly [QueryClientCacheEntryTypeId]: QueryClientCacheEntryTypeId = QueryClientCacheEntryTypeId constructor( - readonly result: Result.Success, - readonly staleTime: Duration.Input, + readonly result: AsyncResult.Success, + readonly staleTime: Duration.Duration, readonly createdAt: DateTime.DateTime, readonly lastAccessedAt: DateTime.DateTime, ) { @@ -185,7 +174,9 @@ export class QueryClientCacheEntry extends Pipeable.Class { export const isQueryClientCacheEntry = (u: unknown): u is QueryClientCacheEntry => Predicate.hasProperty(u, QueryClientCacheEntryTypeId) -export const isQueryClientCacheEntryStale = (self: QueryClientCacheEntry): Effect.Effect => Effect.map( +export const isQueryClientCacheEntryStale = ( + self: QueryClientCacheEntry +): Effect.Effect => Effect.map( DateTime.now, - now => Duration.isGreaterThanOrEqualTo(DateTime.distance(self.createdAt, now), Duration.fromInputUnsafe(self.staleTime)), + now => Duration.isGreaterThanOrEqualTo(DateTime.distance(self.createdAt, now), self.staleTime), ) -- 2.52.0 From 015aa0c8167a99662c947d1549b89bdc6c0a4cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Thu, 25 Jun 2026 04:37:14 +0200 Subject: [PATCH 45/61] Refactor Query --- bun.lock | 3 + packages/effect-fc-next/package.json | 1 + packages/effect-fc-next/src/Query.ts | 387 +++++++++++++++------------ 3 files changed, 224 insertions(+), 167 deletions(-) diff --git a/bun.lock b/bun.lock index cf8ffc5..69dcdf1 100644 --- a/bun.lock +++ b/bun.lock @@ -61,6 +61,7 @@ "effect-lens": "2.0.0-beta.0", }, "devDependencies": { + "@effect/platform-browser": "^4.0.0-beta.85", "@testing-library/react": "^16.3.0", "jsdom": "^26.1.0", "vitest": "^3.2.4", @@ -3062,6 +3063,8 @@ "dot-prop/is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], + "effect-fc-next/@effect/platform-browser": ["@effect/platform-browser@4.0.0-beta.87", "", { "dependencies": { "multipasta": "^0.2.7" }, "peerDependencies": { "effect": "^4.0.0-beta.87" } }, "sha512-sBUUdRt5PjFPLI7+ayxEX/jgnjCbOuc3I//98CmqiwhfgWbCMZ/rofYYb8Zk5tLpNsmdHnWgHWTsBLvH2SFrCw=="], + "effect-fc-next/effect": ["effect@4.0.0-beta.85", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.8.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.1", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^14.0.0", "yaml": "^2.9.0" } }, "sha512-Cjv9YQyv4CiIccmRAQIWAoeESCpCpiuHYY8zb5vqiYs3Ac2yE5RQAnKq7z4Ir/3VJYZb8kxh6rS8czDDnpTdkQ=="], "effect-fc-next/effect-lens": ["effect-lens@2.0.0-beta.0", "", { "peerDependencies": { "effect": "4.0.0-beta.85" } }, "sha512-ntsRQSrzoX+GsNpkNVEGqebl/g1YOEDPIFRAHigf+4P6AtGnnOFcklqDHLrbm4zqnaxuWEgQvvn1J6S3eyC4yw=="], diff --git a/packages/effect-fc-next/package.json b/packages/effect-fc-next/package.json index f29a70b..fa29dbf 100644 --- a/packages/effect-fc-next/package.json +++ b/packages/effect-fc-next/package.json @@ -39,6 +39,7 @@ "clean:modules": "rm -rf node_modules" }, "devDependencies": { + "@effect/platform-browser": "^4.0.0-beta.85", "@testing-library/react": "^16.3.0", "jsdom": "^26.1.0", "vitest": "^3.2.4" diff --git a/packages/effect-fc-next/src/Query.ts b/packages/effect-fc-next/src/Query.ts index e9e317b..670f15d 100644 --- a/packages/effect-fc-next/src/Query.ts +++ b/packages/effect-fc-next/src/Query.ts @@ -1,44 +1,35 @@ -import { - type Cause, - type Context, - type Duration, - Effect, - Equal, - Fiber, - Option, - Pipeable, - Predicate, - type Scope, - Semaphore, - Stream, - SubscriptionRef, -} from "effect" -import { Subscribable } from "effect-lens" +import { type Cause, type Context, Duration, Effect, Equal, Exit, Fiber, Option, Pipeable, Predicate, type Scope, Semaphore, Stream, SubscriptionRef } from "effect" +import { AsyncResult } from "effect/unstable/reactivity" +import * as Lens from "./Lens.js" import * as QueryClient from "./QueryClient.js" -import * as Result from "./Result.js" +import * as Subscribable from "./Subscribable.js" export const QueryTypeId: unique symbol = Symbol.for("@effect-fc/Query/Query") export type QueryTypeId = typeof QueryTypeId -export interface Query +export interface Query extends Pipeable.Pipeable { readonly [QueryTypeId]: QueryTypeId + readonly context: Context.Context readonly key: Stream.Stream readonly f: (key: K) => Effect.Effect - readonly initialProgress: P - readonly staleTime: Duration.Input + + readonly staleTime: Duration.Duration readonly refreshOnWindowFocus: boolean + readonly latestKey: Subscribable.Subscribable> readonly fiber: Subscribable.Subscribable>> - readonly result: Subscribable.Subscribable> - readonly latestFinalResult: Subscribable.Subscribable>> + readonly result: Subscribable.Subscribable> + readonly latestFinalResult: Subscribable.Subscribable | AsyncResult.Failure>> + readonly run: Effect.Effect - fetch(key: K): Effect.Effect> - fetchSubscribable(key: K): Effect.Effect>> - readonly refresh: Effect.Effect, Cause.NoSuchElementError> - readonly refreshSubscribable: Effect.Effect>, Cause.NoSuchElementError> + fetch(key: K): Effect.Effect | AsyncResult.Failure, Cause.NoSuchElementError> + fetchSubscribable(key: K): Effect.Effect>, Cause.NoSuchElementError> + readonly refresh: Effect.Effect | AsyncResult.Failure, Cause.NoSuchElementError> + readonly refreshSubscribable: Effect.Effect>, Cause.NoSuchElementError> + readonly invalidateCache: Effect.Effect invalidateCacheEntry(key: K): Effect.Effect } @@ -47,42 +38,43 @@ export declare namespace Query { export type AnyKey = readonly any[] } -export class QueryImpl -extends Pipeable.Class implements Query { +export class QueryImpl +extends Pipeable.Class implements Query { readonly [QueryTypeId]: QueryTypeId = QueryTypeId - readonly latestKey: Subscribable.Subscribable> - readonly fiber: Subscribable.Subscribable>> - readonly result: Subscribable.Subscribable> - readonly latestFinalResult: Subscribable.Subscribable>> constructor( readonly context: Context.Context, readonly key: Stream.Stream, readonly f: (key: K) => Effect.Effect, - readonly initialProgress: P, - readonly staleTime: Duration.Input, + + readonly staleTime: Duration.Duration, readonly refreshOnWindowFocus: boolean, - readonly latestKeyRef: SubscriptionRef.SubscriptionRef>, - readonly fiberRef: SubscriptionRef.SubscriptionRef>>, - readonly resultRef: SubscriptionRef.SubscriptionRef>, - readonly latestFinalResultRef: SubscriptionRef.SubscriptionRef>>, + + readonly latestKey: Lens.Lens>, + readonly fiber: Lens.Lens>>, + readonly result: Lens.Lens>, + readonly latestFinalResult: Lens.Lens | AsyncResult.Failure>>, + readonly runSemaphore: Semaphore.Semaphore, ) { super() - this.latestKey = fromSubscriptionRef(latestKeyRef) - this.fiber = fromSubscriptionRef(fiberRef) - this.result = fromSubscriptionRef(resultRef) - this.latestFinalResult = fromSubscriptionRef(latestFinalResultRef) } get run(): Effect.Effect { - const focus = this.refreshOnWindowFocus && typeof window !== "undefined" - ? Stream.runForEach(Stream.fromEventListener(window, "focus"), () => this.refreshSubscribable) - : Effect.succeed(undefined) return Effect.all([ Stream.runForEach(this.key, key => this.fetchSubscribable(key)), - focus, - ], { concurrency: "unbounded", discard: true }).pipe( + + Effect.promise(() => import("@effect/platform-browser")).pipe( + Effect.flatMap(({ BrowserStream }) => this.refreshOnWindowFocus + ? Stream.runForEach( + BrowserStream.fromEventListenerWindow("focus"), + () => this.refreshSubscribable, + ) + : Effect.void + ), + Effect.catchDefect(() => Effect.void), + ), + ], { concurrency: "unbounded" }).pipe( Effect.ignore, this.runSemaphore.withPermits(1), Effect.provide(this.context), @@ -90,120 +82,159 @@ extends Pipeable.Class implements Query { } get interrupt(): Effect.Effect { - return Effect.flatMap(SubscriptionRef.get(this.fiberRef), Option.match({ + return Effect.flatMap(Lens.get(this.fiber), Option.match({ onSome: Fiber.interrupt, - onNone: () => Effect.succeed(undefined), + onNone: () => Effect.void, })) } - fetch(key: K): Effect.Effect> { - const self = this - return Effect.gen(function*() { - yield* self.interrupt - yield* SubscriptionRef.set(self.latestKeyRef, Option.some(key)) - const previous = yield* SubscriptionRef.get(self.latestFinalResultRef) - const sub = yield* self.startCached(key, Option.isSome(previous) - ? Result.willFetch(previous.value) as Result.Final - : Result.initial()) - return yield* self.watch(key, sub) - }).pipe(Effect.provide(this.context)) + fetch(key: K): Effect.Effect< + AsyncResult.Success | AsyncResult.Failure, + Cause.NoSuchElementError + > { + return this.interrupt.pipe( + Effect.andThen(Lens.set(this.latestKey, Option.some(key))), + Effect.andThen(this.startCached(key, AsyncResult.initial())), + Effect.flatMap(state => this.watch(key, state)), + Effect.provide(this.context), + ) } - fetchSubscribable(key: K): Effect.Effect>> { - const self = this - return Effect.gen(function*() { - yield* self.interrupt - yield* SubscriptionRef.set(self.latestKeyRef, Option.some(key)) - const previous = yield* SubscriptionRef.get(self.latestFinalResultRef) - const sub = yield* self.startCached(key, Option.isSome(previous) - ? Result.willFetch(previous.value) as Result.Final - : Result.initial()) - yield* Effect.forkScoped(self.watch(key, sub)) - return sub - }).pipe(Effect.provide(this.context)) + fetchSubscribable(key: K): Effect.Effect< + Subscribable.Subscribable>, + Cause.NoSuchElementError + > { + return this.interrupt.pipe( + Effect.andThen(Lens.set(this.latestKey, Option.some(key))), + Effect.andThen(this.startCached(key, AsyncResult.initial(false))), + Effect.tap(state => Effect.forkScoped(this.watch(key, state))), + Effect.provide(this.context), + ) } - get refresh(): Effect.Effect, Cause.NoSuchElementError> { - const self = this - return Effect.gen(function*() { - yield* self.interrupt - const key = yield* Effect.fromOption(yield* SubscriptionRef.get(self.latestKeyRef)) - const previous = yield* SubscriptionRef.get(self.latestFinalResultRef) - const sub = yield* self.startCached(key, Option.isSome(previous) - ? Result.willRefresh(previous.value) as Result.Final - : Result.initial()) - return yield* self.watch(key, sub) - }).pipe(Effect.provide(this.context)) + get refresh(): Effect.Effect | AsyncResult.Failure, Cause.NoSuchElementError> { + return this.interrupt.pipe( + Effect.andThen(Effect.Do), + Effect.bind("latestKey", () => Effect.flatMap(Lens.get(this.latestKey), Effect.fromOption)), + Effect.bind("latestFinalResult", () => Lens.get(this.latestFinalResult)), + Effect.bind("subscribable", ({ latestKey, latestFinalResult }) => + this.startCached(latestKey, Option.getOrElse(latestFinalResult, () => AsyncResult.initial(true))) + ), + Effect.flatMap(({ latestKey, subscribable }) => this.watch(latestKey, subscribable)), + Effect.provide(this.context), + ) } - get refreshSubscribable(): Effect.Effect>, Cause.NoSuchElementError> { - const self = this - return Effect.gen(function*() { - yield* self.interrupt - const key = yield* Effect.fromOption(yield* SubscriptionRef.get(self.latestKeyRef)) - const previous = yield* SubscriptionRef.get(self.latestFinalResultRef) - const sub = yield* self.startCached(key, Option.isSome(previous) - ? Result.willRefresh(previous.value) as Result.Final - : Result.initial()) - yield* Effect.forkScoped(self.watch(key, sub)) - return sub - }).pipe(Effect.provide(this.context)) + get refreshSubscribable(): Effect.Effect< + Subscribable.Subscribable>, + Cause.NoSuchElementError + > { + return this.interrupt.pipe( + Effect.andThen(Effect.Do), + Effect.bind("latestKey", () => Effect.flatMap(Lens.get(this.latestKey), Effect.fromOption)), + Effect.bind("latestFinalResult", () => Lens.get(this.latestFinalResult)), + Effect.bind("subscribable", ({ latestKey, latestFinalResult }) => + this.startCached(latestKey, Option.getOrElse(latestFinalResult, () => AsyncResult.initial(true))) + ), + Effect.tap(({ latestKey, subscribable }) => Effect.forkScoped(this.watch(latestKey, subscribable))), + Effect.map(({ subscribable }) => subscribable), + Effect.provide(this.context), + ) } startCached( key: K, - initial: Result.Initial | Result.Final, - ): Effect.Effect>, never, Scope.Scope | QueryClient.QueryClient | R> { + previous: AsyncResult.AsyncResult, + ): Effect.Effect< + Subscribable.Subscribable>, + Cause.NoSuchElementError, + Scope.Scope | QueryClient.QueryClient | R + > { return Effect.flatMap(this.getCacheEntry(key), Option.match({ onSome: entry => Effect.flatMap( QueryClient.isQueryClientCacheEntryStale(entry), isStale => isStale - ? this.start(key, Result.willRefresh(entry.result) as Result.Final) + ? this.start(key, entry.result as AsyncResult.AsyncResult) : Effect.succeed(Subscribable.make({ - get: Effect.succeed(entry.result as Result.Result), - changes: Stream.make(entry.result as Result.Result), + get: Effect.succeed(entry.result as AsyncResult.AsyncResult), + get changes() { return Stream.make(entry.result as AsyncResult.AsyncResult) }, })), ), - onNone: () => this.start(key, initial), + onNone: () => this.start(key, previous), })) } start( key: K, - initial: Result.Initial | Result.Final, - ): Effect.Effect>, never, Scope.Scope | R> { - const self = this - return Effect.gen(function*() { - const [sub, fiber] = yield* Result.unsafeForkEffect( - Effect.onExit(self.f(key), () => Effect.flatMap( - Effect.all([Effect.fiberId, SubscriptionRef.get(self.fiberRef)]), - ([currentFiberId, current]) => Option.match(current, { - onSome: value => Equal.equals(currentFiberId, value.id) - ? SubscriptionRef.set(self.fiberRef, Option.none()) - : Effect.succeed(undefined), - onNone: () => Effect.succeed(undefined), + previous: AsyncResult.AsyncResult, + ): Effect.Effect< + Subscribable.Subscribable>, + never, + Scope.Scope | R + > { + return Effect.gen({ self: this }, function*() { + const state = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(previous)) + + const fiber = yield* Effect.forkScoped(Effect.andThen( + Lens.update(state, AsyncResult.match({ + onInitial: () => AsyncResult.initial(true), + onSuccess: v => AsyncResult.success(v.value, { + waiting: true, }), + onFailure: v => AsyncResult.failure(v.cause, { + waiting: true, + previousSuccess: v.previousSuccess, + }) + })), + + Effect.onExit(this.f(key), exit => Lens.update( + state, + previous => Exit.match(exit, { + onSuccess: v => AsyncResult.success(v), + onFailure: c => AsyncResult.match(previous, { + onInitial: () => AsyncResult.failure(c), + onSuccess: v => AsyncResult.failure(c, { + previousSuccess: Option.some(v), + }), + onFailure: v => AsyncResult.failure(c, { + previousSuccess: v.previousSuccess, + }) + }), + }), + ).pipe( + Effect.andThen(Effect.all([ + Effect.fiberId, + Lens.get(this.fiber), + ])), + Effect.flatMap(([fiberId, fiber]) => Option.match(fiber, { + onSome: v => Equal.equals(fiberId, v.id) + ? Lens.set(this.fiber, Option.none()) + : Effect.void, + onNone: () => Effect.void, + })), )), - { initial, initialProgress: self.initialProgress }, - ) - yield* SubscriptionRef.set(self.fiberRef, Option.some(fiber)) - return sub + )) + + yield* Lens.set(this.fiber, Option.some(fiber)) + return state }) } watch( key: K, - sub: Subscribable.Subscribable>, - ): Effect.Effect, never, QueryClient.QueryClient> { - return Effect.flatMap(sub.get, initial => Stream.runFoldEffect( - Stream.takeUntil(sub.changes, result => Result.isFinal(result) && !Result.hasFlag(result)), - () => initial, - (_, result) => Effect.as(SubscriptionRef.set(this.resultRef, result), result), - ) as Effect.Effect>).pipe( - Effect.tap(result => SubscriptionRef.set(this.latestFinalResultRef, Option.some(result))), - Effect.tap(result => Result.isSuccess(result) - ? Effect.asVoid(this.setCacheEntry(key, result)) - : Effect.succeed(undefined)), + state: Subscribable.Subscribable> + ): Effect.Effect | AsyncResult.Failure, never, QueryClient.QueryClient> { + return state.get.pipe( + Effect.flatMap(initial => Stream.runFoldEffect( + state.changes, + () => initial, + (_, result) => Effect.as(Lens.set(this.result, result), result), + ) as Effect.Effect | AsyncResult.Failure>), + Effect.tap(result => Lens.set(this.latestFinalResult, Option.some(result))), + Effect.tap(result => AsyncResult.isSuccess(result) + ? this.setCacheEntry(key, result) + : Effect.void + ), ) } @@ -211,73 +242,95 @@ extends Pipeable.Class implements Query { return new QueryClient.QueryClientCacheKey(key, this.f as (key: Query.AnyKey) => Effect.Effect) } - getCacheEntry(key: K): Effect.Effect, never, QueryClient.QueryClient> { - return Effect.flatMap(QueryClient.QueryClient, client => client.getCacheEntry(this.makeCacheKey(key))) + getCacheEntry( + key: K + ): Effect.Effect, never, QueryClient.QueryClient> { + return Effect.andThen( + Effect.all([ + Effect.succeed(this.makeCacheKey(key)), + QueryClient.QueryClient, + ]), + ([key, client]) => client.getCacheEntry(key), + ) } - setCacheEntry(key: K, result: Result.Success): Effect.Effect { - return Effect.flatMap(QueryClient.QueryClient, client => client.setCacheEntry(this.makeCacheKey(key), result, this.staleTime)) + setCacheEntry( + key: K, + result: AsyncResult.Success, + ): Effect.Effect { + return Effect.flatMap( + Effect.all([ + Effect.succeed(this.makeCacheKey(key)), + QueryClient.QueryClient, + ]), + ([key, client]) => client.setCacheEntry(key, result, this.staleTime), + ) } get invalidateCache(): Effect.Effect { - return Effect.flatMap( - QueryClient.QueryClient, - client => client.invalidateCacheEntries(this.f as (key: Query.AnyKey) => Effect.Effect), - ).pipe(Effect.provide(this.context)) + return QueryClient.QueryClient.pipe( + Effect.andThen(client => client.invalidateCacheEntries(this.f as (key: Query.AnyKey) => Effect.Effect)), + Effect.provide(this.context), + ) } invalidateCacheEntry(key: K): Effect.Effect { - return Effect.flatMap( + return Effect.all([ + Effect.succeed(this.makeCacheKey(key)), QueryClient.QueryClient, - client => client.invalidateCacheEntry(this.makeCacheKey(key)), - ).pipe(Effect.provide(this.context)) + ]).pipe( + Effect.andThen(([key, client]) => client.invalidateCacheEntry(key)), + Effect.provide(this.context), + ) } } + export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) + export declare namespace make { - export interface Options { + export interface Options { readonly key: Stream.Stream - readonly f: (key: NoInfer) => Effect.Effect>> - readonly initialProgress?: P + readonly f: (key: NoInfer) => Effect.Effect readonly staleTime?: Duration.Input readonly refreshOnWindowFocus?: boolean } } -export const make = Effect.fnUntraced(function* ( - options: make.Options, +export const make = Effect.fnUntraced(function* ( + options: make.Options ): Effect.fn.Return< - Query, P>, - never, - Scope.Scope | QueryClient.QueryClient | KR | Result.forkEffect.OutputContext + Query, + Cause.NoSuchElementError, + Scope.Scope | QueryClient.QueryClient | KR | R > { const client = yield* QueryClient.QueryClient - return new QueryImpl, P>( - yield* Effect.context>(), + + return new QueryImpl( + yield* Effect.context(), options.key, - options.f as any, - options.initialProgress as P, - options.staleTime ?? client.defaultStaleTime, + options.f, + + options.staleTime ? yield* Effect.fromOption(Duration.fromInput(options.staleTime)) : client.defaultStaleTime, options.refreshOnWindowFocus ?? client.defaultRefreshOnWindowFocus, - yield* SubscriptionRef.make(Option.none()), - yield* SubscriptionRef.make(Option.none>()), - yield* SubscriptionRef.make(Result.initial()), - yield* SubscriptionRef.make(Option.none>()), + + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make>(AsyncResult.initial())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none | AsyncResult.Failure>())), + yield* Semaphore.make(1), ) }) -export const service = ( - options: make.Options, +export const service = ( + options: make.Options ): Effect.Effect< - Query, P>, - never, - Scope.Scope | QueryClient.QueryClient | KR | Result.forkEffect.OutputContext -> => Effect.tap(make(options), query => Effect.asVoid(Effect.forkScoped(query.run))) - -const fromSubscriptionRef = (ref: SubscriptionRef.SubscriptionRef): Subscribable.Subscribable => Subscribable.make({ - get: SubscriptionRef.get(ref), - changes: SubscriptionRef.changes(ref), -}) + Query, + Cause.NoSuchElementError, + Scope.Scope | QueryClient.QueryClient | KR | R +> => Effect.tap( + make(options), + query => Effect.forkScoped(query.run), +) -- 2.52.0 From e5ac120ceabce813c23c768d5dca8d4ea20a1f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 26 Jun 2026 02:38:24 +0200 Subject: [PATCH 46/61] Refactor Mutation --- packages/effect-fc-next/src/Mutation.ts | 167 +++++++++++++----------- packages/effect-fc-next/src/Query.ts | 2 +- 2 files changed, 90 insertions(+), 79 deletions(-) diff --git a/packages/effect-fc-next/src/Mutation.ts b/packages/effect-fc-next/src/Mutation.ts index 0d873eb..5ae14d4 100644 --- a/packages/effect-fc-next/src/Mutation.ts +++ b/packages/effect-fc-next/src/Mutation.ts @@ -1,146 +1,157 @@ -import { type Context, Effect, Equal, type Fiber, Option, Pipeable, Predicate, type Scope, Stream, SubscriptionRef } from "effect" -import { Subscribable } from "effect-lens" -import * as Result from "./Result.js" +import { type Context, Effect, Equal, Exit, type Fiber, Option, Pipeable, Predicate, type Scope, Stream, SubscriptionRef } from "effect" +import { AsyncResult } from "effect/unstable/reactivity" +import * as Lens from "./Lens.js" +import type * as Subscribable from "./Subscribable.js" export const MutationTypeId: unique symbol = Symbol.for("@effect-fc/Mutation/Mutation") export type MutationTypeId = typeof MutationTypeId -export interface Mutation +export interface Mutation extends Pipeable.Pipeable { readonly [MutationTypeId]: MutationTypeId readonly context: Context.Context readonly f: (key: K) => Effect.Effect - readonly initialProgress: P readonly latestKey: Subscribable.Subscribable> readonly fiber: Subscribable.Subscribable>> - readonly result: Subscribable.Subscribable> - readonly latestFinalResult: Subscribable.Subscribable>> + readonly result: Subscribable.Subscribable> + readonly latestFinalResult: Subscribable.Subscribable | AsyncResult.Failure>> - mutate(key: K): Effect.Effect> - mutateSubscribable(key: K): Effect.Effect>> + mutate(key: K): Effect.Effect | AsyncResult.Failure> + mutateSubscribable(key: K): Effect.Effect>> } export declare namespace Mutation { export type AnyKey = readonly any[] } -export class MutationImpl -extends Pipeable.Class implements Mutation { +export class MutationImpl +extends Pipeable.Class implements Mutation { readonly [MutationTypeId]: MutationTypeId = MutationTypeId - readonly latestKey: Subscribable.Subscribable> - readonly fiber: Subscribable.Subscribable>> - readonly result: Subscribable.Subscribable> - readonly latestFinalResult: Subscribable.Subscribable>> constructor( readonly context: Context.Context, readonly f: (key: K) => Effect.Effect, - readonly initialProgress: P, - readonly latestKeyRef: SubscriptionRef.SubscriptionRef>, - readonly fiberRef: SubscriptionRef.SubscriptionRef>>, - readonly resultRef: SubscriptionRef.SubscriptionRef>, - readonly latestFinalResultRef: SubscriptionRef.SubscriptionRef>>, + readonly latestKey: Lens.Lens>, + readonly fiber: Lens.Lens>>, + readonly result: Lens.Lens>, + readonly latestFinalResult: Lens.Lens | AsyncResult.Failure>>, ) { super() - this.latestKey = fromSubscriptionRef(latestKeyRef) - this.fiber = fromSubscriptionRef(fiberRef) - this.result = fromSubscriptionRef(resultRef) - this.latestFinalResult = fromSubscriptionRef(latestFinalResultRef) } - mutate(key: K): Effect.Effect> { - return SubscriptionRef.set(this.latestKeyRef, Option.some(key)).pipe( + mutate(key: K): Effect.Effect | AsyncResult.Failure> { + return Lens.set(this.latestKey, Option.some(key)).pipe( Effect.andThen(this.start(key)), - Effect.andThen(sub => this.watch(sub)), + Effect.flatMap(state => this.watch(state)), Effect.provide(this.context), ) } - mutateSubscribable(key: K): Effect.Effect>> { - return SubscriptionRef.set(this.latestKeyRef, Option.some(key)).pipe( + mutateSubscribable(key: K): Effect.Effect>> { + return Lens.set(this.latestKey, Option.some(key)).pipe( Effect.andThen(this.start(key)), - Effect.tap(sub => Effect.forkScoped(this.watch(sub))), + Effect.tap(state => Effect.forkScoped(this.watch(state))), Effect.provide(this.context), ) } start(key: K): Effect.Effect< - Subscribable.Subscribable>, + Subscribable.Subscribable>, never, Scope.Scope | R > { - const self = this - return Effect.gen(function*() { - const initial = yield* SubscriptionRef.get(self.latestFinalResultRef) - const [sub, fiber] = yield* Result.unsafeForkEffect( - Effect.onExit(self.f(key), () => Effect.andThen( - Effect.all([Effect.fiberId, SubscriptionRef.get(self.fiberRef)]), - ([currentFiberId, fiber]) => Option.match(fiber, { - onSome: v => Equal.equals(currentFiberId, v.id) - ? SubscriptionRef.set(self.fiberRef, Option.none()) - : Effect.succeed(undefined), - onNone: () => Effect.succeed(undefined), - }), - )), + return Effect.gen({ self: this }, function*() { + const previous = yield* Lens.get(this.latestFinalResult) + const state = Lens.fromSubscriptionRef(yield* SubscriptionRef.make>( + Option.getOrElse(previous, () => AsyncResult.initial(false)) + )) - { - initial: Option.isSome(initial) ? Result.willFetch(initial.value) : Result.initial(), - initialProgress: self.initialProgress, - } as Result.unsafeForkEffect.Options, - ) - yield* SubscriptionRef.set(self.fiberRef, Option.some(fiber)) - return sub + const fiber = yield* Effect.forkScoped(Effect.andThen( + Lens.update(state, AsyncResult.match({ + onInitial: () => AsyncResult.initial(true), + onSuccess: v => AsyncResult.success(v.value, { + waiting: true, + }), + onFailure: v => AsyncResult.failure(v.cause, { + waiting: true, + previousSuccess: v.previousSuccess, + }) + })), + + Effect.onExit(this.f(key), exit => Lens.update( + state, + previous => Exit.match(exit, { + onSuccess: v => AsyncResult.success(v), + onFailure: c => AsyncResult.match(previous, { + onInitial: () => AsyncResult.failure(c), + onSuccess: v => AsyncResult.failure(c, { + previousSuccess: Option.some(v), + }), + onFailure: v => AsyncResult.failure(c, { + previousSuccess: v.previousSuccess, + }) + }), + }), + ).pipe( + Effect.andThen(Effect.all([ + Effect.fiberId, + Lens.get(this.fiber), + ])), + Effect.flatMap(([fiberId, fiber]) => Option.match(fiber, { + onSome: v => Equal.equals(fiberId, v.id) + ? Lens.set(this.fiber, Option.none()) + : Effect.void, + onNone: () => Effect.void, + })), + )), + )) + + yield* Lens.set(this.fiber, Option.some(fiber)) + return state }) } watch( - sub: Subscribable.Subscribable> - ): Effect.Effect> { - return sub.get.pipe( + state: Subscribable.Subscribable> + ): Effect.Effect | AsyncResult.Failure> { + return state.get.pipe( Effect.andThen(initial => Stream.runFoldEffect( - Stream.takeUntil(sub.changes, result => Result.isFinal(result) && !Result.hasFlag(result)), + state.changes, () => initial, - (_, result) => Effect.as(SubscriptionRef.set(this.resultRef, result), result), - ) as Effect.Effect>), - Effect.tap(result => SubscriptionRef.set(this.latestFinalResultRef, Option.some(result))), + (_, result) => Effect.as(Lens.set(this.result, result), result), + ) as Effect.Effect | AsyncResult.Failure>), + Effect.tap(result => Lens.set(this.latestFinalResult, Option.some(result))), ) } } -export const isMutation = (u: unknown): u is Mutation => Predicate.hasProperty(u, MutationTypeId) +export const isMutation = (u: unknown): u is Mutation => Predicate.hasProperty(u, MutationTypeId) export declare namespace make { - export interface Options { - readonly f: (key: K) => Effect.Effect>> - readonly initialProgress?: P + export interface Options { + readonly f: (key: K) => Effect.Effect } } -export const make = Effect.fnUntraced(function* ( - options: make.Options +export const make = Effect.fnUntraced(function* ( + options: make.Options ): Effect.fn.Return< - Mutation, P>, + Mutation, never, - Scope.Scope | Result.forkEffect.OutputContext + Scope.Scope | R > { return new MutationImpl( - yield* Effect.context>(), - options.f as any, - options.initialProgress as P, + yield* Effect.context(), + options.f, - yield* SubscriptionRef.make(Option.none()), - yield* SubscriptionRef.make(Option.none>()), - yield* SubscriptionRef.make(Result.initial()), - yield* SubscriptionRef.make(Option.none>()), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make>(AsyncResult.initial())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none | AsyncResult.Failure>())), ) }) - -const fromSubscriptionRef = (ref: SubscriptionRef.SubscriptionRef): Subscribable.Subscribable => Subscribable.make({ - get: SubscriptionRef.get(ref), - changes: SubscriptionRef.changes(ref), -}) diff --git a/packages/effect-fc-next/src/Query.ts b/packages/effect-fc-next/src/Query.ts index 670f15d..27a6531 100644 --- a/packages/effect-fc-next/src/Query.ts +++ b/packages/effect-fc-next/src/Query.ts @@ -286,7 +286,7 @@ extends Pipeable.Class implements Query { } -export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) +export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) export declare namespace make { -- 2.52.0 From c59e2ee03517c00910eb0d7751204faaf1f2a167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 26 Jun 2026 02:54:40 +0200 Subject: [PATCH 47/61] Refactor Query/Mutation --- packages/effect-fc-next/src/Mutation.ts | 16 ++++++--------- packages/effect-fc-next/src/Query.ts | 23 +++++++++------------- packages/effect-fc-next/src/QueryClient.ts | 13 ++++++------ 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/packages/effect-fc-next/src/Mutation.ts b/packages/effect-fc-next/src/Mutation.ts index 5ae14d4..6ad8140 100644 --- a/packages/effect-fc-next/src/Mutation.ts +++ b/packages/effect-fc-next/src/Mutation.ts @@ -7,7 +7,7 @@ import type * as Subscribable from "./Subscribable.js" export const MutationTypeId: unique symbol = Symbol.for("@effect-fc/Mutation/Mutation") export type MutationTypeId = typeof MutationTypeId -export interface Mutation +export interface Mutation extends Pipeable.Pipeable { readonly [MutationTypeId]: MutationTypeId @@ -23,11 +23,10 @@ extends Pipeable.Pipeable { mutateSubscribable(key: K): Effect.Effect>> } -export declare namespace Mutation { - export type AnyKey = readonly any[] -} +export const isMutation = (u: unknown): u is Mutation => Predicate.hasProperty(u, MutationTypeId) -export class MutationImpl + +export class MutationImpl extends Pipeable.Class implements Mutation { readonly [MutationTypeId]: MutationTypeId = MutationTypeId @@ -129,16 +128,13 @@ extends Pipeable.Class implements Mutation { } -export const isMutation = (u: unknown): u is Mutation => Predicate.hasProperty(u, MutationTypeId) - - export declare namespace make { - export interface Options { + export interface Options { readonly f: (key: K) => Effect.Effect } } -export const make = Effect.fnUntraced(function* ( +export const make = Effect.fnUntraced(function* ( options: make.Options ): Effect.fn.Return< Mutation, diff --git a/packages/effect-fc-next/src/Query.ts b/packages/effect-fc-next/src/Query.ts index 27a6531..6e7d589 100644 --- a/packages/effect-fc-next/src/Query.ts +++ b/packages/effect-fc-next/src/Query.ts @@ -8,7 +8,7 @@ import * as Subscribable from "./Subscribable.js" export const QueryTypeId: unique symbol = Symbol.for("@effect-fc/Query/Query") export type QueryTypeId = typeof QueryTypeId -export interface Query +export interface Query extends Pipeable.Pipeable { readonly [QueryTypeId]: QueryTypeId @@ -34,11 +34,10 @@ extends Pipeable.Pipeable { invalidateCacheEntry(key: K): Effect.Effect } -export declare namespace Query { - export type AnyKey = readonly any[] -} +export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) -export class QueryImpl + +export class QueryImpl extends Pipeable.Class implements Query { readonly [QueryTypeId]: QueryTypeId = QueryTypeId @@ -239,7 +238,7 @@ extends Pipeable.Class implements Query { } makeCacheKey(key: K): QueryClient.QueryClientCacheKey { - return new QueryClient.QueryClientCacheKey(key, this.f as (key: Query.AnyKey) => Effect.Effect) + return new QueryClient.QueryClientCacheKey(key, this.f as (key: unknown) => Effect.Effect) } getCacheEntry( @@ -269,7 +268,7 @@ extends Pipeable.Class implements Query { get invalidateCache(): Effect.Effect { return QueryClient.QueryClient.pipe( - Effect.andThen(client => client.invalidateCacheEntries(this.f as (key: Query.AnyKey) => Effect.Effect)), + Effect.andThen(client => client.invalidateCacheEntries(this.f as (key: unknown) => Effect.Effect)), Effect.provide(this.context), ) } @@ -285,12 +284,8 @@ extends Pipeable.Class implements Query { } } - -export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) - - export declare namespace make { - export interface Options { + export interface Options { readonly key: Stream.Stream readonly f: (key: NoInfer) => Effect.Effect readonly staleTime?: Duration.Input @@ -298,7 +293,7 @@ export declare namespace make { } } -export const make = Effect.fnUntraced(function* ( +export const make = Effect.fnUntraced(function* ( options: make.Options ): Effect.fn.Return< Query, @@ -324,7 +319,7 @@ export const make = Effect.fnUntraced(function* ( +export const service = ( options: make.Options ): Effect.Effect< Query, diff --git a/packages/effect-fc-next/src/QueryClient.ts b/packages/effect-fc-next/src/QueryClient.ts index 61dcf59..2405cbd 100644 --- a/packages/effect-fc-next/src/QueryClient.ts +++ b/packages/effect-fc-next/src/QueryClient.ts @@ -1,7 +1,6 @@ import { type Cause, Context, DateTime, Duration, Effect, Equal, Equivalence, Hash, HashMap, type Option, Pipeable, Predicate, Schedule, type Scope, Semaphore, SubscriptionRef } from "effect" import type { AsyncResult } from "effect/unstable/reactivity" import * as Lens from "./Lens.js" -import type * as Query from "./Query.js" import type * as Subscribable from "./Subscribable.js" @@ -23,7 +22,7 @@ export interface QueryClientService extends Pipeable.Pipeable { result: AsyncResult.Success, staleTime: Duration.Duration, ): Effect.Effect - invalidateCacheEntries(f: (key: Query.Query.AnyKey) => Effect.Effect): Effect.Effect + invalidateCacheEntries(f: (key: unknown) => Effect.Effect): Effect.Effect invalidateCacheEntry(key: QueryClientCacheKey): Effect.Effect } @@ -86,7 +85,7 @@ implements QueryClientService { ) } - invalidateCacheEntries(f: (key: Query.Query.AnyKey) => Effect.Effect): Effect.Effect { + invalidateCacheEntries(f: (key: unknown) => Effect.Effect): Effect.Effect { return Lens.update(this.cache, HashMap.filter((_, key) => !Equivalence.strictEqual()(key.f, f))) } invalidateCacheEntry(key: QueryClientCacheKey): Effect.Effect { @@ -137,17 +136,17 @@ implements Pipeable.Pipeable, Equal.Equal { readonly [QueryClientCacheKeyTypeId]: QueryClientCacheKeyTypeId = QueryClientCacheKeyTypeId constructor( - readonly key: Query.Query.AnyKey, - readonly f: (key: Query.Query.AnyKey) => Effect.Effect, + readonly key: unknown, + readonly f: (key: unknown) => Effect.Effect, ) { super() } [Equal.symbol](that: Equal.Equal) { - return isQueryClientCacheKey(that) && Equivalence.Array(Equal.asEquivalence())(this.key, that.key) && Equivalence.strictEqual()(this.f, that.f) + return isQueryClientCacheKey(that) && Equal.equals(this.key, that.key) && Equivalence.strictEqual()(this.f, that.f) } [Hash.symbol]() { - return Hash.combine(Hash.hash(this.f))(Hash.array(this.key)) + return Hash.combine(Hash.hash(this.f))(Hash.hash(this.key)) } } -- 2.52.0 From e07ce1cd682f7ca99c3c48ba027e5e8c322e110d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Wed, 1 Jul 2026 21:12:05 +0200 Subject: [PATCH 48/61] Refactor Query --- packages/effect-fc-next/src/Query.ts | 251 ++++++++++++++++----------- 1 file changed, 147 insertions(+), 104 deletions(-) diff --git a/packages/effect-fc-next/src/Query.ts b/packages/effect-fc-next/src/Query.ts index 6e7d589..ca169be 100644 --- a/packages/effect-fc-next/src/Query.ts +++ b/packages/effect-fc-next/src/Query.ts @@ -1,4 +1,4 @@ -import { type Cause, type Context, Duration, Effect, Equal, Exit, Fiber, Option, Pipeable, Predicate, type Scope, Semaphore, Stream, SubscriptionRef } from "effect" +import { type Cause, type Context, Duration, Effect, Equal, type Equivalence, Exit, Fiber, Option, Pipeable, Predicate, type Scope, Semaphore, Stream, SubscriptionRef } from "effect" import { AsyncResult } from "effect/unstable/reactivity" import * as Lens from "./Lens.js" import * as QueryClient from "./QueryClient.js" @@ -8,51 +8,61 @@ import * as Subscribable from "./Subscribable.js" export const QueryTypeId: unique symbol = Symbol.for("@effect-fc/Query/Query") export type QueryTypeId = typeof QueryTypeId -export interface Query +export interface Query extends Pipeable.Pipeable { readonly [QueryTypeId]: QueryTypeId - readonly context: Context.Context - readonly key: Stream.Stream + readonly context: Context.Context readonly f: (key: K) => Effect.Effect + readonly keyEquivalence: Equivalence.Equivalence readonly staleTime: Duration.Duration readonly refreshOnWindowFocus: boolean readonly latestKey: Subscribable.Subscribable> readonly fiber: Subscribable.Subscribable>> - readonly result: Subscribable.Subscribable> - readonly latestFinalResult: Subscribable.Subscribable | AsyncResult.Failure>> + readonly state: Subscribable.Subscribable> + readonly latestFinalState: Subscribable.Subscribable>> readonly run: Effect.Effect - fetch(key: K): Effect.Effect | AsyncResult.Failure, Cause.NoSuchElementError> - fetchSubscribable(key: K): Effect.Effect>, Cause.NoSuchElementError> - readonly refresh: Effect.Effect | AsyncResult.Failure, Cause.NoSuchElementError> - readonly refreshSubscribable: Effect.Effect>, Cause.NoSuchElementError> + fetch(key: K): Effect.Effect, Cause.NoSuchElementError> + fetchSubscribable(key: K): Effect.Effect>, Cause.NoSuchElementError> + readonly refresh: Effect.Effect, Cause.NoSuchElementError> + readonly refreshSubscribable: Effect.Effect>, Cause.NoSuchElementError> readonly invalidateCache: Effect.Effect invalidateCacheEntry(key: K): Effect.Effect } -export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) +export interface QueryState { + readonly key: K + readonly result: AsyncResult.AsyncResult +} + +export interface FinalQueryState { + readonly key: K + readonly result: AsyncResult.Success | AsyncResult.Failure +} + +export const isQuery = (u: unknown): u is Query => Predicate.hasProperty(u, QueryTypeId) -export class QueryImpl -extends Pipeable.Class implements Query { +export class QueryImpl +extends Pipeable.Class implements Query { readonly [QueryTypeId]: QueryTypeId = QueryTypeId constructor( - readonly context: Context.Context, - readonly key: Stream.Stream, + readonly context: Context.Context, readonly f: (key: K) => Effect.Effect, + readonly keyEquivalence: Equivalence.Equivalence, readonly staleTime: Duration.Duration, readonly refreshOnWindowFocus: boolean, readonly latestKey: Lens.Lens>, readonly fiber: Lens.Lens>>, - readonly result: Lens.Lens>, - readonly latestFinalResult: Lens.Lens | AsyncResult.Failure>>, + readonly state: Lens.Lens>, + readonly latestFinalState: Lens.Lens>>, readonly runSemaphore: Semaphore.Semaphore, ) { @@ -60,20 +70,15 @@ extends Pipeable.Class implements Query { } get run(): Effect.Effect { - return Effect.all([ - Stream.runForEach(this.key, key => this.fetchSubscribable(key)), - - Effect.promise(() => import("@effect/platform-browser")).pipe( - Effect.flatMap(({ BrowserStream }) => this.refreshOnWindowFocus - ? Stream.runForEach( - BrowserStream.fromEventListenerWindow("focus"), - () => this.refreshSubscribable, - ) - : Effect.void - ), - Effect.catchDefect(() => Effect.void), + return Effect.promise(() => import("@effect/platform-browser")).pipe( + Effect.flatMap(({ BrowserStream }) => this.refreshOnWindowFocus + ? Stream.runForEach( + BrowserStream.fromEventListenerWindow("focus"), + () => this.refreshSubscribable, + ) + : Effect.void ), - ], { concurrency: "unbounded" }).pipe( + Effect.catchDefect(() => Effect.void), Effect.ignore, this.runSemaphore.withPermits(1), Effect.provide(this.context), @@ -87,117 +92,156 @@ extends Pipeable.Class implements Query { })) } - fetch(key: K): Effect.Effect< - AsyncResult.Success | AsyncResult.Failure, - Cause.NoSuchElementError - > { + fetch(key: K): Effect.Effect, Cause.NoSuchElementError> { return this.interrupt.pipe( Effect.andThen(Lens.set(this.latestKey, Option.some(key))), - Effect.andThen(this.startCached(key, AsyncResult.initial())), - Effect.flatMap(state => this.watch(key, state)), + Effect.andThen(this.startCached({ + key, + result: AsyncResult.initial(false) + })), + Effect.flatMap(state => this.watch(state)), Effect.provide(this.context), ) } fetchSubscribable(key: K): Effect.Effect< - Subscribable.Subscribable>, + Subscribable.Subscribable>, Cause.NoSuchElementError > { return this.interrupt.pipe( Effect.andThen(Lens.set(this.latestKey, Option.some(key))), - Effect.andThen(this.startCached(key, AsyncResult.initial(false))), - Effect.tap(state => Effect.forkScoped(this.watch(key, state))), + Effect.andThen(this.startCached({ + key, + result: AsyncResult.initial(false) + })), + Effect.tap(state => Effect.forkScoped(this.watch(state))), Effect.provide(this.context), ) } - get refresh(): Effect.Effect | AsyncResult.Failure, Cause.NoSuchElementError> { + get refresh(): Effect.Effect, Cause.NoSuchElementError> { return this.interrupt.pipe( Effect.andThen(Effect.Do), Effect.bind("latestKey", () => Effect.flatMap(Lens.get(this.latestKey), Effect.fromOption)), - Effect.bind("latestFinalResult", () => Lens.get(this.latestFinalResult)), - Effect.bind("subscribable", ({ latestKey, latestFinalResult }) => - this.startCached(latestKey, Option.getOrElse(latestFinalResult, () => AsyncResult.initial(true))) + Effect.bind("latestFinalState", () => Lens.get(this.latestFinalState)), + Effect.bind("subscribable", ({ latestKey, latestFinalState }) => + this.startCached(Option.getOrElse(latestFinalState, () => ({ + key: latestKey, + result: AsyncResult.initial(true), + }))) ), - Effect.flatMap(({ latestKey, subscribable }) => this.watch(latestKey, subscribable)), + Effect.flatMap(({ subscribable }) => this.watch(subscribable)), Effect.provide(this.context), ) } get refreshSubscribable(): Effect.Effect< - Subscribable.Subscribable>, + Subscribable.Subscribable>, Cause.NoSuchElementError > { return this.interrupt.pipe( Effect.andThen(Effect.Do), Effect.bind("latestKey", () => Effect.flatMap(Lens.get(this.latestKey), Effect.fromOption)), - Effect.bind("latestFinalResult", () => Lens.get(this.latestFinalResult)), - Effect.bind("subscribable", ({ latestKey, latestFinalResult }) => - this.startCached(latestKey, Option.getOrElse(latestFinalResult, () => AsyncResult.initial(true))) + Effect.bind("latestFinalState", () => Lens.get(this.latestFinalState)), + Effect.bind("subscribable", ({ latestKey, latestFinalState }) => + this.startCached(Option.getOrElse(latestFinalState, () => ({ + key: latestKey, + result: AsyncResult.initial(true), + }))) ), - Effect.tap(({ latestKey, subscribable }) => Effect.forkScoped(this.watch(latestKey, subscribable))), + Effect.tap(({ subscribable }) => Effect.forkScoped(this.watch(subscribable))), Effect.map(({ subscribable }) => subscribable), Effect.provide(this.context), ) } startCached( - key: K, - previous: AsyncResult.AsyncResult, + previous: QueryState, ): Effect.Effect< - Subscribable.Subscribable>, + Subscribable.Subscribable>, Cause.NoSuchElementError, Scope.Scope | QueryClient.QueryClient | R > { - return Effect.flatMap(this.getCacheEntry(key), Option.match({ + return Effect.flatMap(this.getCacheEntry(previous.key), Option.match({ onSome: entry => Effect.flatMap( QueryClient.isQueryClientCacheEntryStale(entry), isStale => isStale - ? this.start(key, entry.result as AsyncResult.AsyncResult) + ? this.start({ + key: previous.key, + result: entry.result as AsyncResult.AsyncResult, + }) : Effect.succeed(Subscribable.make({ - get: Effect.succeed(entry.result as AsyncResult.AsyncResult), - get changes() { return Stream.make(entry.result as AsyncResult.AsyncResult) }, + get: Effect.succeed({ + key: previous.key, + result: entry.result as AsyncResult.AsyncResult, + }), + get changes() { + return Stream.make({ + key: previous.key, + result: entry.result as AsyncResult.AsyncResult, + }) + }, })), ), - onNone: () => this.start(key, previous), + onNone: () => this.start(previous), })) } start( - key: K, - previous: AsyncResult.AsyncResult, + previous: QueryState, ): Effect.Effect< - Subscribable.Subscribable>, + Subscribable.Subscribable>, never, Scope.Scope | R > { return Effect.gen({ self: this }, function*() { - const state = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(previous)) + const subscribable = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(previous)) const fiber = yield* Effect.forkScoped(Effect.andThen( - Lens.update(state, AsyncResult.match({ - onInitial: () => AsyncResult.initial(true), - onSuccess: v => AsyncResult.success(v.value, { - waiting: true, + Lens.update(subscribable, previous => AsyncResult.match(previous.result, { + onInitial: () => ({ + key: previous.key, + result: AsyncResult.initial(true), + }), + onSuccess: result => ({ + key: previous.key, + result: AsyncResult.success(result.value, { + waiting: true, + }), + }), + onFailure: result => ({ + key: previous.key, + result: AsyncResult.failure(result.cause, { + waiting: true, + previousSuccess: result.previousSuccess, + }), }), - onFailure: v => AsyncResult.failure(v.cause, { - waiting: true, - previousSuccess: v.previousSuccess, - }) })), - Effect.onExit(this.f(key), exit => Lens.update( - state, + Effect.onExit(this.f(previous.key), exit => Lens.update( + subscribable, previous => Exit.match(exit, { - onSuccess: v => AsyncResult.success(v), - onFailure: c => AsyncResult.match(previous, { - onInitial: () => AsyncResult.failure(c), - onSuccess: v => AsyncResult.failure(c, { - previousSuccess: Option.some(v), + onSuccess: v => ({ + key: previous.key, + result: AsyncResult.success(v), + }), + onFailure: c => AsyncResult.match(previous.result, { + onInitial: () => ({ + key: previous.key, + result: AsyncResult.failure(c), + }), + onSuccess: v => ({ + key: previous.key, + result: AsyncResult.failure(c, { + previousSuccess: Option.some(v), + }), + }), + onFailure: v => ({ + key: previous.key, + result: AsyncResult.failure(c, { + previousSuccess: v.previousSuccess, + }), }), - onFailure: v => AsyncResult.failure(c, { - previousSuccess: v.previousSuccess, - }) }), }), ).pipe( @@ -206,7 +250,7 @@ extends Pipeable.Class implements Query { Lens.get(this.fiber), ])), Effect.flatMap(([fiberId, fiber]) => Option.match(fiber, { - onSome: v => Equal.equals(fiberId, v.id) + onSome: v => fiberId === v.id ? Lens.set(this.fiber, Option.none()) : Effect.void, onNone: () => Effect.void, @@ -215,23 +259,22 @@ extends Pipeable.Class implements Query { )) yield* Lens.set(this.fiber, Option.some(fiber)) - return state + return subscribable }) } watch( - key: K, - state: Subscribable.Subscribable> - ): Effect.Effect | AsyncResult.Failure, never, QueryClient.QueryClient> { - return state.get.pipe( + subscribable: Subscribable.Subscribable> + ): Effect.Effect, never, QueryClient.QueryClient> { + return subscribable.get.pipe( Effect.flatMap(initial => Stream.runFoldEffect( - state.changes, + subscribable.changes, () => initial, - (_, result) => Effect.as(Lens.set(this.result, result), result), - ) as Effect.Effect | AsyncResult.Failure>), - Effect.tap(result => Lens.set(this.latestFinalResult, Option.some(result))), - Effect.tap(result => AsyncResult.isSuccess(result) - ? this.setCacheEntry(key, result) + (_, state) => Effect.as(Lens.set(this.state, state), state), + ) as Effect.Effect>), + Effect.tap(state => Lens.set(this.latestFinalState, Option.some(state))), + Effect.tap(state => AsyncResult.isSuccess(state.result) + ? this.setCacheEntry(state.key, state.result) : Effect.void ), ) @@ -285,27 +328,27 @@ extends Pipeable.Class implements Query { } export declare namespace make { - export interface Options { - readonly key: Stream.Stream - readonly f: (key: NoInfer) => Effect.Effect + export interface Options { + readonly f: (key: K) => Effect.Effect + readonly keyEquivalence?: Equivalence.Equivalence, readonly staleTime?: Duration.Input readonly refreshOnWindowFocus?: boolean } } -export const make = Effect.fnUntraced(function* ( - options: make.Options +export const make = Effect.fnUntraced(function* ( + options: make.Options ): Effect.fn.Return< - Query, + Query, Cause.NoSuchElementError, - Scope.Scope | QueryClient.QueryClient | KR | R + Scope.Scope | QueryClient.QueryClient | R > { const client = yield* QueryClient.QueryClient return new QueryImpl( - yield* Effect.context(), - options.key, + yield* Effect.context(), options.f, + options.keyEquivalence ?? Equal.asEquivalence(), options.staleTime ? yield* Effect.fromOption(Duration.fromInput(options.staleTime)) : client.defaultStaleTime, options.refreshOnWindowFocus ?? client.defaultRefreshOnWindowFocus, @@ -319,12 +362,12 @@ export const make = Effect.fnUntraced(function* ( - options: make.Options +export const service = ( + options: make.Options ): Effect.Effect< - Query, + Query, Cause.NoSuchElementError, - Scope.Scope | QueryClient.QueryClient | KR | R + Scope.Scope | QueryClient.QueryClient | R > => Effect.tap( make(options), query => Effect.forkScoped(query.run), -- 2.52.0 From 7a7783e7ded89409cc5db4ed89e78fc9e38f4f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Tue, 7 Jul 2026 21:22:05 +0200 Subject: [PATCH 49/61] Refactor Query --- packages/effect-fc-next/src/Query.ts | 161 +++++++++++++++++---------- 1 file changed, 100 insertions(+), 61 deletions(-) diff --git a/packages/effect-fc-next/src/Query.ts b/packages/effect-fc-next/src/Query.ts index ca169be..9b5007b 100644 --- a/packages/effect-fc-next/src/Query.ts +++ b/packages/effect-fc-next/src/Query.ts @@ -13,13 +13,13 @@ extends Pipeable.Pipeable { readonly [QueryTypeId]: QueryTypeId readonly context: Context.Context - readonly f: (key: K) => Effect.Effect + readonly key: Subscribable.Subscribable readonly keyEquivalence: Equivalence.Equivalence + readonly f: (key: K) => Effect.Effect readonly staleTime: Duration.Duration readonly refreshOnWindowFocus: boolean - readonly latestKey: Subscribable.Subscribable> readonly fiber: Subscribable.Subscribable>> readonly state: Subscribable.Subscribable> readonly latestFinalState: Subscribable.Subscribable>> @@ -53,13 +53,13 @@ extends Pipeable.Class implements Query { constructor( readonly context: Context.Context, - readonly f: (key: K) => Effect.Effect, + readonly key: Lens.Lens, readonly keyEquivalence: Equivalence.Equivalence, + readonly f: (key: K) => Effect.Effect, readonly staleTime: Duration.Duration, readonly refreshOnWindowFocus: boolean, - readonly latestKey: Lens.Lens>, readonly fiber: Lens.Lens>>, readonly state: Lens.Lens>, readonly latestFinalState: Lens.Lens>>, @@ -70,15 +70,29 @@ extends Pipeable.Class implements Query { } get run(): Effect.Effect { - return Effect.promise(() => import("@effect/platform-browser")).pipe( - Effect.flatMap(({ BrowserStream }) => this.refreshOnWindowFocus - ? Stream.runForEach( - BrowserStream.fromEventListenerWindow("focus"), - () => this.refreshSubscribable, - ) - : Effect.void + return Effect.all([ + Stream.runFoldEffect( + this.key.changes, + () => Option.none(), + (previous, key) => Effect.as( + Option.isSome(previous) && this.keyEquivalence(key, previous.value) + ? this.refreshSubscribable + : this.fetchSubscribable(key), + Option.some(key), + ), ), - Effect.catchDefect(() => Effect.void), + + Effect.promise(() => import("@effect/platform-browser")).pipe( + Effect.flatMap(({ BrowserStream }) => this.refreshOnWindowFocus + ? Stream.runForEach( + BrowserStream.fromEventListenerWindow("focus"), + () => this.refreshSubscribable, + ) + : Effect.void + ), + Effect.catchDefect(() => Effect.void), + ), + ], { concurrency: "unbounded" }).pipe( Effect.ignore, this.runSemaphore.withPermits(1), Effect.provide(this.context), @@ -93,13 +107,16 @@ extends Pipeable.Class implements Query { } fetch(key: K): Effect.Effect, Cause.NoSuchElementError> { - return this.interrupt.pipe( - Effect.andThen(Lens.set(this.latestKey, Option.some(key))), - Effect.andThen(this.startCached({ + return Effect.gen({ self: this }, function*() { + yield* this.interrupt + yield* Lens.set(this.key, key) + + const state = yield* this.startCached({ key, - result: AsyncResult.initial(false) - })), - Effect.flatMap(state => this.watch(state)), + result: AsyncResult.initial(false), + }) + return yield* this.watch(state) + }).pipe( Effect.provide(this.context), ) } @@ -108,29 +125,39 @@ extends Pipeable.Class implements Query { Subscribable.Subscribable>, Cause.NoSuchElementError > { - return this.interrupt.pipe( - Effect.andThen(Lens.set(this.latestKey, Option.some(key))), - Effect.andThen(this.startCached({ + return Effect.gen({ self: this }, function*() { + yield* this.interrupt + yield* Lens.set(this.key, key) + + const state = yield* this.startCached({ key, - result: AsyncResult.initial(false) - })), - Effect.tap(state => Effect.forkScoped(this.watch(state))), + result: AsyncResult.initial(false), + }) + + yield* Effect.forkScoped(this.watch(state)) + return state + }).pipe( Effect.provide(this.context), ) } get refresh(): Effect.Effect, Cause.NoSuchElementError> { - return this.interrupt.pipe( - Effect.andThen(Effect.Do), - Effect.bind("latestKey", () => Effect.flatMap(Lens.get(this.latestKey), Effect.fromOption)), - Effect.bind("latestFinalState", () => Lens.get(this.latestFinalState)), - Effect.bind("subscribable", ({ latestKey, latestFinalState }) => - this.startCached(Option.getOrElse(latestFinalState, () => ({ - key: latestKey, - result: AsyncResult.initial(true), - }))) - ), - Effect.flatMap(({ subscribable }) => this.watch(subscribable)), + return Effect.gen({ self: this }, function*() { + yield* this.interrupt + const latestKey = yield* Lens.get(this.key) + const latestFinalState = yield* Lens.get(this.latestFinalState) + + const state = yield* this.startCached( + Option.isSome(latestFinalState) && this.keyEquivalence(latestKey, latestFinalState.value.key) + ? latestFinalState.value + : { + key: latestKey, + result: AsyncResult.initial(false), + } + ) + + return yield* this.watch(state) + }).pipe( Effect.provide(this.context), ) } @@ -139,18 +166,23 @@ extends Pipeable.Class implements Query { Subscribable.Subscribable>, Cause.NoSuchElementError > { - return this.interrupt.pipe( - Effect.andThen(Effect.Do), - Effect.bind("latestKey", () => Effect.flatMap(Lens.get(this.latestKey), Effect.fromOption)), - Effect.bind("latestFinalState", () => Lens.get(this.latestFinalState)), - Effect.bind("subscribable", ({ latestKey, latestFinalState }) => - this.startCached(Option.getOrElse(latestFinalState, () => ({ - key: latestKey, - result: AsyncResult.initial(true), - }))) - ), - Effect.tap(({ subscribable }) => Effect.forkScoped(this.watch(subscribable))), - Effect.map(({ subscribable }) => subscribable), + return Effect.gen({ self: this }, function*() { + yield* this.interrupt + const latestKey = yield* Lens.get(this.key) + const latestFinalState = yield* Lens.get(this.latestFinalState) + + const state = yield* this.startCached( + Option.isSome(latestFinalState) && this.keyEquivalence(latestKey, latestFinalState.value.key) + ? latestFinalState.value + : { + key: latestKey, + result: AsyncResult.initial(false), + } + ) + + yield* Effect.forkScoped(this.watch(state)) + return state + }).pipe( Effect.provide(this.context), ) } @@ -266,18 +298,20 @@ extends Pipeable.Class implements Query { watch( subscribable: Subscribable.Subscribable> ): Effect.Effect, never, QueryClient.QueryClient> { - return subscribable.get.pipe( - Effect.flatMap(initial => Stream.runFoldEffect( + return Effect.gen({ self: this }, function*() { + const initial = yield* subscribable.get + const final = yield* Stream.runFoldEffect( subscribable.changes, () => initial, (_, state) => Effect.as(Lens.set(this.state, state), state), - ) as Effect.Effect>), - Effect.tap(state => Lens.set(this.latestFinalState, Option.some(state))), - Effect.tap(state => AsyncResult.isSuccess(state.result) - ? this.setCacheEntry(state.key, state.result) - : Effect.void - ), - ) + ) as Effect.Effect> + + yield* Lens.set(this.latestFinalState, Option.some(final)) + if (AsyncResult.isSuccess(final.result)) + yield* this.setCacheEntry(final.key, final.result) + + return final + }) } makeCacheKey(key: K): QueryClient.QueryClientCacheKey { @@ -329,8 +363,10 @@ extends Pipeable.Class implements Query { export declare namespace make { export interface Options { - readonly f: (key: K) => Effect.Effect + readonly key: Lens.Lens, readonly keyEquivalence?: Equivalence.Equivalence, + readonly f: (key: K) => Effect.Effect + readonly staleTime?: Duration.Input readonly refreshOnWindowFocus?: boolean } @@ -347,16 +383,19 @@ export const make = Effect.fnUntraced(function* ( return new QueryImpl( yield* Effect.context(), - options.f, + options.key, options.keyEquivalence ?? Equal.asEquivalence(), + options.f, options.staleTime ? yield* Effect.fromOption(Duration.fromInput(options.staleTime)) : client.defaultStaleTime, options.refreshOnWindowFocus ?? client.defaultRefreshOnWindowFocus, - Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none())), Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), - Lens.fromSubscriptionRef(yield* SubscriptionRef.make>(AsyncResult.initial())), - Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none | AsyncResult.Failure>())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make>({ + key: yield* Lens.get(options.key), + result: AsyncResult.initial(false), + })), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), yield* Semaphore.make(1), ) -- 2.52.0 From 23cdfb389488c5530e57934764f4829e1195bfb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 17 Jul 2026 01:15:53 +0200 Subject: [PATCH 50/61] Refactor Query --- packages/effect-fc-next/src/Query.ts | 46 +++++++++++++++------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/packages/effect-fc-next/src/Query.ts b/packages/effect-fc-next/src/Query.ts index 9b5007b..e9a155b 100644 --- a/packages/effect-fc-next/src/Query.ts +++ b/packages/effect-fc-next/src/Query.ts @@ -53,7 +53,7 @@ extends Pipeable.Class implements Query { constructor( readonly context: Context.Context, - readonly key: Lens.Lens, + readonly key: Subscribable.Subscribable, readonly keyEquivalence: Equivalence.Equivalence, readonly f: (key: K) => Effect.Effect, @@ -71,15 +71,23 @@ extends Pipeable.Class implements Query { get run(): Effect.Effect { return Effect.all([ - Stream.runFoldEffect( + Stream.runForEach( this.key.changes, - () => Option.none(), - (previous, key) => Effect.as( - Option.isSome(previous) && this.keyEquivalence(key, previous.value) - ? this.refreshSubscribable - : this.fetchSubscribable(key), - Option.some(key), - ), + key => Effect.gen({ self: this }, function*() { + yield* this.interrupt + const latestFinalState = yield* Lens.get(this.latestFinalState) + + const state = yield* this.startCached( + Option.isSome(latestFinalState) && this.keyEquivalence(key, latestFinalState.value.key) + ? latestFinalState.value + : { + key, + result: AsyncResult.initial(false), + } + ) + + yield* Effect.forkScoped(this.watch(state)) + }), ), Effect.promise(() => import("@effect/platform-browser")).pipe( @@ -109,8 +117,6 @@ extends Pipeable.Class implements Query { fetch(key: K): Effect.Effect, Cause.NoSuchElementError> { return Effect.gen({ self: this }, function*() { yield* this.interrupt - yield* Lens.set(this.key, key) - const state = yield* this.startCached({ key, result: AsyncResult.initial(false), @@ -127,8 +133,6 @@ extends Pipeable.Class implements Query { > { return Effect.gen({ self: this }, function*() { yield* this.interrupt - yield* Lens.set(this.key, key) - const state = yield* this.startCached({ key, result: AsyncResult.initial(false), @@ -144,14 +148,14 @@ extends Pipeable.Class implements Query { get refresh(): Effect.Effect, Cause.NoSuchElementError> { return Effect.gen({ self: this }, function*() { yield* this.interrupt - const latestKey = yield* Lens.get(this.key) + const latestState = yield* Lens.get(this.state) const latestFinalState = yield* Lens.get(this.latestFinalState) const state = yield* this.startCached( - Option.isSome(latestFinalState) && this.keyEquivalence(latestKey, latestFinalState.value.key) + Option.isSome(latestFinalState) && this.keyEquivalence(latestState.key, latestFinalState.value.key) ? latestFinalState.value : { - key: latestKey, + key: latestState.key, result: AsyncResult.initial(false), } ) @@ -168,14 +172,14 @@ extends Pipeable.Class implements Query { > { return Effect.gen({ self: this }, function*() { yield* this.interrupt - const latestKey = yield* Lens.get(this.key) + const latestState = yield* Lens.get(this.state) const latestFinalState = yield* Lens.get(this.latestFinalState) const state = yield* this.startCached( - Option.isSome(latestFinalState) && this.keyEquivalence(latestKey, latestFinalState.value.key) + Option.isSome(latestFinalState) && this.keyEquivalence(latestState.key, latestFinalState.value.key) ? latestFinalState.value : { - key: latestKey, + key: latestState.key, result: AsyncResult.initial(false), } ) @@ -363,7 +367,7 @@ extends Pipeable.Class implements Query { export declare namespace make { export interface Options { - readonly key: Lens.Lens, + readonly key: Subscribable.Subscribable, readonly keyEquivalence?: Equivalence.Equivalence, readonly f: (key: K) => Effect.Effect @@ -392,7 +396,7 @@ export const make = Effect.fnUntraced(function* ( Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), Lens.fromSubscriptionRef(yield* SubscriptionRef.make>({ - key: yield* Lens.get(options.key), + key: yield* options.key.get, result: AsyncResult.initial(false), })), Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), -- 2.52.0 From 3fc3904c6cfe336e5ea61ab88c25bf3dfa86eb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 17 Jul 2026 21:25:07 +0200 Subject: [PATCH 51/61] Upgrade effect-lens --- bun.lock | 21 ++++--- packages/effect-fc-next/package.json | 7 ++- packages/effect-fc-next/src/Form.ts | 38 ++++++------- packages/effect-fc-next/src/Mutation.ts | 28 +++++----- packages/effect-fc-next/src/Query.ts | 56 +++++++++---------- packages/effect-fc-next/src/QueryClient.ts | 4 +- packages/effect-fc-next/src/Result.ts | 7 ++- .../effect-fc-next/src/SubmittableForm.ts | 20 +++---- packages/effect-fc-next/src/Subscribable.ts | 53 ------------------ .../effect-fc-next/src/SynchronizedForm.ts | 18 +++--- packages/effect-fc-next/src/View.ts | 40 +++++++++++++ packages/effect-fc-next/src/index.ts | 2 +- .../{Subscribable.test.tsx => View.test.tsx} | 49 +++------------- packages/example-next/src/main.tsx | 4 +- 14 files changed, 154 insertions(+), 193 deletions(-) delete mode 100644 packages/effect-fc-next/src/Subscribable.ts create mode 100644 packages/effect-fc-next/src/View.ts rename packages/effect-fc-next/test/{Subscribable.test.tsx => View.test.tsx} (60%) diff --git a/bun.lock b/bun.lock index 69dcdf1..91d7915 100644 --- a/bun.lock +++ b/bun.lock @@ -58,17 +58,18 @@ "name": "effect-fc-next", "version": "0.1.0-beta.0", "dependencies": { - "effect-lens": "2.0.0-beta.0", + "effect-lens": "^2.0.0-beta.1", }, "devDependencies": { - "@effect/platform-browser": "^4.0.0-beta.85", + "@effect/platform-browser": "4.0.0-beta.98", "@testing-library/react": "^16.3.0", + "effect": "4.0.0-beta.98", "jsdom": "^26.1.0", "vitest": "^3.2.4", }, "peerDependencies": { "@types/react": "^19.2.0", - "effect": "4.0.0-beta.85", + "effect": "4.0.0-beta.98", "react": "^19.2.0", }, }, @@ -3063,11 +3064,11 @@ "dot-prop/is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], - "effect-fc-next/@effect/platform-browser": ["@effect/platform-browser@4.0.0-beta.87", "", { "dependencies": { "multipasta": "^0.2.7" }, "peerDependencies": { "effect": "^4.0.0-beta.87" } }, "sha512-sBUUdRt5PjFPLI7+ayxEX/jgnjCbOuc3I//98CmqiwhfgWbCMZ/rofYYb8Zk5tLpNsmdHnWgHWTsBLvH2SFrCw=="], + "effect-fc-next/@effect/platform-browser": ["@effect/platform-browser@4.0.0-beta.98", "", { "dependencies": { "multipasta": "^0.2.8" }, "peerDependencies": { "effect": "^4.0.0-beta.98" } }, "sha512-Y0BEe0N8clKmJTHqmZpS85pLZbqAxP5uV3IYF0tDw/1dcs8AbTRHjbRmOLdyLtmU32NBVAiaUD3Vopb5Et5R/g=="], - "effect-fc-next/effect": ["effect@4.0.0-beta.85", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.8.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.1", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^14.0.0", "yaml": "^2.9.0" } }, "sha512-Cjv9YQyv4CiIccmRAQIWAoeESCpCpiuHYY8zb5vqiYs3Ac2yE5RQAnKq7z4Ir/3VJYZb8kxh6rS8czDDnpTdkQ=="], + "effect-fc-next/effect": ["effect@4.0.0-beta.98", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.9.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.4", "multipasta": "^0.2.8", "toml": "^4.1.2", "uuid": "^14.0.1", "yaml": "^2.9.0" } }, "sha512-oz+bsG5h+6RNrw4t5GMfQrk/xBS8ROoqkYsuvRhBr5O7mCOrpvH/hbw+QrDzvKIpX4HJClwm86F94c87W0sJxg=="], - "effect-fc-next/effect-lens": ["effect-lens@2.0.0-beta.0", "", { "peerDependencies": { "effect": "4.0.0-beta.85" } }, "sha512-ntsRQSrzoX+GsNpkNVEGqebl/g1YOEDPIFRAHigf+4P6AtGnnOFcklqDHLrbm4zqnaxuWEgQvvn1J6S3eyC4yw=="], + "effect-fc-next/effect-lens": ["effect-lens@2.0.0-beta.1", "", { "peerDependencies": { "effect": "4.0.0-beta.98" } }, "sha512-3MwsrezPczZHH4Tl2SvliZdiNRq9e/XbH+Vr1ckr/FPCEp6Wv8IYQL4Ie/hhI+XBiLlxbQERbgL8FlHW21avtw=="], "esrecurse/estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], @@ -3373,10 +3374,16 @@ "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], - "effect-fc-next/effect/fast-check": ["fast-check@4.8.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg=="], + "effect-fc-next/@effect/platform-browser/multipasta": ["multipasta@0.2.8", "", {}, "sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q=="], + + "effect-fc-next/effect/fast-check": ["fast-check@4.9.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg=="], "effect-fc-next/effect/msgpackr": ["msgpackr@2.0.4", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA=="], + "effect-fc-next/effect/multipasta": ["multipasta@0.2.8", "", {}, "sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q=="], + + "effect-fc-next/effect/toml": ["toml@4.3.0", "", {}, "sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A=="], + "express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "file-loader/schema-utils/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], diff --git a/packages/effect-fc-next/package.json b/packages/effect-fc-next/package.json index fa29dbf..2375e0e 100644 --- a/packages/effect-fc-next/package.json +++ b/packages/effect-fc-next/package.json @@ -39,17 +39,18 @@ "clean:modules": "rm -rf node_modules" }, "devDependencies": { - "@effect/platform-browser": "^4.0.0-beta.85", + "@effect/platform-browser": "4.0.0-beta.98", "@testing-library/react": "^16.3.0", + "effect": "4.0.0-beta.98", "jsdom": "^26.1.0", "vitest": "^3.2.4" }, "peerDependencies": { "@types/react": "^19.2.0", - "effect": "4.0.0-beta.85", + "effect": "4.0.0-beta.98", "react": "^19.2.0" }, "dependencies": { - "effect-lens": "2.0.0-beta.0" + "effect-lens": "^2.0.0-beta.1" } } diff --git a/packages/effect-fc-next/src/Form.ts b/packages/effect-fc-next/src/Form.ts index 30039aa..e3ce5ea 100644 --- a/packages/effect-fc-next/src/Form.ts +++ b/packages/effect-fc-next/src/Form.ts @@ -2,7 +2,7 @@ import { Array, type Cause, Chunk, type Duration, Effect, Equal, Function, ident import type * as React from "react" import * as Component from "./Component.js" import * as Lens from "./Lens.js" -import * as Subscribable from "./Subscribable.js" +import * as View from "./View.js" export const FormTypeId: unique symbol = Symbol.for("@effect-fc/Form/Form") @@ -18,12 +18,12 @@ extends Pipeable.Pipeable { readonly [FormTypeId]: FormTypeId readonly path: P - readonly value: Subscribable.Subscribable, ER, never> + readonly value: View.View, ER, never> readonly encodedValue: Lens.Lens - readonly issues: Subscribable.Subscribable - readonly isValidating: Subscribable.Subscribable - readonly canCommit: Subscribable.Subscribable - readonly isCommitting: Subscribable.Subscribable + readonly issues: View.View + readonly isValidating: View.View + readonly canCommit: View.View + readonly isCommitting: View.View } export class FormImpl @@ -32,12 +32,12 @@ extends Pipeable.Class implements Form { constructor( readonly path: P, - readonly value: Subscribable.Subscribable, ER, never>, + readonly value: View.View, ER, never>, readonly encodedValue: Lens.Lens, - readonly issues: Subscribable.Subscribable, - readonly isValidating: Subscribable.Subscribable, - readonly canCommit: Subscribable.Subscribable, - readonly isCommitting: Subscribable.Subscribable, + readonly issues: View.View, + readonly isValidating: View.View, + readonly canCommit: View.View, + readonly isCommitting: View.View, ) { super() } @@ -71,9 +71,9 @@ export const focusObjectOn: { return new FormImpl( path, - Subscribable.mapOption(form.value, a => a[key]), + View.mapOption(form.value, a => a[key]), Lens.focusObjectOn(form.encodedValue, key), - Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)), + View.map(form.issues, issues => filterIssuesByPath(issues, path)), form.isValidating, form.canCommit, form.isCommitting, @@ -97,9 +97,9 @@ export const focusArrayAt: { return new FormImpl( path, - Subscribable.mapOptionEffect(form.value, values => Effect.fromOption(Array.get(values, index))), + View.mapOptionEffect(form.value, values => Effect.fromOption(Array.get(values, index))), Lens.focusArrayAt(form.encodedValue, index), - Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)), + View.map(form.issues, issues => filterIssuesByPath(issues, path)), form.isValidating, form.canCommit, form.isCommitting, @@ -123,9 +123,9 @@ export const focusTupleAt: { return new FormImpl( path, - Subscribable.mapOption(form.value, values => values[index]), + View.mapOption(form.value, values => values[index]), Lens.focusTupleAt(form.encodedValue, index), - Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)), + View.map(form.issues, issues => filterIssuesByPath(issues, path)), form.isValidating, form.canCommit, form.isCommitting, @@ -149,9 +149,9 @@ export const focusChunkAt: { return new FormImpl( path, - Subscribable.mapOptionEffect(form.value, values => Effect.fromOption(Chunk.get(values, index))), + View.mapOptionEffect(form.value, values => Effect.fromOption(Chunk.get(values, index))), Lens.focusChunkAt(form.encodedValue, index), - Subscribable.map(form.issues, issues => filterIssuesByPath(issues, path)), + View.map(form.issues, issues => filterIssuesByPath(issues, path)), form.isValidating, form.canCommit, form.isCommitting, diff --git a/packages/effect-fc-next/src/Mutation.ts b/packages/effect-fc-next/src/Mutation.ts index 6ad8140..3e13174 100644 --- a/packages/effect-fc-next/src/Mutation.ts +++ b/packages/effect-fc-next/src/Mutation.ts @@ -1,26 +1,26 @@ import { type Context, Effect, Equal, Exit, type Fiber, Option, Pipeable, Predicate, type Scope, Stream, SubscriptionRef } from "effect" import { AsyncResult } from "effect/unstable/reactivity" import * as Lens from "./Lens.js" -import type * as Subscribable from "./Subscribable.js" +import * as View from "./View.js" export const MutationTypeId: unique symbol = Symbol.for("@effect-fc/Mutation/Mutation") export type MutationTypeId = typeof MutationTypeId -export interface Mutation +export interface Mutation extends Pipeable.Pipeable { readonly [MutationTypeId]: MutationTypeId readonly context: Context.Context readonly f: (key: K) => Effect.Effect - readonly latestKey: Subscribable.Subscribable> - readonly fiber: Subscribable.Subscribable>> - readonly result: Subscribable.Subscribable> - readonly latestFinalResult: Subscribable.Subscribable | AsyncResult.Failure>> + readonly latestKey: View.View> + readonly fiber: View.View>> + readonly state: View.View> + readonly latestFinalResult: View.View | AsyncResult.Failure>> mutate(key: K): Effect.Effect | AsyncResult.Failure> - mutateSubscribable(key: K): Effect.Effect>> + mutateView(key: K): Effect.Effect>> } export const isMutation = (u: unknown): u is Mutation => Predicate.hasProperty(u, MutationTypeId) @@ -36,7 +36,7 @@ extends Pipeable.Class implements Mutation { readonly latestKey: Lens.Lens>, readonly fiber: Lens.Lens>>, - readonly result: Lens.Lens>, + readonly state: Lens.Lens>, readonly latestFinalResult: Lens.Lens | AsyncResult.Failure>>, ) { super() @@ -49,7 +49,7 @@ extends Pipeable.Class implements Mutation { Effect.provide(this.context), ) } - mutateSubscribable(key: K): Effect.Effect>> { + mutateView(key: K): Effect.Effect>> { return Lens.set(this.latestKey, Option.some(key)).pipe( Effect.andThen(this.start(key)), Effect.tap(state => Effect.forkScoped(this.watch(state))), @@ -58,7 +58,7 @@ extends Pipeable.Class implements Mutation { } start(key: K): Effect.Effect< - Subscribable.Subscribable>, + View.View>, never, Scope.Scope | R > { @@ -114,13 +114,13 @@ extends Pipeable.Class implements Mutation { } watch( - state: Subscribable.Subscribable> + state: View.View> ): Effect.Effect | AsyncResult.Failure> { - return state.get.pipe( + return View.get(state).pipe( Effect.andThen(initial => Stream.runFoldEffect( - state.changes, + View.changes(state), () => initial, - (_, result) => Effect.as(Lens.set(this.result, result), result), + (_, result) => Effect.as(Lens.set(this.state, result), result), ) as Effect.Effect | AsyncResult.Failure>), Effect.tap(result => Lens.set(this.latestFinalResult, Option.some(result))), ) diff --git a/packages/effect-fc-next/src/Query.ts b/packages/effect-fc-next/src/Query.ts index e9a155b..ff84519 100644 --- a/packages/effect-fc-next/src/Query.ts +++ b/packages/effect-fc-next/src/Query.ts @@ -2,44 +2,44 @@ import { type Cause, type Context, Duration, Effect, Equal, type Equivalence, Ex import { AsyncResult } from "effect/unstable/reactivity" import * as Lens from "./Lens.js" import * as QueryClient from "./QueryClient.js" -import * as Subscribable from "./Subscribable.js" +import * as View from "./View.js" export const QueryTypeId: unique symbol = Symbol.for("@effect-fc/Query/Query") export type QueryTypeId = typeof QueryTypeId -export interface Query +export interface Query extends Pipeable.Pipeable { readonly [QueryTypeId]: QueryTypeId readonly context: Context.Context - readonly key: Subscribable.Subscribable + readonly key: View.View readonly keyEquivalence: Equivalence.Equivalence readonly f: (key: K) => Effect.Effect readonly staleTime: Duration.Duration readonly refreshOnWindowFocus: boolean - readonly fiber: Subscribable.Subscribable>> - readonly state: Subscribable.Subscribable> - readonly latestFinalState: Subscribable.Subscribable>> + readonly fiber: View.View>> + readonly state: View.View> + readonly latestFinalState: View.View>> readonly run: Effect.Effect fetch(key: K): Effect.Effect, Cause.NoSuchElementError> - fetchSubscribable(key: K): Effect.Effect>, Cause.NoSuchElementError> + fetchView(key: K): Effect.Effect>, Cause.NoSuchElementError> readonly refresh: Effect.Effect, Cause.NoSuchElementError> - readonly refreshSubscribable: Effect.Effect>, Cause.NoSuchElementError> + readonly refreshView: Effect.Effect>, Cause.NoSuchElementError> readonly invalidateCache: Effect.Effect invalidateCacheEntry(key: K): Effect.Effect } -export interface QueryState { +export interface QueryState { readonly key: K readonly result: AsyncResult.AsyncResult } -export interface FinalQueryState { +export interface FinalQueryState { readonly key: K readonly result: AsyncResult.Success | AsyncResult.Failure } @@ -53,7 +53,7 @@ extends Pipeable.Class implements Query { constructor( readonly context: Context.Context, - readonly key: Subscribable.Subscribable, + readonly key: View.View, readonly keyEquivalence: Equivalence.Equivalence, readonly f: (key: K) => Effect.Effect, @@ -94,7 +94,7 @@ extends Pipeable.Class implements Query { Effect.flatMap(({ BrowserStream }) => this.refreshOnWindowFocus ? Stream.runForEach( BrowserStream.fromEventListenerWindow("focus"), - () => this.refreshSubscribable, + () => this.refreshView, ) : Effect.void ), @@ -127,8 +127,8 @@ extends Pipeable.Class implements Query { ) } - fetchSubscribable(key: K): Effect.Effect< - Subscribable.Subscribable>, + fetchView(key: K): Effect.Effect< + View.View>, Cause.NoSuchElementError > { return Effect.gen({ self: this }, function*() { @@ -166,8 +166,8 @@ extends Pipeable.Class implements Query { ) } - get refreshSubscribable(): Effect.Effect< - Subscribable.Subscribable>, + get refreshView(): Effect.Effect< + View.View>, Cause.NoSuchElementError > { return Effect.gen({ self: this }, function*() { @@ -194,7 +194,7 @@ extends Pipeable.Class implements Query { startCached( previous: QueryState, ): Effect.Effect< - Subscribable.Subscribable>, + View.View>, Cause.NoSuchElementError, Scope.Scope | QueryClient.QueryClient | R > { @@ -206,7 +206,7 @@ extends Pipeable.Class implements Query { key: previous.key, result: entry.result as AsyncResult.AsyncResult, }) - : Effect.succeed(Subscribable.make({ + : Effect.succeed(View.make({ get: Effect.succeed({ key: previous.key, result: entry.result as AsyncResult.AsyncResult, @@ -226,15 +226,15 @@ extends Pipeable.Class implements Query { start( previous: QueryState, ): Effect.Effect< - Subscribable.Subscribable>, + View.View>, never, Scope.Scope | R > { return Effect.gen({ self: this }, function*() { - const subscribable = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(previous)) + const state = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(previous)) const fiber = yield* Effect.forkScoped(Effect.andThen( - Lens.update(subscribable, previous => AsyncResult.match(previous.result, { + Lens.update(state, previous => AsyncResult.match(previous.result, { onInitial: () => ({ key: previous.key, result: AsyncResult.initial(true), @@ -255,7 +255,7 @@ extends Pipeable.Class implements Query { })), Effect.onExit(this.f(previous.key), exit => Lens.update( - subscribable, + state, previous => Exit.match(exit, { onSuccess: v => ({ key: previous.key, @@ -295,17 +295,17 @@ extends Pipeable.Class implements Query { )) yield* Lens.set(this.fiber, Option.some(fiber)) - return subscribable + return state }) } watch( - subscribable: Subscribable.Subscribable> + view: View.View> ): Effect.Effect, never, QueryClient.QueryClient> { return Effect.gen({ self: this }, function*() { - const initial = yield* subscribable.get + const initial = yield* View.get(view) const final = yield* Stream.runFoldEffect( - subscribable.changes, + View.changes(view), () => initial, (_, state) => Effect.as(Lens.set(this.state, state), state), ) as Effect.Effect> @@ -367,7 +367,7 @@ extends Pipeable.Class implements Query { export declare namespace make { export interface Options { - readonly key: Subscribable.Subscribable, + readonly key: View.View, readonly keyEquivalence?: Equivalence.Equivalence, readonly f: (key: K) => Effect.Effect @@ -396,7 +396,7 @@ export const make = Effect.fnUntraced(function* ( Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), Lens.fromSubscriptionRef(yield* SubscriptionRef.make>({ - key: yield* options.key.get, + key: yield* View.get(options.key), result: AsyncResult.initial(false), })), Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), diff --git a/packages/effect-fc-next/src/QueryClient.ts b/packages/effect-fc-next/src/QueryClient.ts index 2405cbd..946e45f 100644 --- a/packages/effect-fc-next/src/QueryClient.ts +++ b/packages/effect-fc-next/src/QueryClient.ts @@ -1,7 +1,7 @@ import { type Cause, Context, DateTime, Duration, Effect, Equal, Equivalence, Hash, HashMap, type Option, Pipeable, Predicate, Schedule, type Scope, Semaphore, SubscriptionRef } from "effect" import type { AsyncResult } from "effect/unstable/reactivity" import * as Lens from "./Lens.js" -import type * as Subscribable from "./Subscribable.js" +import type * as View from "./View.js" export const QueryClientServiceTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientService") @@ -10,7 +10,7 @@ export type QueryClientServiceTypeId = typeof QueryClientServiceTypeId export interface QueryClientService extends Pipeable.Pipeable { readonly [QueryClientServiceTypeId]: QueryClientServiceTypeId - readonly cache: Subscribable.Subscribable> + readonly cache: View.View> readonly cacheGcTime: Duration.Duration readonly defaultStaleTime: Duration.Duration readonly defaultRefreshOnWindowFocus: boolean diff --git a/packages/effect-fc-next/src/Result.ts b/packages/effect-fc-next/src/Result.ts index 672ae18..1c92d99 100644 --- a/packages/effect-fc-next/src/Result.ts +++ b/packages/effect-fc-next/src/Result.ts @@ -1,5 +1,6 @@ import { Cause, Context, Data, Effect, Equal, Exit, type Fiber, Hash, Layer, Match, Pipeable, Predicate, pipe, type Scope, SubscriptionRef } from "effect" -import { Lens, Subscribable } from "effect-lens" +import { Lens } from "effect-lens" +import type { View } from "effect-lens/View" export const ResultTypeId: unique symbol = Symbol.for("@effect-fc/Result/Result") @@ -207,7 +208,7 @@ export const unsafeForkEffect = Effect.fnUntraced(function* effect: Effect.Effect, options?: unsafeForkEffect.Options, NoInfer, P>, ): Effect.fn.Return< - readonly [result: Subscribable.Subscribable, never, never>, fiber: Fiber.Fiber], + readonly [result: View, never, never>, fiber: Fiber.Fiber], never, Scope.Scope | unsafeForkEffect.OutputContext > { @@ -242,7 +243,7 @@ export const forkEffect: { effect: Effect.Effect>>, options?: forkEffect.Options, NoInfer, P>, ): Effect.Effect< - readonly [result: Subscribable.Subscribable, never, never>, fiber: Fiber.Fiber], + readonly [result: View, never, never>, fiber: Fiber.Fiber], never, Scope.Scope | forkEffect.OutputContext > diff --git a/packages/effect-fc-next/src/SubmittableForm.ts b/packages/effect-fc-next/src/SubmittableForm.ts index 79dfe46..a08b59c 100644 --- a/packages/effect-fc-next/src/SubmittableForm.ts +++ b/packages/effect-fc-next/src/SubmittableForm.ts @@ -18,7 +18,7 @@ import * as Form from "./Form.js" import * as Lens from "./Lens.js" import * as Mutation from "./Mutation.js" import * as Result from "./Result.js" -import * as Subscribable from "./Subscribable.js" +import * as View from "./View.js" type FormSchema = Schema.Top & { @@ -39,7 +39,7 @@ extends Form.Form { readonly [value: A, form: SubmittableForm], MA, ME, MR, MP > - readonly validationFiber: Subscribable.Subscribable>, never, never> + readonly validationFiber: View.View>, never, never> readonly run: Effect.Effect readonly submit: Effect.Effect>, Cause.NoSuchElementError> } @@ -50,9 +50,9 @@ extends Pipeable.Class implements SubmittableForm { readonly [SubmittableFormTypeId]: SubmittableFormTypeId = SubmittableFormTypeId readonly path = [] as const readonly encodedValue: Lens.Lens - readonly isValidating: Subscribable.Subscribable - readonly canCommit: Subscribable.Subscribable - readonly isCommitting: Subscribable.Subscribable + readonly isValidating: View.View + readonly canCommit: View.View + readonly isCommitting: View.View constructor( readonly schema: FormSchema, @@ -77,26 +77,26 @@ extends Pipeable.Class implements SubmittableForm { ), lock: Lens.asLensImpl(internalEncodedValue).lock, }) - this.isValidating = Subscribable.map(validationFiber, Option.isSome) - const commitState = Subscribable.zipLatestAll( + this.isValidating = View.map(validationFiber, Option.isSome) + const commitState = View.zipLatestAll( value as any, issues as any, validationFiber as any, mutation.result as any, - ) as unknown as Subscribable.Subscribable, readonly Form.FormIssue[], Option.Option>, Result.Result, ]> - this.canCommit = Subscribable.map( + this.canCommit = View.map( commitState, ([current, currentIssues, fiber, result]: readonly [Option.Option, readonly Form.FormIssue[], Option.Option>, Result.Result]) => Option.isSome(current) && currentIssues.length === 0 && Option.isNone(fiber) && !(Result.isRunning(result) || Result.hasRefreshingFlag(result)), ) - this.isCommitting = Subscribable.map( + this.isCommitting = View.map( mutation.result, result => Result.isRunning(result) || Result.hasRefreshingFlag(result), ) diff --git a/packages/effect-fc-next/src/Subscribable.ts b/packages/effect-fc-next/src/Subscribable.ts deleted file mode 100644 index e8fafe6..0000000 --- a/packages/effect-fc-next/src/Subscribable.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Effect, Equivalence, Stream } from "effect" -import { Subscribable } from "effect-lens" -import * as React from "react" -import * as Component from "./Component.js" - - -export * from "effect-lens/Subscribable" - -export const zipLatestAll = []>( - ...elements: T -): Subscribable.Subscribable< - [T[number]] extends [never] - ? never - : { [K in keyof T]: T[K] extends Subscribable.Subscribable ? A : never }, - [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? E : never, - [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? R : never -> => Subscribable.make({ - get: Effect.all(elements.map(v => v.get)), - changes: Stream.zipLatestAll(...elements.map(v => v.changes)), -}) as any - -export declare namespace useAll { - export type Success[]> = [T[number]] extends [never] - ? never - : { [K in keyof T]: T[K] extends Subscribable.Subscribable ? A : never } - - export interface Options { - readonly equivalence?: Equivalence.Equivalence - } -} - -export const useAll = Effect.fnUntraced(function* []>( - elements: T, - options?: useAll.Options>>, -): Effect.fn.Return< - useAll.Success, - [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? E : never, - [T[number]] extends [never] ? never : T[number] extends Subscribable.Subscribable ? R : never -> { - const [reactStateValue, setReactStateValue] = React.useState( - yield* Component.useOnMount(() => Effect.all(elements.map(v => v.get))) - ) - - yield* Component.useReactEffect(() => Stream.zipLatestAll(...elements.map(ref => ref.changes)).pipe( - Stream.changesWith((options?.equivalence as Equivalence.Equivalence | undefined) ?? Equivalence.Array(Equivalence.strictEqual())), - Stream.runForEach(v => - Effect.sync(() => setReactStateValue(v)) - ), - Effect.forkScoped, - ), elements) - - return reactStateValue as any -}) diff --git a/packages/effect-fc-next/src/SynchronizedForm.ts b/packages/effect-fc-next/src/SynchronizedForm.ts index 330628a..96d6915 100644 --- a/packages/effect-fc-next/src/SynchronizedForm.ts +++ b/packages/effect-fc-next/src/SynchronizedForm.ts @@ -17,7 +17,7 @@ import { } from "effect" import * as Form from "./Form.js" import * as Lens from "./Lens.js" -import * as Subscribable from "./Subscribable.js" +import * as View from "./View.js" type FormSchema = Schema.Top & { @@ -43,7 +43,7 @@ export interface SynchronizedForm< readonly schema: FormSchema readonly context: Context.Context readonly target: Lens.Lens - readonly validationFiber: Subscribable.Subscribable>, never, never> + readonly validationFiber: View.View>, never, never> readonly run: Effect.Effect } @@ -59,10 +59,10 @@ export class SynchronizedFormImpl< readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId = SynchronizedFormTypeId readonly path = [] as const - readonly value: Subscribable.Subscribable, TER, never> + readonly value: View.View, TER, never> readonly encodedValue: Lens.Lens - readonly isValidating: Subscribable.Subscribable - readonly canCommit: Subscribable.Subscribable + readonly isValidating: View.View + readonly canCommit: View.View constructor( readonly schema: FormSchema, @@ -75,7 +75,7 @@ export class SynchronizedFormImpl< readonly runSemaphore: Semaphore.Semaphore, ) { super() - this.value = Subscribable.make({ + this.value = View.make({ get: Effect.provide(Effect.map(target.get, Option.some), context), changes: Stream.provideContext( target.changes.pipe( @@ -94,13 +94,13 @@ export class SynchronizedFormImpl< ), lock: Lens.asLensImpl(internalEncodedValue).lock, }) as unknown as Lens.Lens - this.isValidating = Subscribable.map(validationFiber, Option.isSome) - const commitState = Subscribable.zipLatestAll(issues as any, validationFiber as any, isCommitting as any) as unknown as Subscribable.Subscribable>, boolean, ]> - this.canCommit = Subscribable.map( + this.canCommit = View.map( commitState, ([currentIssues, fiber, committing]) => currentIssues.length === 0 && Option.isNone(fiber) && !committing, ) diff --git a/packages/effect-fc-next/src/View.ts b/packages/effect-fc-next/src/View.ts new file mode 100644 index 0000000..04ab6f3 --- /dev/null +++ b/packages/effect-fc-next/src/View.ts @@ -0,0 +1,40 @@ +import { Effect, Equivalence, Stream } from "effect" +import { View } from "effect-lens" +import * as React from "react" +import * as Component from "./Component.js" + + +export * from "effect-lens/View" + +export declare namespace useAll { + export type Success[]> = [T[number]] extends [never] + ? never + : { [K in keyof T]: T[K] extends View.View ? A : never } + + export interface Options { + readonly equivalence?: Equivalence.Equivalence + } +} + +export const useAll = Effect.fnUntraced(function* []>( + elements: T, + options?: useAll.Options>>, +): Effect.fn.Return< + useAll.Success, + [T[number]] extends [never] ? never : T[number] extends View.View ? E : never, + [T[number]] extends [never] ? never : T[number] extends View.View ? R : never +> { + const [reactStateValue, setReactStateValue] = React.useState( + yield* Component.useOnMount(() => Effect.all(elements.map(View.get))) + ) + + yield* Component.useReactEffect(() => View.changes(View.zipLatestAll(...elements)).pipe( + Stream.changesWith((options?.equivalence as Equivalence.Equivalence | undefined) ?? Equivalence.Array(Equivalence.strictEqual())), + Stream.runForEach(v => + Effect.sync(() => setReactStateValue(v)) + ), + Effect.forkScoped, + ), elements) + + return reactStateValue as any +}) diff --git a/packages/effect-fc-next/src/index.ts b/packages/effect-fc-next/src/index.ts index 8829e81..ca7e03d 100644 --- a/packages/effect-fc-next/src/index.ts +++ b/packages/effect-fc-next/src/index.ts @@ -13,5 +13,5 @@ export * as Result from "./Result.js" export * as SetStateAction from "./SetStateAction.js" export * as Stream from "./Stream.js" export * as SubmittableForm from "./SubmittableForm.js" -export * as Subscribable from "./Subscribable.js" export * as SynchronizedForm from "./SynchronizedForm.js" +export * as View from "./View.js" diff --git a/packages/effect-fc-next/test/Subscribable.test.tsx b/packages/effect-fc-next/test/View.test.tsx similarity index 60% rename from packages/effect-fc-next/test/Subscribable.test.tsx rename to packages/effect-fc-next/test/View.test.tsx index 5641d1b..3065a8e 100644 --- a/packages/effect-fc-next/test/Subscribable.test.tsx +++ b/packages/effect-fc-next/test/View.test.tsx @@ -1,10 +1,10 @@ import { render, screen, waitFor } from "@testing-library/react" -import { Effect, Fiber, Layer, Stream, SubscriptionRef } from "effect" +import { Effect, Layer, SubscriptionRef } from "effect" import { Lens } from "effect-lens" import { describe, expect, it } from "vitest" import * as Component from "../src/Component.js" import * as ReactRuntime from "../src/ReactRuntime.js" -import * as Subscribable from "../src/Subscribable.js" +import * as View from "../src/View.js" const makeRuntime = async () => { @@ -18,42 +18,7 @@ const makeRuntime = async () => { } } -describe("Subscribable", () => { - it("zipLatestAll reads current values from all inputs", async () => { - const leftRef = await Effect.runPromise(SubscriptionRef.make(1)) - const rightRef = await Effect.runPromise(SubscriptionRef.make("a")) - const left = Lens.fromSubscriptionRef(leftRef) - const right = Lens.fromSubscriptionRef(rightRef) - - const zipped = Subscribable.zipLatestAll(left, right) - - expect(await Effect.runPromise(zipped.get)).toEqual([1, "a"]) - }) - - it("zipLatestAll emits updates when any input changes", async () => { - const leftRef = await Effect.runPromise(SubscriptionRef.make(1)) - const rightRef = await Effect.runPromise(SubscriptionRef.make("a")) - const left = Lens.fromSubscriptionRef(leftRef) - const right = Lens.fromSubscriptionRef(rightRef) - - const zipped = Subscribable.zipLatestAll(left, right) - const values: Array = [] - - const collector = Effect.runFork(Effect.scoped(zipped.changes.pipe( - Stream.runForEach(value => Effect.sync(() => { - values.push(value as readonly [number, string]) - })), - ))) - - await Effect.runPromise(Lens.set(left, 2)) - await waitFor(() => expect(values).toContainEqual([2, "a"])) - - await Effect.runPromise(Lens.set(right, "b")) - await waitFor(() => expect(values).toContainEqual([2, "b"])) - - await Effect.runPromise(Fiber.interrupt(collector)) - }) - +describe("View", () => { it("useAll returns the latest values and rerenders when any input changes", async () => { const { runtime, effectRuntime, dispose } = await makeRuntime() const countRef = await Effect.runPromise(SubscriptionRef.make(1)) @@ -61,8 +26,8 @@ describe("Subscribable", () => { const count = Lens.fromSubscriptionRef(countRef) const label = Lens.fromSubscriptionRef(labelRef) - const Probe = Component.makeUntraced("SubscribableUseAllProbe")(function*() { - const [currentCount, currentLabel] = yield* Subscribable.useAll([count, label]) + const Probe = Component.makeUntraced("ViewUseAllProbe")(function*() { + const [currentCount, currentLabel] = yield* View.useAll([count, label]) return

}).pipe( @@ -94,8 +59,8 @@ describe("Subscribable", () => { const item = Lens.fromSubscriptionRef(itemRef) const flag = Lens.fromSubscriptionRef(flagRef) - const Probe = Component.makeUntraced("SubscribableUseAllEquivalenceProbe")(function*() { - const [currentItem, currentFlag] = yield* Subscribable.useAll([item, flag], { + const Probe = Component.makeUntraced("ViewUseAllEquivalenceProbe")(function*() { + const [currentItem, currentFlag] = yield* View.useAll([item, flag], { equivalence: ([selfItem, selfFlag], [thatItem, thatFlag]) => selfItem.id === thatItem.id && selfFlag === thatFlag, }) diff --git a/packages/example-next/src/main.tsx b/packages/example-next/src/main.tsx index 125ca5b..3b4d312 100644 --- a/packages/example-next/src/main.tsx +++ b/packages/example-next/src/main.tsx @@ -1,5 +1,5 @@ import { Effect, Layer, SubscriptionRef } from "effect" -import { Component, Lens, ReactRuntime, Subscribable } from "effect-fc-next" +import { Component, Lens, ReactRuntime, View } from "effect-fc-next" import { StrictMode } from "react" import { createRoot } from "react-dom/client" import "./index.css" @@ -10,7 +10,7 @@ const Counter = Component.make("Counter")(function*() { SubscriptionRef.make(0), Lens.fromSubscriptionRef, )) - const [value] = yield* Subscribable.useAll([count]) + const [value] = yield* View.useAll([count]) const increment = yield* Component.useCallbackSync( () => Lens.update(count, n => n + 1), [count], -- 2.52.0 From cc64ae785d03e7f834d58d6c33dda759124b3c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 19 Jul 2026 00:46:36 +0200 Subject: [PATCH 52/61] Refactor Form --- bun.lock | 637 +++++++++--------- packages/effect-fc-next/package.json | 1 + packages/effect-fc-next/src/Form.ts | 57 +- .../effect-fc-next/src/SubmittableForm.ts | 267 ++++---- 4 files changed, 478 insertions(+), 484 deletions(-) diff --git a/bun.lock b/bun.lock index 91d7915..9cee2d3 100644 --- a/bun.lock +++ b/bun.lock @@ -58,6 +58,7 @@ "name": "effect-fc-next", "version": "0.1.0-beta.0", "dependencies": { + "@standard-schema/spec": "^1.1.0", "effect-lens": "^2.0.0-beta.1", }, "devDependencies": { @@ -118,41 +119,41 @@ }, }, "packages": { - "@algolia/abtesting": ["@algolia/abtesting@1.19.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-Lhnez3hhXHk25lfxLAMxvkP4fmN3+1RgADhD2ssMDBYuAsDVReeyP+3SGRx+ntq8ijMrLqUyfvO72TB6jsTteQ=="], + "@algolia/abtesting": ["@algolia/abtesting@1.22.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-BFR6zNowNKcY7Ou7TaJc9QWexES4YKPbmf/OTFofpdsdhz4x6q0lbxp3duO0EHnyrN7rE4ba/TSXuY+BDGu4+g=="], - "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.19.8", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.19.8", "@algolia/autocomplete-shared": "1.19.8" } }, "sha512-3YEorYg44niXcm7gkft3nXYItHd44e8tmh4D33CTszPgP0QWkaLEaFywiNyJBo7UL/mqObA/G9RYuU7R8tN1IA=="], + "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.19.9", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.19.9", "@algolia/autocomplete-shared": "1.19.9" } }, "sha512-4U2JKLMWlDu0CotYyUkWakDxr8AIav3QtIUXXRpfavYN29aVWfzlwJp9T0rPKEf/dO2QCPAUc0Kq1Tj1GJxo2A=="], - "@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.19.8", "", { "dependencies": { "@algolia/autocomplete-shared": "1.19.8" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-ZvJWO8ZZJDpc1LNM2TTBdmQsZBLMR4rU5iNR2OYvEeFBiaf/0ESnRSSLQbryarJY4SVxtoz6A2ZtDMNM+iQEAA=="], + "@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.19.9", "", { "dependencies": { "@algolia/autocomplete-shared": "1.19.9" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-6mExC6X7762s2SV3eJy3QOkB8bdMmnUhQ2agvGVDuzwoGyr3PquGSY/0vPQXCfiAiCaXUz1rXn+lwghgSi0l0w=="], - "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.19.8", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-h5hf2t8ejF6vlOgvLaZzQbWs5SyH2z4PAWygNAvvD/2RI29hdQ54ldUGwqVuj9Srs+n8XUKTPUqb7fvhBhQrnQ=="], + "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.19.9", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-YosP9Uoek6y/Ur1r1qeogk4biMe/hzkyNcgMCciw0//3XpCM7VlYLSHnyt/vOnEOGhCCc0+3v+unEiH6zz+Z1A=="], - "@algolia/client-abtesting": ["@algolia/client-abtesting@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-0ZjA5Hcmaoz5Lj6OG0zhfIyeqzJZnLW2CRJA1W17UwMFGRtZAJ9yJKRvPEDA6gkpsIoQxORTSW6sWFiuYncPNQ=="], + "@algolia/client-abtesting": ["@algolia/client-abtesting@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-7r4Z3NC7yU1oAQVWJNA2HX7tX481F3pJvCGyLIXiTdBcthz4Q/o21jwcMYDFkuI92UWTNBQQmHYgwHo1zS5dzg=="], - "@algolia/client-analytics": ["@algolia/client-analytics@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-kWNodP75iiEaOtemC9F/hlxNBG5E2QUjN1BusnE6m2b4l7Qh/BUO3fGCVsmKJI65VO4VKGGmT43ICvHtTcJ2JQ=="], + "@algolia/client-analytics": ["@algolia/client-analytics@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-avmjXQSq+jadFO8Xl2em05/uQdQnEmHsJyOAdVbZkmVgpMfxL12aJwVVfGNwYr9nulcpuJN1X0lTaQ5wxuNGcA=="], - "@algolia/client-common": ["@algolia/client-common@5.53.0", "", {}, "sha512-YPN45TXD9Wrse185t/Ta7nktZsqpv97oOjCzp2sblHnCL6rBc9TDeJAg1IGl2UpdwnSD05Zu/5wLB4watOUMyg=="], + "@algolia/client-common": ["@algolia/client-common@5.56.0", "", {}, "sha512-v2TPStUhY//ripPjIVclZ8AWc7DEGooXULZGFlFu37zNatgHjw34oZZ+OSbbc/YHO+xZwPl62I1k8xH1m4S2eg=="], - "@algolia/client-insights": ["@algolia/client-insights@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-qAcYTDJE6m924FDDUQvdD6vh7DYaqOeSpFS74IP37/JRV0v4cGBauyxTF2WzDnokUylQDbqreoFIJZfg0Fitmw=="], + "@algolia/client-insights": ["@algolia/client-insights@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-P0ehROpM4Sem3Sqo5x2cKPgj67D3G3jy0rh1Amwkcvsfr6tkvIcdCmerieanqTF7NxUMPNFLkpIFeMO8Rpa50w=="], - "@algolia/client-personalization": ["@algolia/client-personalization@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-fQaY+DkSJOpuUVUe8MQTwrdiKAqkJGhpDarB08duBn/sUv7Bkib6MDRQauCcWTWTe4HIW+EbwQP9R4kci1V/Yw=="], + "@algolia/client-personalization": ["@algolia/client-personalization@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-SXK3Vn3WVxyzbm31oePZBJkp1wpOyuWdd4B/Pv7n0aXDxmeSWhC1R1FC1517mMrFAIaPH4Rt0x6RUe7ZNjz8FA=="], - "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-o72tsiEZGfeS/dxL9IADfzcZWGEwKDEe5CvtrBuT//3JR+SHuTtHRI2ZTf7D7bcKagcbojvO8hnkHdfoakSlYg=="], + "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-5+ZdX8garFnmycnZgKhtXHePEaLj5zqDxI/0lkhhluzCcvTn0/PvvTirTg8hHYetQHvn7GDyeAiqTAieMvMW4A=="], - "@algolia/client-search": ["@algolia/client-search@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-Ds16IyPm/dNJPCU8OzApo2gwGrgWT5BYHhE3NFwZbpCveqyvPDB9sZDDkJ5DsdOGT2aC+R3i0/M1OVXF2qdgPg=="], + "@algolia/client-search": ["@algolia/client-search@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-+mKUdYvqOi0BcvpAEyCEw49vSBptufIcfibtHz2bdr1pI789M46Yt0uQEk/sxtK3teh71OQvVFHaTDzShUWewQ=="], "@algolia/events": ["@algolia/events@4.0.1", "", {}, "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ=="], - "@algolia/ingestion": ["@algolia/ingestion@1.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-oNbT6z4NwD8Pou9VPINGlN/tlG1afESh2EbxqnP6rwl95xKVD/Zlciis1PpNeO/9U/rrajc1+7DcfKi03tX1KQ=="], + "@algolia/ingestion": ["@algolia/ingestion@1.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-9g/zj+AZx5moFcdFIrYQoVrueXivjUcc3MQHtCYT8WhIuk1lUh1AyEhvJCS0XBZld09cLvd1AZ3BvDBpVpX2UA=="], - "@algolia/monitoring": ["@algolia/monitoring@1.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-G+KZb/yd+qAOFn/cEvTGeLxQm8aP3a0od50l3z/ylccY+/o4YG3TNcjU1tFQHW4mXC137GPyR7W70R0kRQDLnA=="], + "@algolia/monitoring": ["@algolia/monitoring@1.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-Qf3Sr6f9A9uxCZUf3MXS0d2b877uYzEB5yxqpVGXAhcJnBCQjrRRon0KvefpGkxy+BshrIJs96OUoMtGqXTFDA=="], - "@algolia/recommend": ["@algolia/recommend@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-6aVfYd55Un6IUgPLbo84WfgFZlS3L0vA1ttzXL5vahHewUJ8jYgd89TzlWRTeej7w70mb9RWsVlFYGmJ/diQww=="], + "@algolia/recommend": ["@algolia/recommend@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-GXWG1rWc5wu8hY4N33Y3b6ernY6sAdAvmKWN/zHAiACOx40WnpG0TVX5YazCAr/9gOYGInSiM2A0y2jy2xbiDA=="], - "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0" } }, "sha512-ke27DqgzCOlt+RbeEdCxtXxMQOnAOi8ujr2wid0DmDKzR95Kw/f9sBsuhBxtjevCqJRJszfRTLY0B1pbO6IhkA=="], + "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0" } }, "sha512-7t24cBxaInS3mZb7ddEaZT/tp6q+/aR4YttsQVyP1/i+LmwPR34atO35KjaLFCcRVrlP7sYOAqkCfg6lIRB+ew=="], - "@algolia/requester-fetch": ["@algolia/requester-fetch@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0" } }, "sha512-GngiOqt2Gq4oLno6yXQVj9om+qSO9SWAoduoTOEg79dKZ62brB8OOIvSJG/vDNoanYi6a7Al9uDZwXvi+bcVTg=="], + "@algolia/requester-fetch": ["@algolia/requester-fetch@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0" } }, "sha512-R7ePHgVYmDFjZpvrsVAfbDz/d4RxKAYZ5/vgLfIsCVRZRryjWl/3INOxpOICzitehQ5FjNtNjcLQTrmHPTcHBQ=="], - "@algolia/requester-node-http": ["@algolia/requester-node-http@5.53.0", "", { "dependencies": { "@algolia/client-common": "5.53.0" } }, "sha512-6mF9LZMUk0QqWvrnxkxBqhswwz6Xfiwy6/gmTzL5HrlhdVG3ITAqGV2k3XmVThP1h0Ulc3VQwiNCD7/Nr4JNlQ=="], + "@algolia/requester-node-http": ["@algolia/requester-node-http@5.56.0", "", { "dependencies": { "@algolia/client-common": "5.56.0" } }, "sha512-PIOUXlSnrqM0S+WOgDRb4RzotydJH7ZoT6tOyL7tAO7qJOfvX5wsEW8Pe+PMKMwvuI4/gIyK9cg2H7lJXqnc4Q=="], "@asamuzakjp/css-color": ["@asamuzakjp/css-color@3.2.0", "", { "dependencies": { "@csstools/css-calc": "^2.1.3", "@csstools/css-color-parser": "^3.0.9", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw=="], @@ -362,23 +363,23 @@ "@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "^7.29.7", "@babel/helper-validator-identifier": "^7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], - "@biomejs/biome": ["@biomejs/biome@2.4.16", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.16", "@biomejs/cli-darwin-x64": "2.4.16", "@biomejs/cli-linux-arm64": "2.4.16", "@biomejs/cli-linux-arm64-musl": "2.4.16", "@biomejs/cli-linux-x64": "2.4.16", "@biomejs/cli-linux-x64-musl": "2.4.16", "@biomejs/cli-win32-arm64": "2.4.16", "@biomejs/cli-win32-x64": "2.4.16" }, "bin": { "biome": "bin/biome" } }, "sha512-x9ajFh1zChVybCiM3TN6OD4phAqLgtPZjFrZF+aTMYCPjwBO+k529TX7PPsAqtGNLeV4UgzwQnowEgS7bGmzcA=="], + "@biomejs/biome": ["@biomejs/biome@2.5.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.4", "@biomejs/cli-darwin-x64": "2.5.4", "@biomejs/cli-linux-arm64": "2.5.4", "@biomejs/cli-linux-arm64-musl": "2.5.4", "@biomejs/cli-linux-x64": "2.5.4", "@biomejs/cli-linux-x64-musl": "2.5.4", "@biomejs/cli-win32-arm64": "2.5.4", "@biomejs/cli-win32-x64": "2.5.4" }, "bin": { "biome": "bin/biome" } }, "sha512-xy5FNE5kQJKyK5MR1gJy6ztXYx4WBAbYGlK04lMEgmyPRWKybY9NFwiG9yo0XdzOU8Xvhj41u034J1ywfoWfMw=="], - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wxPvu4XOA85YJk9ixSWUmq/QBHbid85BISbOAqqBM/5xQpPk9ayjk5375tOlSC0BeCwNSbPFafQBm+vBumXq0A=="], + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4o3NFRobXHynkgcFVrlZsoDAFtF2ldlEGN8sORSws5ZQqyY4PXnPUIylu4ksfyHuwkfvDREuWh3JK+niRwGq3w=="], - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-xFCqGPwYusQJp4N4NJLi1XJiZqjwFdjhT+KqtNy+Ug3qgfczqnTa6MSDvxJF6TkuDLoYJItMapz6tAf7kCekFw=="], + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.5.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-D32P5HkU2Y6PySuC/WsVDTOgsDwVFmujzhhhOQjajtATpVWFDXuVd3oRbsWNSEA+aaFzyzZm22szsyydBYlSyQ=="], - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-2kFb4//jxfZaP6D+Rj5VkHkxgyD9EoRAVBEQb8PKRv+s4NO2zYNJKXFaJmK1CmhufJOWEfpHKaRbOja7qjmdhQ=="], + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.5.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-pSEfW7B8kTsXUjUxC1xVVK+y85Ht3C5XxZ9gclmC7/3Ku9Vqz8jmI7k0p/BNIjQ6t4sFERI2sFeH73ybiZl6YQ=="], - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-oYxnW0ARfJkr72ezzF2OR8N/rtkgLUQeYtF8cFhVswbknHxtTcmzSsanVJP8yQKnGpGpc2ck6c5zLvHahL6Cbg=="], + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.5.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-Rpm5/AT1m+DlJmUoYvS4/vXc+0tXJPJ2NQz25TGPyHVF5JrWy75PE0GH6kVxsKtQDuCH4OgzquZq0R4kj/wCVg=="], - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.16", "", { "os": "linux", "cpu": "x64" }, "sha512-NbcBbi/nJqn5baae6wqRXdS7Gadf2uRpehSh6vMSYpG8OhkXl/Xg8aorWrJ+9VWqAT5ml90alLvorkpMW0nBwQ=="], + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.5.4", "", { "os": "linux", "cpu": "x64" }, "sha512-FNxojWJkL7EajAuzBgoLe0T2G0y112M4lBrDIFl/DomFTx8yqenYOIdsRLNXvOvBBofE8hJi85LjzLmBDpY7/Q=="], - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.16", "", { "os": "linux", "cpu": "x64" }, "sha512-iHDS+MCM65DPqWGu+ECC3uoALyj2H7F4nVUPxIPjz/PIl94EUu+EDfGZDzFP+NY1EOPVt9NQvwFqq7HdMmowdg=="], + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.5.4", "", { "os": "linux", "cpu": "x64" }, "sha512-aby/PohmmgbShcHqFsZVzG8H6D98+P+A6xRWRrQcLW1pCjabcov5UUlke4UqNQBYTkDQav+jB4zyyDDeKB2GaA=="], - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-0rgImMsNb5v/chhkIFe3wu7PEFClS6RBAYUijGL9UsYN3PanSaoK24HSSuSJb1pYbYYVjzAyZTl3gtjJ84BM8A=="], + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.5.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-emoXexPZIPAZkz2RKmA95WJUqK3I5MJNYtwEbL5ESciRzhmFMMyekDhNG8hpeOaK+ZGRDxAU4wvGuA5IHQ0h0w=="], - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.16", "", { "os": "win32", "cpu": "x64" }, "sha512-Kp85jgoBHa05gix6UIRjfCDiUV3w/8VIdZ247VyyO2gEjaw12WEVhdIjlxp/AMzXxqxQwbxNTDVZ3Mwd2RG5rw=="], + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.4", "", { "os": "win32", "cpu": "x64" }, "sha512-U1jaluLw1qQc2Tx7/CeSoL9N5XcqIH+GWjpUAy1ouB5nVjSCMNO+NNHdY3RAs8zxNurLWAdj6pehQdCA2zyU+Q=="], "@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="], @@ -498,7 +499,7 @@ "@docusaurus/cssnano-preset": ["@docusaurus/cssnano-preset@3.10.1", "", { "dependencies": { "cssnano-preset-advanced": "^6.1.2", "postcss": "^8.5.4", "postcss-sort-media-queries": "^5.2.0", "tslib": "^2.6.0" } }, "sha512-eNfHGcTKCSq6xmcavAkX3RRclHaE2xRCMParlDXLdXVP01/a2e/jKXMj/0ULnLFQSNwwuI62L0Ge8J+nZsR7UQ=="], - "@docusaurus/faster": ["@docusaurus/faster@3.10.1", "", { "dependencies": { "@docusaurus/types": "3.10.1", "@rspack/core": "^1.7.10", "@swc/core": "^1.7.39", "@swc/html": "^1.13.5", "browserslist": "^4.24.2", "lightningcss": "^1.27.0", "semver": "^7.5.4", "swc-loader": "^0.2.6", "tslib": "^2.6.0", "webpack": "^5.95.0" } }, "sha512-XTZhE5C1gZ/DaYYMlSk02dwP5vhpQON5QHVz1s3892mSESAywgWanURpXEDAvt4GvGuq7s+XP8rTWHZvfaJmdQ=="], + "@docusaurus/faster": ["@docusaurus/faster@3.10.2", "", { "dependencies": { "@docusaurus/types": "3.10.2", "@rspack/core": "^1.7.10", "@swc/core": "^1.15.40", "@swc/html": "^1.15.40", "browserslist": "^4.24.2", "lightningcss": "^1.27.0", "semver": "^7.5.4", "swc-loader": "^0.2.6", "tslib": "^2.6.0", "webpack": "^5.95.0" } }, "sha512-p/5E5/RyHv+QWusJMPN5i3OMJTqTgkhuwzVbB1AReDWTUHXQCmf5mlTFzGiDrWeQWIDOKsuOPn1jJh0s9LUOHA=="], "@docusaurus/logger": ["@docusaurus/logger@3.10.1", "", { "dependencies": { "chalk": "^4.1.2", "tslib": "^2.6.0" } }, "sha512-oPjNFnfJsRCkePVjkGrxWGq4MvJKRQT0r9jOP0eRBTZ7Wr9FAbzdP/Gjs0I2Ss6YRkPoEgygKG112OkE6skvJw=="], @@ -550,77 +551,77 @@ "@effect-fc/example-next": ["@effect-fc/example-next@workspace:packages/example-next"], - "@effect/language-service": ["@effect/language-service@0.86.2", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-SaPln+8srOqDJDUwNTDmP5e+IYpEDr9+1epGznnsLqu8xvo6VnxyWARdeLpqvZJlb0Pgy9ca7ppqvvdWbHPXAg=="], + "@effect/language-service": ["@effect/language-service@0.86.6", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-uwXbp+lWzt60bZnm6lG6S5DWy0m6TthUzV2hcQoiS6NzieEDm07tuBakscxOXoO+AU9+yTH+0TSIa9mEDt9dFA=="], - "@effect/platform": ["@effect/platform@0.96.1", "", { "dependencies": { "find-my-way-ts": "^0.1.6", "msgpackr": "^1.11.10", "multipasta": "^0.2.7" }, "peerDependencies": { "effect": "^3.21.2" } }, "sha512-cjB1QZZYEP8JXCFNGvBLVi0T6YUBQTmOVEUA3SDbiQ6RUO+p6CE3eyD2vMWmrz5nE8yY5QSAuOV9v0boEcUv+A=="], + "@effect/platform": ["@effect/platform@0.96.3", "", { "dependencies": { "find-my-way-ts": "^0.1.6", "msgpackr": "^1.11.10", "multipasta": "^0.2.7" }, "peerDependencies": { "effect": "^3.21.5" } }, "sha512-LzvIj4HYE++TcTv/cVTCI/GRvQTV0ymwRmgjZMzNB5dU4OS05pTN36RKN0npiOm5orLJgw4yjIv1dNZoYGh/vg=="], "@effect/platform-browser": ["@effect/platform-browser@0.76.0", "", { "dependencies": { "multipasta": "^0.2.7" }, "peerDependencies": { "@effect/platform": "^0.96.0", "effect": "^3.21.0" } }, "sha512-cUyBpcLstrP/HiNsIePMBAI6R1+u6aRFlAUZb4wf08y1d1Vqf/Dmxsq14ZjBfnSYiqBPrCeYf1ZI+qMGQQL0RA=="], - "@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], + "@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], - "@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="], + "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.27.7", "", { "os": "android", "cpu": "arm" }, "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.7", "", { "os": "android", "cpu": "arm64" }, "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.27.7", "", { "os": "android", "cpu": "x64" }, "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.7", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.7", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.7", "", { "os": "linux", "cpu": "arm" }, "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.7", "", { "os": "linux", "cpu": "ia32" }, "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.7", "", { "os": "linux", "cpu": "ppc64" }, "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.7", "", { "os": "linux", "cpu": "none" }, "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.7", "", { "os": "linux", "cpu": "s390x" }, "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.7", "", { "os": "linux", "cpu": "x64" }, "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.7", "", { "os": "none", "cpu": "x64" }, "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.7", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.7", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="], - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.7", "", { "os": "none", "cpu": "arm64" }, "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw=="], + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.7", "", { "os": "sunos", "cpu": "x64" }, "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.7", "", { "os": "win32", "cpu": "ia32" }, "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.7", "", { "os": "win32", "cpu": "x64" }, "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="], - "@floating-ui/core": ["@floating-ui/core@1.7.5", "", { "dependencies": { "@floating-ui/utils": "^0.2.11" } }, "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ=="], + "@floating-ui/core": ["@floating-ui/core@1.8.0", "", { "dependencies": { "@floating-ui/utils": "^0.2.12" } }, "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ=="], - "@floating-ui/dom": ["@floating-ui/dom@1.7.6", "", { "dependencies": { "@floating-ui/core": "^1.7.5", "@floating-ui/utils": "^0.2.11" } }, "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ=="], + "@floating-ui/dom": ["@floating-ui/dom@1.8.0", "", { "dependencies": { "@floating-ui/core": "^1.8.0", "@floating-ui/utils": "^0.2.12" } }, "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg=="], - "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.8", "", { "dependencies": { "@floating-ui/dom": "^1.7.6" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A=="], + "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.9", "", { "dependencies": { "@floating-ui/dom": "^1.8.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg=="], - "@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="], + "@floating-ui/utils": ["@floating-ui/utils@0.2.12", "", {}, "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww=="], "@hapi/hoek": ["@hapi/hoek@9.3.0", "", {}, "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="], @@ -648,21 +649,21 @@ "@jsonjoy.com/codegen": ["@jsonjoy.com/codegen@1.0.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g=="], - "@jsonjoy.com/fs-core": ["@jsonjoy.com/fs-core@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-uI++Wx6VkBJqVmkb4ZeExwAVpZiA2Do5NrEtXoDk0Pdvce3ytFXJoviT1sLOj16+qDIMnD5nWPfOhVpnDmRJKg=="], + "@jsonjoy.com/fs-core": ["@jsonjoy.com/fs-core@4.64.0", "", { "dependencies": { "@jsonjoy.com/fs-node-builtins": "4.64.0", "@jsonjoy.com/fs-node-utils": "4.64.0", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-zs2TAq7Six5jgMuoMNjpspAvOP3mhtgq/k1UyQodEzCtQi/N83y2/y+zcvnZSGp/Rxq96DBN+bValOBQAyn/ew=="], - "@jsonjoy.com/fs-fsa": ["@jsonjoy.com/fs-fsa@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.6", "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-pKkw/yC5CzSZKhIIUIsH1przOa+K5jGmZIg1sWaSF24JojyrUFbjcQv7QrcGAudriei6HQ6R0BFj+V8NbQinJw=="], + "@jsonjoy.com/fs-fsa": ["@jsonjoy.com/fs-fsa@4.64.0", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.64.0", "@jsonjoy.com/fs-node-builtins": "4.64.0", "@jsonjoy.com/fs-node-utils": "4.64.0", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-nMWOVbkLFyEgmXZih3wyvxA9XpgyyqyfrINMHvEFqhi7uqfRl7c9ERJt6yX7vgMPrB9Uo+OJO+Spa0cFzPD01w=="], - "@jsonjoy.com/fs-node": ["@jsonjoy.com/fs-node@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.6", "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6", "@jsonjoy.com/fs-print": "4.57.6", "@jsonjoy.com/fs-snapshot": "4.57.6", "glob-to-regex.js": "^1.0.0", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-Kbn1jdkvDN4F2+BhoB6mMu7NCbhP0bgA5NcI1aJj/Q5UcU+I1JLLW+dEQean33iV4tXv35AzBVKPICnDltBpxw=="], + "@jsonjoy.com/fs-node": ["@jsonjoy.com/fs-node@4.64.0", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.64.0", "@jsonjoy.com/fs-node-builtins": "4.64.0", "@jsonjoy.com/fs-node-utils": "4.64.0", "@jsonjoy.com/fs-print": "4.64.0", "@jsonjoy.com/fs-snapshot": "4.64.0", "glob-to-regex.js": "^1.0.0", "thingies": "^2.5.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-dO+NNkODbUli4uV42bcNrrLvq5rE7SNpdZ5TNd0dtbLsAaNK3MDiIC9lUi+brboGoIjW6vd2fB1qao60nrk5xA=="], - "@jsonjoy.com/fs-node-builtins": ["@jsonjoy.com/fs-node-builtins@4.57.6", "", { "peerDependencies": { "tslib": "2" } }, "sha512-V4DgEFT3Cg5S9fCMOZSCVdTxdJWWLBO0WnAazV7hnCM96u5zXHyW/ubDAfcSVwqjkMJ50W1Y44IXtxRoIwaCVg=="], + "@jsonjoy.com/fs-node-builtins": ["@jsonjoy.com/fs-node-builtins@4.64.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-/o7WRFhUWaM/fOrslwLZGnzn4RmRILykn+lAL+mNObqqRNw+CQSiij6hpCeZ+C7buhdoVo7go/OYqzaSUfDYmA=="], - "@jsonjoy.com/fs-node-to-fsa": ["@jsonjoy.com/fs-node-to-fsa@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-fsa": "4.57.6", "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6" }, "peerDependencies": { "tslib": "2" } }, "sha512-+JptNw3iifihxH2rEXrninDzX4FFVW8JD/wPR8GbJPAeL9CQUSblrlumOPB5gZuS7tYRX+PJPLtT7XzKoRhv/Q=="], + "@jsonjoy.com/fs-node-to-fsa": ["@jsonjoy.com/fs-node-to-fsa@4.64.0", "", { "dependencies": { "@jsonjoy.com/fs-fsa": "4.64.0", "@jsonjoy.com/fs-node-builtins": "4.64.0", "@jsonjoy.com/fs-node-utils": "4.64.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-WDD9WVs0hb7UAEKTgZW2f66WDrbj7gIIWwpP3spbLyXa0rghtUaFTB8L4gdR3ZCWwiKIsj38/CNijpVmpnuPUw=="], - "@jsonjoy.com/fs-node-utils": ["@jsonjoy.com/fs-node-utils@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-node-builtins": "4.57.6" }, "peerDependencies": { "tslib": "2" } }, "sha512-foyUrfS7WmYEUzqYXSNxmJBcSj04TABrkpFabwO9SCDCpVCfJ+qG+2sk5FjfiflG2n0SDFZDCJ6vYlJAEpxJFg=="], + "@jsonjoy.com/fs-node-utils": ["@jsonjoy.com/fs-node-utils@4.64.0", "", { "dependencies": { "@jsonjoy.com/fs-node-builtins": "4.64.0", "glob-to-regex.js": "^1.0.1" }, "peerDependencies": { "tslib": "2" } }, "sha512-k5Indsx9hWW9xSF7Y6oSKKwtCUNhzZxadub3owhIlitc+iMRVlPPdX2duTKQWBL3qNWpXya8jykgaaWpheeS4w=="], - "@jsonjoy.com/fs-print": ["@jsonjoy.com/fs-print@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-node-utils": "4.57.6", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-96eAn4Dudtt67LTeuU47yUD+pg9/G/oKpI10zei9ljk3X3WK4lYKc+n3cpaPCAbKPzoyfxl0mXm8f8Y7BOSFXw=="], + "@jsonjoy.com/fs-print": ["@jsonjoy.com/fs-print@4.64.0", "", { "dependencies": { "@jsonjoy.com/fs-node-utils": "4.64.0", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-PHZFccchvkhWrwPWHjmVAhbC3vSHCtyZvlZfJJ3ho2bnzl450hXri6/8e6pbkWdH+SkmLXNml0sV8e5HDAfxKw=="], - "@jsonjoy.com/fs-snapshot": ["@jsonjoy.com/fs-snapshot@4.57.6", "", { "dependencies": { "@jsonjoy.com/buffers": "^17.65.0", "@jsonjoy.com/fs-node-utils": "4.57.6", "@jsonjoy.com/json-pack": "^17.65.0", "@jsonjoy.com/util": "^17.65.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-V57CMzbOgTzUWGOWQ8GzHQdpJP6JnrYVNCtTBNxVYEnlVRvo4uEJqHhtAT8vhDFrIuJOXLrTL1Fki4h5oI7xxg=="], + "@jsonjoy.com/fs-snapshot": ["@jsonjoy.com/fs-snapshot@4.64.0", "", { "dependencies": { "@jsonjoy.com/buffers": "^17.65.0", "@jsonjoy.com/fs-node-utils": "4.64.0", "@jsonjoy.com/json-pack": "^17.65.0", "@jsonjoy.com/util": "^17.65.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-oM7UDeL83q6NBzzsfKAsYKXKVXlykKFqqOLh4xZZKAzzROTlInkPbc6LTDGThEOnPiFiUzA7tYziHG9xavd76Q=="], "@jsonjoy.com/json-pack": ["@jsonjoy.com/json-pack@1.21.0", "", { "dependencies": { "@jsonjoy.com/base64": "^1.1.2", "@jsonjoy.com/buffers": "^1.2.0", "@jsonjoy.com/codegen": "^1.0.0", "@jsonjoy.com/json-pointer": "^1.0.2", "@jsonjoy.com/util": "^1.9.0", "hyperdyperid": "^1.2.0", "thingies": "^2.5.0", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg=="], @@ -700,7 +701,7 @@ "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", "", { "os": "win32", "cpu": "x64" }, "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], "@noble/hashes": ["@noble/hashes@1.4.0", "", {}, "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg=="], @@ -710,27 +711,27 @@ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], - "@oxc-project/types": ["@oxc-project/types@0.133.0", "", {}, "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA=="], + "@oxc-project/types": ["@oxc-project/types@0.139.0", "", {}, "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw=="], - "@peculiar/asn1-cms": ["@peculiar/asn1-cms@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "@peculiar/asn1-x509-attr": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-hew63shtzzvBcSHbhm+cyAmKe6AIfinT9hzEqSPjDC6opTTMKmTkQ0gHuN2KsWlvqiKw1S/fS94fhag/FJkioQ=="], + "@peculiar/asn1-cms": ["@peculiar/asn1-cms@2.8.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.8.0", "@peculiar/asn1-x509": "^2.8.0", "@peculiar/asn1-x509-attr": "^2.8.0", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-NgekZOrSJFSBFLFoLfwePguAWAx7z1+f2TEsWFUMyiqqfntZ4+S/S5hzqME3q4pCA0iOsFKdwiQ35dwY24eVqA=="], - "@peculiar/asn1-csr": ["@peculiar/asn1-csr@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-VVsAyGqErT9D1SY4aEqozThXMVI+ssVRiv2DDeYuvpBKLIgZ3hYs3Ay3u/VSoKq6ESFi9cf6rf3IOOzfwh7oMA=="], + "@peculiar/asn1-csr": ["@peculiar/asn1-csr@2.8.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.8.0", "@peculiar/asn1-x509": "^2.8.0", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-akbF8+uvleHs8sejNPQxwmVFuInAg6FMNHOwMILXfP518YfFJwdR3jr6oNUPOaEJfuEhn/vkNOCIT6ASUd4mbg=="], - "@peculiar/asn1-ecc": ["@peculiar/asn1-ecc@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-n7KEs/Q/wrB415cxy4fHOBhegp4NdJ15fkJPwcB/3/8iNBQC2L/N7SChJPKDJPZGYH0jD4Tg4/0vnHmwghnbKw=="], + "@peculiar/asn1-ecc": ["@peculiar/asn1-ecc@2.8.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.8.0", "@peculiar/asn1-x509": "^2.8.0", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-ohwlk+u9Rv2NOAY1c6MfHj45ATVF8R1DUN/WCgABiRtLi2ZftlZWZX7KvpAbU8v9xPcmoILfELeEABj/rn18AQ=="], - "@peculiar/asn1-pfx": ["@peculiar/asn1-pfx@2.7.0", "", { "dependencies": { "@peculiar/asn1-cms": "^2.7.0", "@peculiar/asn1-pkcs8": "^2.7.0", "@peculiar/asn1-rsa": "^2.7.0", "@peculiar/asn1-schema": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-V/nrlQVmhg7lYAsM7E13UDL5erAwFv6kCIVFqNaMIHSVi7dngcT839JkRTkQBqznMG98l2XjxYk74ZztAohZzA=="], + "@peculiar/asn1-pfx": ["@peculiar/asn1-pfx@2.8.0", "", { "dependencies": { "@peculiar/asn1-cms": "^2.8.0", "@peculiar/asn1-pkcs8": "^2.8.0", "@peculiar/asn1-rsa": "^2.8.0", "@peculiar/asn1-schema": "^2.8.0", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-5yof1ytoB++RQtaFbqSUJ8pxDJtZT6vbVqZ8XoJ61ph7UjNVvfFwAilnCodqkNsAodpy13gDhoxZXw00pghnyg=="], - "@peculiar/asn1-pkcs8": ["@peculiar/asn1-pkcs8@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-9GTl1nE8Mx1kTZ+7QyYatDyKsm34QcWRBFkY1iPvWC3X4Dona5s/tlLiQsx5WzVdZqiMBZNYT0buyw4/vbhnjw=="], + "@peculiar/asn1-pkcs8": ["@peculiar/asn1-pkcs8@2.8.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.8.0", "@peculiar/asn1-x509": "^2.8.0", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-qAKXtLpBEw9LqhKpjw3ajZSXlBur+ipW+y2ivVBQAG6F6qRx94yO+1ZR4mvw+YaCfKSaOzLeYEzsPaBp4SJELA=="], - "@peculiar/asn1-pkcs9": ["@peculiar/asn1-pkcs9@2.7.0", "", { "dependencies": { "@peculiar/asn1-cms": "^2.7.0", "@peculiar/asn1-pfx": "^2.7.0", "@peculiar/asn1-pkcs8": "^2.7.0", "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "@peculiar/asn1-x509-attr": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-Bh7m+OuIaSEllPQcSd9OSp93F4ROWH7sbITWV8MI+8dwsjE5111/87VxiWVvYFKyww3vp39geLv9ENqhwWHcew=="], + "@peculiar/asn1-pkcs9": ["@peculiar/asn1-pkcs9@2.8.0", "", { "dependencies": { "@peculiar/asn1-cms": "^2.8.0", "@peculiar/asn1-pfx": "^2.8.0", "@peculiar/asn1-pkcs8": "^2.8.0", "@peculiar/asn1-schema": "^2.8.0", "@peculiar/asn1-x509": "^2.8.0", "@peculiar/asn1-x509-attr": "^2.8.0", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-b5nDWCnkV60+cQ141D6sVVwK9nz64R5n3zSVnklGd+ECdkW2Ol3U1a6yYFlalpSOaD557yuJB64A+q42jG7lUQ=="], - "@peculiar/asn1-rsa": ["@peculiar/asn1-rsa@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-/qvENQrXyTZURjMqSeofHul0JJt2sNSzSwk36pl2olkHbaioMQgrASDZAlHXl0xUlnVbHj0uGgOrBMTb5x2aJQ=="], + "@peculiar/asn1-rsa": ["@peculiar/asn1-rsa@2.8.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.8.0", "@peculiar/asn1-x509": "^2.8.0", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-zHEUlCqB2mk7x2lxDwHHJy7hWZOPdGHVlsmITWKB5/PbQo61atbu9PJ/0r9dQNMwFzbKPXZ8uK8/91eUhRznSg=="], - "@peculiar/asn1-schema": ["@peculiar/asn1-schema@2.7.0", "", { "dependencies": { "@peculiar/utils": "^2.0.2", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-W8ZfWzLmQnrcky+eh3tni4IozMdqBDiHWU0N+vve/UGjMaUs8c0L7A2oEdkBXS8rTpWDpK/aoI3DG/L/hxmxPg=="], + "@peculiar/asn1-schema": ["@peculiar/asn1-schema@2.8.0", "", { "dependencies": { "@peculiar/utils": "^2.0.2", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q=="], - "@peculiar/asn1-x509": ["@peculiar/asn1-x509@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/utils": "^2.0.2", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-mUn9RRrkGDnG4ALfunDmzyRW5dg+sWCj/pfnCCqEHYbkGxEpvUt6iVJv8Yw1cyp6SWZ26ZE5oSmI5SqEaen15g=="], + "@peculiar/asn1-x509": ["@peculiar/asn1-x509@2.8.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.8.0", "@peculiar/utils": "^2.0.2", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-N0CMuhWUzsWEVq6F1q9X6+VKUnWzSW+cSVg+aPaGGwDdbFoFWTYgin5MHwXgpWd6y9COMBxnfy/Qc+Xc7F0Zwg=="], - "@peculiar/asn1-x509-attr": ["@peculiar/asn1-x509-attr@2.7.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.7.0", "@peculiar/asn1-x509": "^2.7.0", "asn1js": "^3.0.6", "tslib": "^2.8.1" } }, "sha512-NS8e7SOgXipkzUPLF/sce7ukpMpWjhxYsH0n6Y+bHYo4TTxOb95Zv7hqwSuL212mj5YxovjdOKQOgH1As3E94w=="], + "@peculiar/asn1-x509-attr": ["@peculiar/asn1-x509-attr@2.8.0", "", { "dependencies": { "@peculiar/asn1-schema": "^2.8.0", "@peculiar/asn1-x509": "^2.8.0", "asn1js": "^3.0.10", "tslib": "^2.8.1" } }, "sha512-tHjkfS/qhMnmrlB2J9NhflQlQ7In3khO3CfmVrriOlpTeErY9ZIKOso1hQ5JQiyrJ7ShvqVPk7E5fQmbclkSKA=="], "@peculiar/utils": ["@peculiar/utils@2.0.3", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ=="], @@ -740,7 +741,7 @@ "@pnpm/network.ca-file": ["@pnpm/network.ca-file@1.0.2", "", { "dependencies": { "graceful-fs": "4.2.10" } }, "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA=="], - "@pnpm/npm-conf": ["@pnpm/npm-conf@3.0.2", "", { "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", "config-chain": "^1.1.11" } }, "sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA=="], + "@pnpm/npm-conf": ["@pnpm/npm-conf@3.0.3", "", { "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", "config-chain": "^1.1.11" } }, "sha512-//0sR/cow/s4ICQaYoAobOl4aU8cjU6x/V24V7XkKotb9+O+3zySIYp146vpaobYHnxa4pZX8NkV54Z5AwbDKA=="], "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], @@ -748,101 +749,101 @@ "@radix-ui/number": ["@radix-ui/number@1.1.2", "", {}, "sha512-ceTwaxc4I5IOi97DgCotl3pqiyRGvffcc0oOsE2dQYaJOFIDsDt4VWG6xEbg1QePv9QWausCEIppud/tJ1wNig=="], - "@radix-ui/primitive": ["@radix-ui/primitive@1.1.4", "", {}, "sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ=="], + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.5", "", {}, "sha512-d86WIWFYNtGA0H/d8exstrTRTp7eWJYlYJbtNofxr/3ljupZYn6EFDG/Qgu/0Kc8v7yMUxySagqJsL1+PdYjWg=="], - "@radix-ui/react-accessible-icon": ["@radix-ui/react-accessible-icon@1.1.9", "", { "dependencies": { "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-5W9KzJz/3DeYbGJHbZv8Q6AkxMOKUmALfc+PRg9dWwJZMk6zD37Sz8sZrF7UD6CBkiJvn7dNeRzn5G7XiCMyig=="], + "@radix-ui/react-accessible-icon": ["@radix-ui/react-accessible-icon@1.1.11", "", { "dependencies": { "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-HQDOFTKwSnmUij6l54wYJJtxTAnxI71+YJLOrjm2ladFB8HAV5Jt7hwaZPhWTGBkYoW4+ZAOfNZrLDh/qvxSYA=="], - "@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collapsible": "1.1.13", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-xITxBB2p5m5tAe7M0F95kb4uAh7jSIKGlExMEm93HlW+XxZHV2eXFbPWLktd4JhRiwcnXNbO7iekcrbZy6ZCvA=="], + "@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collapsible": "1.1.16", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-BpZJNmetujnGgUI6OX0jEhEmlA46WPqgub8Rv09Kyquwd0cc1ndMKpiPYCjmBU6KSSRPAMtgLpEoZSG/tdNIWQ=="], - "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dialog": "1.1.16", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-vPaIgo0mxYlvcFaM9jB2Uot9TjGXMuAPEvrc6BOLeV+I5U8s1dkIoouYaa6lmSfc5SPMo5x5djOTOTvaigdGMQ=="], + "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-dialog": "1.1.19", "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FA7n1f6D/DwGE0+AWxiY5LacNbbExQuEgMubeG06idEaH+mSLuf9dp/qBNqOnvbTQ+4gZ2ue1RATF1Ub91Mg5g=="], - "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-yqHW5WQ/cTpU/un7dqqIKNy2iRU8BC0JB78PEzTfCCYvZu1U6W9KwObAniMk9nhSfyotKPQTYaUD/HB0f5muig=="], + "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Kdil9BB1rIFC/khmf4hC35bn8701AJcizTU7G7cUbEbk5XqqbjDuHW60uUfKqO5WojjZcbAW51Q7P0hRmMLw8A=="], - "@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Xy+Dpxt/5n9rVTdPrNFmf8GwG1NlT1pzCF/z1MgOGZMLZWdWl+km+ZRWGQAPEhbkzSwYEsfYmTca8NhUtVxqnw=="], + "@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-IUAhIVpBUvP5NNICjlaB1OFmtRLGqQqTF3ZOSGPoq3XeLXRFtHiWTRxSVEULgOd9GQR2c7tsYqDnhUennapZnw=="], - "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.12", "", { "dependencies": { "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-NQCQyWC7QrDPhjMn8hUqFeU0lUrprIgm1AyMgLbzuQJibNnatdc3SSMo3/UGFu/eUkJUU1cEcKCnyhXTQzq6tA=="], + "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.2.2", "", { "dependencies": { "@radix-ui/react-context": "1.2.0", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sST0qh8GzOB7besQ3tMLWLyngnRuSk0gc/Hm+667KYKQFCt6Y6ZXv25WlqM7dIDK54ULCh5+CHmk4LIolzfz+A=="], - "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.4", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m3JmIOAX5ZzZ6VPjxEU2dbTOhoHi0nT5riwcDwe8idocsWf4a5DXJLDtZ6LfJwMBx7W+A2b7kp2TgPEKtaiF6A=="], + "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.7", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JroKHfQBfh+fDuzpPsBC+pESkhuq8ql4hljTguz8MWnS35cISr3d/Jhl9kYrB44FlDtxCArYdDvTx+BSsJ64rQ=="], - "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-F0s8+p2XNpfc3k02zBfB0jPWbkHVG162+p7BdUMyJ2308QMqZ+oaclX+FAzKFovgL5OqRU+Rvy6f/vbdlJVaqA=="], + "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-opfXRe6nnzyGmCDPx+l1Aqo/RbqWtQal2FnsBqF9hhePp6j0LsRoBaRxcMOlTv+uYTJVtWYZKg9t9wTe+BA/ZA=="], - "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.9", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zuSVi7ziP7uQRqc+yGxsKJfNkdyHv3ZKDaHe0gzg4dRgws96TPKWIiz84tVHP4GEcEl8bC0mdt17NkcxaJHmaQ=="], + "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.12", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-nb67INpE0IahJKN7EYPp9m9YGwYeKlnzxT3MwXVkgCskaSJia97kG4T0ywpjNUSSnoJk/uvk12V8vbrEHEj+/Q=="], "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA=="], - "@radix-ui/react-context": ["@radix-ui/react-context@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg=="], + "@radix-ui/react-context": ["@radix-ui/react-context@1.2.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-fOE+JtN9rygNZkCnHRBEP0TAvLldlhyOxMsbwFvTP4nAs+nBmfnna+o/Zski2wkmY1YMrFC0aSzsHoLY47iLrg=="], - "@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.3.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-menu": "2.1.17", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-d7CouXhAW+CGmFOqmB+IEvd3E9GcaqfgvfjCc3hfulp2pkaUCEVEGa0SN5nNWYA+IvQ6g1Pt+S5dpNn1AoY9hg=="], + "@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-menu": "2.1.20", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-PS+gKE0z2prJ74Y0sM+brAGK4mYOHIR7TlcV5EJgUQ6E0xMvyswkK2X4yRqyganrzsRL+WCSKAPu0NQITICRWg=="], - "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-l9ok83YBclEZhbjgzt76Hw733e6cvRKPNgO6GJ/IETlufXG9p+fRu2wlvpImQvR6xdJ8h7J8J2DBvsPEiEsKMw=="], + "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.12", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-+HhbN2+YtkRgVirjZ2afMeutQRuGOrdkWR5+EFC58SJojGmtyNQwYzgi6tHBpOxvFHefMtPeHdgtjz0BOGxFQg=="], "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA=="], - "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-escape-keydown": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-MhoruH6xEzsbvOmo4TNgMfmtvRGyDZw4MDSdf4ybMHfezjqwzv6hyd4lsMzBp8K9Sn6sGzCF62x1I7BYUECXOg=="], + "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-effect-event": "0.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-b0XaRlzn2QKuo10XyNgi2DAJDf5XC9d1nD3FJcuvCjbR7+4Ad28zmZsLsqx+hvDEzMnRuZaZxZm9gYObV6RmRA=="], - "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.17", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-S6b3Jm57sY5EdDyOMLkacbB0qMnKhy1RCKZCt795ZkmtUOAvojYIZ5p7dXHIh5Cyr3jCLLI5/g64V3FKLudZmw=="], + "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.20", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.20", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-slfm+rRaZRuQBvHq60lXvSVUPhid0IPtjSZzIuUlWZMUs01iYZNlGS3mJgRD3ChLQVBAYlKiL/tFyWGX+dz8Xw=="], "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.4", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q=="], - "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.9", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9Se8t+Zry+1rEOL7Y6l/4ANYU/TOtAtf8O2fKdwLltcaMcm6kOqYGbzO4tMFQ0bvzO920pRAoHpFZ4W85S3keQ=="], + "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.12", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-jjk/lqTeNL0azUx5ZYzVrl4NgaDIrdzTNE4mABV9yBFI7FQqN7pIgzV1bTleUezP2QiTGA1BFTqY8MegDgWX9A=="], - "@radix-ui/react-form": ["@radix-ui/react-form@0.1.9", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-label": "2.1.9", "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-eTPyThIKDacJ3mJDvYwf/PSmsEYlOyA2Qcb+aGyWwYv+P5w57VPUkMVA2XJ9z0Du2KBY1HoHQzhPV9iYL/r4hg=="], + "@radix-ui/react-form": ["@radix-ui/react-form@0.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-label": "2.1.11", "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JTX94E4LDL91rzLg7X0mHPdxr0A8JEdVwZEmeOwZJSMDHCGW5DFtSlTSJozUyUs807IQmnvbfzKZFVCK5DmkqQ=="], - "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-hAileDBtd6CX7nlZOarOnISQ6PP4q0e16BX51ulzdZ+7IzjL0sDTVpFdmSYrIjw6zVNsfQBao5gG6AWr3qwfvA=="], + "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-popper": "1.3.3", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-2KTgMLQtKvicznQgbindEI2RZ3QbDIwU5gabjUPwFJsormjGDz+rUvO4NANmYwzEEpTcTONUt33vBHIfTIVSfw=="], "@radix-ui/react-id": ["@radix-ui/react-id@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA=="], - "@radix-ui/react-label": ["@radix-ui/react-label@2.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-rDoTeMbCwRVcnmo7NGT9IlPo1yXmEI+xc1URP3oeewwZEV4mdTp1dYUhYbQdo4D1q2SjKVvv4N1gNY77QAQtjA=="], + "@radix-ui/react-label": ["@radix-ui/react-label@2.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-3PKvDDxOn62k0oV1n4QtNtD2vpu+zYjXR7ojLBPaO6SPvhy53yg0vAmgNeBQeJW5rV3dffoRG+HYfLBZuzw0CQ=="], - "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-callback-ref": "1.1.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-fmbNnFyf+JYCN0DhhWnEdUTDnZD1mXaPQWivdsPIb8oOSbARfD3LIQJbLCG8a8QLCwoMxiJ7GVPIFcC8Dw8v2Q=="], + "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.20", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.12", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.3", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-callback-ref": "1.1.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-VsUrXxFe9d2ScbZF0fR/oPR1+qjyeLs5p0jzG8h90puMoA9bq4SirYlXbE+USRg9Q2qTeJSFNqjw2nts8jJe4w=="], - "@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.17", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-AKtZ4O782yO7qwIyq73WpulYt1IHhQ0htDb6wNcxzxnSDCcSWMVBiU9ycpcA90XzQO4IVIxIErtak6Kg/Vt0rQ=="], + "@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.20", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-menu": "2.1.20", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-gzFZvybgmwYsFBWDqanycIoEYnhyk8MMnuLamdFVHUZYGp4COM+sqXiwbnn0VMWqGLeeU7GV7jm+dXRa+Wufag=="], - "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/fS8hKCcRt4DwCGa5QIB3juRXmfYSOk4a2AEe/BDIyy7Hm+eje2Y13oUx5zejl+wFt1owrM7E8NWlbaEl5EGpg=="], + "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.18", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-K9HiuxZ6xCwSaHcIuUpxyhy4w5gpwzWjh9dHTSbMN3Ix4qAyVObS9RlU3zMycb0PO3v9Tpk0BXMwWvXOUbVXew=="], - "@radix-ui/react-one-time-password-field": ["@radix-ui/react-one-time-password-field@0.1.9", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-fvCzA9hm7yN5xxTPJIi4VhSmH5gv+76ILsxguBK3cm3icD5BR4vW7POQmu8Zio0yh91uuouG/Kang40IbMkaSQ=="], + "@radix-ui/react-one-time-password-field": ["@radix-ui/react-one-time-password-field@0.1.12", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-nQLu5OAcORDQp1EHAv6k3mJGV1hjMTw2NTGVAsGE1g/mWeNqAd1R5jyaAs3U+A8ZD/W8XNPY2yKT0ZdQnqo3NA=="], - "@radix-ui/react-password-toggle-field": ["@radix-ui/react-password-toggle-field@0.1.4", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-qoDSkObZ9faJlsjlwyBH6ia7kq9vaJ2QwWTowT3nQpzPvUTAKesmWuGJYpd91HIoJqS+5ZPXy5uFPp+HlwdaAg=="], + "@radix-ui/react-password-toggle-field": ["@radix-ui/react-password-toggle-field@0.1.7", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-is-hydrated": "0.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-gB1Mr8vzdv1XzDjrtJTXmL0JORRs1B4g7ngUs0F+H2VvMOwXTZMTmLCl0wZZ3m7ylX8TssI7NCvgiSHmLuTm/A=="], - "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-8brVpAU5Uq7Bh0c8EFc4ZTf2JJTYn0o+1L+CUJB3UYIOkTjKGMgoHvduylrahdmNlr3DfH0rFq2DrbNZXgaspw=="], + "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.12", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.3", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-jkrTdQVxnIB8fpn0NyyxW9CTB5aCXZZelVz5z+Xmii6g5WxMqS3fInNslZ63puP39+Puu4jYohUK31y3dT87gQ=="], - "@radix-ui/react-popper": ["@radix-ui/react-popper@1.3.0", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-rect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9PB589e1aWZbrlFUHdz6WiPCL+xLZHQFX7oibqG/6Q0SwOkxDyQX9W/cyPa+sAPPKuC8cpLCpRczE5a/1DiwVQ=="], + "@radix-ui/react-popper": ["@radix-ui/react-popper@1.3.3", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.11", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-rect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/rect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-mS7dGpyjv6b+gsDjLF7e0ia1W4Im1B1hSCy2yuXlHuvnZxHKagfDaobt/KAKt27EpZMit2pss8eJBVyVjEWM+g=="], - "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-UEytdjgEh2tJGgD/gZK4FUx6t1rNIlM3U0DENhSrG7I75FGm1DnaDuVUWF1pWAWUwGmn1sCJ1VGHn8LhN1aTOw=="], + "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.13", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-z3oXfmaHLJTF1wktbjgD6cn9jiEbq3WSondB10LIuIt2m2Ym4iJlrW04/euMwENDdWDdE7z+OuY7Qyp1YpRSwA=="], - "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.6", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ=="], + "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.7", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zBZ4QM5XG3JRanDmqXYf3MD6th4AFXFmgU6KNMFzUaV6F3uw9I5/zjMUvFriSEn5ewo1nxuibvyxJdmLlDcslA=="], - "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.5", "", { "dependencies": { "@radix-ui/react-slot": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zifXeB8Y88qCYx8PLZ5oQb32KwZub+s925mMoZsBBq9KUQqWKkREubTfs6ASjRPPBe7Jt9O8OHH89+95VG+grA=="], + "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.7", "", { "dependencies": { "@radix-ui/react-slot": "1.3.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ=="], - "@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.9", "", { "dependencies": { "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-+EOkvg1Zn1vI1+fRDfRSAiJ7BWfcDAo5ASMmbqrcLZ4s4USk2FGkoHgeb2X+CkUgo2zJMiyObwf1k44CrRWsyw=="], + "@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.12", "", { "dependencies": { "@radix-ui/react-context": "1.2.0", "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-ZPHyI0JyzoH/rP0tq2uRaIZTj/4s8+kAbqPz+e2N8+ejHvwPJ889dHhqn+vh7PNvNeq+boAoH9yzqeoShzwF2w=="], - "@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.4.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-eHdV5bLx9sH+tBnbDjkIBdvQEH/c6MEtQYhTbxkaDK9qsIFFLtmJYEQFVdwhnruWotLfQmIuWEL/J+L3utE8rQ=="], + "@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.4.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-WwZFjWV4s3aC1QtR3k04R+oANHtX2q6fgKlc7MCEiDNlnTxCZ3H8k3mHtEgVlOejystwk1WQgarQhNOQZ2bK1g=="], - "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FvgPt1bRmg8Xt2QpF7NUZW3dE0ZQHGm41dAdgT2J2GJPoIXz+9Em3NobAxf4fupcxhgHu03E5CRiU2MWvObXyg=="], + "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-40svmmugfM3mUN7VUDGVE1tQGOhyi8enlGD0CNJEcMM36C1f71PKM21DFgNHUfem0XnA+d8H8oN3Z9ZpJjSslg=="], - "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.11", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-DS39ziOgea75U/TrXKU2/oKp0be2jrDHnzFLvahg/0iNAT1Zq16e4Uw0WXwyXvsK+mG3BRyMb7A3NRZMDuEXtQ=="], + "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.14", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bBODCWZK7JTbQLHs0uIP4f73wIWatakK4OS33UzkR1x897wu0PuO658a3f+6P2GEGyDzGYMuHRatMVoAk9WZTw=="], - "@radix-ui/react-select": ["@radix-ui/react-select@2.3.0", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.5", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-mENc7WpJvJcW8hlMpzfFcHcEhTvYS5JMBmi9HVC1Q00uhBwML086MHYUV8QQdQv6lcu0Wg8dzd1RB8AFADcG/g=="], + "@radix-ui/react-select": ["@radix-ui/react-select@2.3.3", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.12", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.3", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-L5RQTXz6Anxsf9CCv+pTgiAsUpyVj7rJxsGtmhFaEOJ++cVfXucv4qWfsIO0AIB4NAhi3yovWGVMKKS1Xf1Wrg=="], - "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-gvgW+JV/Mbjj6darztTetnmElpQEzZrXpJvfj+dOxNAxiyHEAyUvEjjl4zxblvmjmKmi3jfPoy7ZdxzCuUBJSA=="], + "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.11", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-jRhe86+8PF7VZ1u14eOWVOuh2BuAhALg/FT1VcMC4OHedMTRUazDnDlKTt+yxo5cRNKHMfmvZ4sSQtWDeMV4CQ=="], - "@radix-ui/react-slider": ["@radix-ui/react-slider@1.4.0", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-RHcPlLOThRJM51DSIC33ZnpDEBYhyEFroVWkd2P54PGGjkmAt14RboYUU9E1MFst666zFHM0tGtWvMjSOtU1pw=="], + "@radix-ui/react-slider": ["@radix-ui/react-slider@1.4.3", "", { "dependencies": { "@radix-ui/number": "1.1.2", "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-CWVVj+XaTom0SKCqw1EUgb0NuiLwS+N3OFG73mVEezKEjgNIvZiu0EevMelSSU+CbX3owbqJweG2gPU31WGC5A=="], - "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-rCMO3QsIVKv5JTY5CVbo2MvO77SpEqqYc8AvRE7OWqRDOIqAKjsp+DrmnY9uc8NPdxB5E2z47HTYGeE2+NTptg=="], + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.3.0", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA=="], - "@radix-ui/react-switch": ["@radix-ui/react-switch@1.3.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-GP1EZwhoZO/GGnhM1P5/2Vpm8iN8EnngyU0oezn2l78kN8tj25pyrvjIaT7azBhK615KSt+P2w39y57YV5jVkA=="], + "@radix-ui/react-switch": ["@radix-ui/react-switch@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-previous": "1.1.2", "@radix-ui/react-use-size": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1+mlB4/lxJfk5tgJ4g+R5mUCbRpPE1T9+UsEyeLYbGgMtwiMgmuTnfKz4Mw1nHALHjuwyxw4MLd4cSHn6pNSlQ=="], - "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-D5jwp9JNuwDeCw3CYD2Fz+sSHo0droQjC8u75dJHe4aWr5q6yBiXZU+hurXnKudRgEpUkD5TsI6bjHPo5ThUxA=="], + "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.17", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-nRyXnrAVCwjeXcHbvEbLS6ndbTeKHG1RqCP4A8Gw5L4cemDzPXdD8rAmr6wet0v57R69wGvuIIsFjHSVkZiMzQ=="], - "@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.16", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-WUymDDiN2DpoGudRN1aW4wF5O3BNQjZZO/5nngPoNiEVqjyOzirvZZNO0R6dC1ifucSINVaSv8JX1aq47VGgiA=="], + "@radix-ui/react-toast": ["@radix-ui/react-toast@1.2.19", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-SxfVZfVOibWKWdkf0Xx1awW2d09fQu4V4PXDY1j5hi4MVf7MWdJZqTBJMa1KWtOr1S6GGtCk02nniZ0Iia+dHw=="], - "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FikrKJemoBGZQ6uRID0HJqSPBP6D7OppdD2OhLl0ZYLlAyPXI7MezoYGmumwNkrAoRm35xXkb4C8JPfJZZzcaw=="], + "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-QI/hB65XKWACA66P64A+aHxtLUgHJeJLkaQa+awUNXT6T3swndtY5DojeHA+vldrTspMTtFBd7HfZ9QGbM1Qrw=="], - "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-toggle": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TEgECgJaWGAHJJZGzNNEYTNBdIXqX7LchANycpyP7DkfjmuiSN7ISt1k/ZRGVJgVJonsgP4vwaiKMn5utrcwWQ=="], + "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-toggle": "1.1.14", "@radix-ui/react-use-controllable-state": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-gIC5Q+Xljg7lmUdzSuDoy0t97yZn1sZl00Ra37ZvKrYdWnQLU6sWLd09yG8cIB9jUAlQfHgJ2ACAG00MFwsqSQ=="], - "@radix-ui/react-toolbar": ["@radix-ui/react-toolbar@1.1.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-separator": "1.1.9", "@radix-ui/react-toggle-group": "1.1.12" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-4wHtJVdIgqMmEwUvxA0BYg/2JMRbt0L3+8UD8Ml/nhKkfXtiZcM8u/S15gQ5xj9YEd/0qlrm5bE805LsjQ+J8A=="], + "@radix-ui/react-toolbar": ["@radix-ui/react-toolbar@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-separator": "1.1.11", "@radix-ui/react-toggle-group": "1.1.15" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t/iEuVjUnXXtrsGK40AA43uIx37sn3AqZ7oAVnPICK6lFJP6dzMzWR3U9b6eCfFjb6wtSEqkJ9Rn9xDjiOx20g=="], - "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.9", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-u6F9MmTtBSLkiXNVDrtB/yPCZarM9smNswC24YYLV/M+bth6J3Gs3vlJezEoFwKZvPvxhCpUYdUnOsNG/0XOlA=="], + "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.2.12", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-id": "1.1.2", "@radix-ui/react-popper": "1.3.3", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-U3HoftgWnmla78vzQbLvKKb7bUYJxoiiqYFzp1wu/TBMyDqMZSuCl3aRICsD6EfVEwcJD2mumGDGUXLFVqQHKA=="], "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw=="], @@ -850,7 +851,7 @@ "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.3", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA=="], - "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.2", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-2uVLvLjgO7NZCWw01/FdqRwmA42J0BcjPMUCA+koFEOAb+zjqIP7SiFz/7zWPrKnVmSqr76Omq2ALyCuX4dhLw=="], + "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.3", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-3wEkMiPHXha/2VadZ68rYBcmYnPINVGl4Y3gtcM7fKRjANk0OscK+cdqBgUWdozb7YJxsh0vefM7vgAMHXOjqg=="], "@radix-ui/react-use-is-hydrated": ["@radix-ui/react-use-is-hydrated@0.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A=="], @@ -862,117 +863,117 @@ "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-giWQp+4mxjBPt4KZ0MmyuykFNWfbDxKt4x+fPkRYmgRFJSbCZFzUglvMb/Kjn38tm10YP4ufiQZDx3zna4LU6w=="], - "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.5", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tPcHNI3FajdDBFpl/Ez1m2WL0ufJqBKyHxMDBvKitopamK36WwBGOMicuMEZKkM5Wce41QxUyv6BsiqfrWBiGg=="], + "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1wNZBggTDK3GRuuQ6nP4k2yi7a6l7I5qbMPbZcRsrGsGVead/f/d5FhEzUvqFs0bcrDLx7n1zKQ3JvLR6whaaw=="], "@radix-ui/rect": ["@radix-ui/rect@1.1.2", "", {}, "sha512-xnXE7wG13PI+cxieVssYXlQJuYVRhH9NBoxt3KNwzghDIA69GMm7d4wXRouHIYjE+KvS6U/MsMO73NdS2MH9ZA=="], "@radix-ui/themes": ["@radix-ui/themes@3.3.0", "", { "dependencies": { "@radix-ui/colors": "^3.0.0", "classnames": "^2.3.2", "radix-ui": "^1.1.3", "react-remove-scroll-bar": "^2.3.8" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-I0/h2CRNTpYNB7Mi3xFIvSsQq5a108d7kK8dTO5zp5b9HR5QJXKag6B8tjpz2ITkVYkFdkGk45doNkSr7OxwNw=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.3", "", { "os": "android", "cpu": "arm64" }, "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.5", "", { "os": "android", "cpu": "arm64" }, "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ=="], - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA=="], + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw=="], - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg=="], + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g=="], - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g=="], + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA=="], - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.3", "", { "os": "linux", "cpu": "arm" }, "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw=="], + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.5", "", { "os": "linux", "cpu": "arm" }, "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw=="], - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw=="], + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q=="], - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q=="], + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA=="], - "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg=="], + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg=="], - "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg=="], + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA=="], - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.3", "", { "os": "linux", "cpu": "x64" }, "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg=="], + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ=="], - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.3", "", { "os": "linux", "cpu": "x64" }, "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow=="], + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg=="], - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.3", "", { "os": "none", "cpu": "arm64" }, "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg=="], + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.5", "", { "os": "none", "cpu": "arm64" }, "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw=="], - "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.3", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg=="], + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.5", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA=="], - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g=="], + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw=="], - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA=="], + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA=="], "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.61.1", "", { "os": "android", "cpu": "arm" }, "sha512-JnBB8MdXj45cajvTuO5FmPlvFVJRQgvrz1uSEl3NwqFnReAPGwb8EanbGi4z2nRaqLzjJSv5/JmycoTKlRZxHA=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.62.2", "", { "os": "android", "cpu": "arm" }, "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.61.1", "", { "os": "android", "cpu": "arm64" }, "sha512-Jx2g7iSjw4AOT0HDPHM9RV3GNjRXwybWtSFZiZAYUTjUwjVrYIwq3kBf+LnhqJlzXFAqTAh2F7IGI+O568exPw=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.62.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.61.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0F1L/Z3Eqv8mT2n3dCpeO8GcTvHvVqkP5/t6DMsn0KzhYVcg+s7Ncl5DS8qjKYEeio6Az0Gt6nyBORay5qIlCA=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.62.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.61.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-qLttcH871ujY4YcVfUSShhOw+CsoTatYz8gRbHO7Bb92QH059/P0y5do1KMs41fY0BpD2x4AJH/gID0zFiqVKQ=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.62.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.61.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-fUI4RapGE0Oh3mb8mgfvC1O2nU1RpDZUKnDQm3xB1Ipg7C2wTs5Kstz7G2uWK99a8S2yTMq8/P4uycwNa0nJyw=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.62.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.61.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-H5YrdvJaDtI/U9/emrD4b++xkvp3y/JvOe4rizHbxvkyMfRS/CiRYdji+Pl8D0brEaNFWUh1drQxgAGIl6Xudw=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.62.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.61.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Q8CBCCQtDFrYtXoeUXSrnFXKOnyUhx6bz+SkL6A0E7V8kAiCJ5pamq1WtbfpVGhR5TSpXY6ak3avmDc5fHTyJA=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.62.2", "", { "os": "linux", "cpu": "arm" }, "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.61.1", "", { "os": "linux", "cpu": "arm" }, "sha512-nwnhk1581l0FBVellGcVCAT0Oi06onEA3WB53sf01VO3I0UPBkMH9sXONYME2K0ovXcNayJfNtHfm6mpJElatQ=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.62.2", "", { "os": "linux", "cpu": "arm" }, "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.61.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-x5Xr49hwt3hdW75UOZm3395YwwzPyauktslv29KpWL/T+vVAzoT3azLcTWv0eMciBNrx+DYjH4paehHoLpPvpg=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.62.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.61.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-unMS3H73DpaoPyyEVPjGKleM/s0mkmsauTENpw4INQY8y4+IuLNjkueQ5QCtC0D3N38Y38yhAU8OoZ20S2Tm6w=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.62.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ=="], - "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.61.1", "", { "os": "linux", "cpu": "none" }, "sha512-zNZzGRnAhwjFEYmvphJRV5XaQGjs62cCmeYYHUT//NbvEnHauw+I85nGG+SiVg5ld4GX8D1IbKIX+ozITQnhMQ=="], + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.62.2", "", { "os": "linux", "cpu": "none" }, "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg=="], - "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.61.1", "", { "os": "linux", "cpu": "none" }, "sha512-LdpWGL8X209B2SIvWjqlc8VZgM6PKfontSerGepuldQmHYrAOtnMCXeJkxXGbC+PPZVOuu5czJo7fNV6aeW8rQ=="], + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.62.2", "", { "os": "linux", "cpu": "none" }, "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ=="], - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.61.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-EC5kTtNaNGOmbMGqar8dvJy6y/hg99GAwjfBz++pxZhQATXGcRjd6c5en5wcbru0vkRmiMGsQKdMJOOf6sza4g=="], + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.62.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A=="], - "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.61.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-8hiwp6D4acEcNK78I4rP0/XtS1sknWIAMJBPdR4l6zUtyTm5KiTDr5bXmWt4foY7nAN7AThDHgkLIEZOWKbzWw=="], + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.62.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.61.1", "", { "os": "linux", "cpu": "none" }, "sha512-10dh/h/BqA7DuMPWSxkR8uks18FRwnwOEqr5zOTEl+NOwP/OMzKX8OFR/Of9xxDA7D5qef1Nzar5WDD2kCCr1g=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.62.2", "", { "os": "linux", "cpu": "none" }, "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg=="], - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.61.1", "", { "os": "linux", "cpu": "none" }, "sha512-YKJ5lg35DP17gcAOggnihe+APw9HLyj1Xn7gsmGumBJAUDa6NGXNixJzmkWLhcK9TOuuyQjdamzvJefkO7qHZQ=="], + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.62.2", "", { "os": "linux", "cpu": "none" }, "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.61.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-Mlil5G2Jj6a7B3LWGctg+XPL9vdXYuzCtNXfxOQ0nPjc2m6ueUktocPGH9bnAM0bNRKb/bAWTujUU7IJQdQA+g=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.62.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.61.1", "", { "os": "linux", "cpu": "x64" }, "sha512-bVWIOIk6pV01p4CdUbPP7CJ/434z+OooYjDuFcR+44N35YvKUC66G8MGnvcWx5mWKW3g61J+t74l3Kj15Kwn2Q=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.62.2", "", { "os": "linux", "cpu": "x64" }, "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.61.1", "", { "os": "linux", "cpu": "x64" }, "sha512-qy5pBvZbqNFheBz61R1rzsezjm0J7O2oNGoWtGoY89SZYLUfxAJTBAqDChqAIdB4rCiIbi9nF7yZ83GnNiLwSw=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.62.2", "", { "os": "linux", "cpu": "x64" }, "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg=="], - "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.61.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-E83TXjI4zm0+5f2qO+UOudaCYIhYwpJ5jq6YCZNIZ+6CbfhKrkAGezeiASBL9ElxAxFsRS9ZhESv8mfnj6TKeg=="], + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.62.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg=="], - "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.61.1", "", { "os": "none", "cpu": "arm64" }, "sha512-fbWnKqVkjrJN38vNe3ahkbk6iejS/3b0Nt7EEtPpE6RBacZcGXNKbzfHN3GUUlXOPghUg0j6XUGrtjX9z1sIvA=="], + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.62.2", "", { "os": "none", "cpu": "arm64" }, "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.61.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-ArMl38iVAbk0New1ogihQNY6iphLi4ZaRsa037gUzv5yeKPY8TD3Dmy4x2RNC1VztU/uqm+G+/RwFrSka3Oy2g=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.62.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.61.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-0mYtjHS9ucAbcATycCNK9IGBk/cCe/ma7EmSLGZdsxnOA8cjRIyU04wDpVAD9NiOfLUR9KTxdiO53uOkherqjQ=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.62.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q=="], - "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.61.1", "", { "os": "win32", "cpu": "x64" }, "sha512-gK1iCEPfpoSG9wfBihXxvBMi8ZfcWffYkEsC/Eih+iFENTaewvNcrEQ69lIOWYO5pePHKLHHO7nq5AILGO/HQQ=="], + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.62.2", "", { "os": "win32", "cpu": "x64" }, "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.61.1", "", { "os": "win32", "cpu": "x64" }, "sha512-X+zaP2x+j4RXGfbp/seSoRHWnPxzApilDszisZxbYH5C/jTxFhCtDNdPGZb9lJyYPs24wGxruPF7Y+sIXt9Gzw=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.62.2", "", { "os": "win32", "cpu": "x64" }, "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA=="], - "@rspack/binding": ["@rspack/binding@1.7.11", "", { "optionalDependencies": { "@rspack/binding-darwin-arm64": "1.7.11", "@rspack/binding-darwin-x64": "1.7.11", "@rspack/binding-linux-arm64-gnu": "1.7.11", "@rspack/binding-linux-arm64-musl": "1.7.11", "@rspack/binding-linux-x64-gnu": "1.7.11", "@rspack/binding-linux-x64-musl": "1.7.11", "@rspack/binding-wasm32-wasi": "1.7.11", "@rspack/binding-win32-arm64-msvc": "1.7.11", "@rspack/binding-win32-ia32-msvc": "1.7.11", "@rspack/binding-win32-x64-msvc": "1.7.11" } }, "sha512-2MGdy2s2HimsDT444Bp5XnALzNRxuBNc7y0JzyuqKbHBywd4x2NeXyhWXXoxufaCFu5PBc9Qq9jyfjW2Aeh06Q=="], + "@rspack/binding": ["@rspack/binding@1.7.12", "", { "optionalDependencies": { "@rspack/binding-darwin-arm64": "1.7.12", "@rspack/binding-darwin-x64": "1.7.12", "@rspack/binding-linux-arm64-gnu": "1.7.12", "@rspack/binding-linux-arm64-musl": "1.7.12", "@rspack/binding-linux-x64-gnu": "1.7.12", "@rspack/binding-linux-x64-musl": "1.7.12", "@rspack/binding-wasm32-wasi": "1.7.12", "@rspack/binding-win32-arm64-msvc": "1.7.12", "@rspack/binding-win32-ia32-msvc": "1.7.12", "@rspack/binding-win32-x64-msvc": "1.7.12" } }, "sha512-f4HHuLbvuld8Ba4iB/4ibse5XrKxFrgmM3S4P2AOKnPlekAFlBjmltCuaTL/W2ggYvILaVY+YcFXrEH1rrKeQA=="], - "@rspack/binding-darwin-arm64": ["@rspack/binding-darwin-arm64@1.7.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oduECiZVqbO5zlVw+q7Vy65sJFth99fWPTyucwvLJJtJkPL5n17Uiql2cYP6Ijn0pkqtf1SXgK8WjiKLG5bIig=="], + "@rspack/binding-darwin-arm64": ["@rspack/binding-darwin-arm64@1.7.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rbFprJaJiqrmfy8SHth8EsoRS0wg4bXcucwj9NiMzpGFq14Opw8c04iQ6H9BECYzgmN0PKZ9rh41LdVvhdZe4A=="], - "@rspack/binding-darwin-x64": ["@rspack/binding-darwin-x64@1.7.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-a1+TtTE9ap6RalgFi7FGIgkJP6O4Vy6ctv+9WGJy53E4kuqHR0RygzaiVxCI/GMc/vBT9vY23hyrpWb3d1vtXA=="], + "@rspack/binding-darwin-x64": ["@rspack/binding-darwin-x64@1.7.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-jnOp+/UXOJa9xqUb8KXH03sysoO2e4Ij6tw6MqDdmdj8n/A8PQENRPUbW9AwXpPtVDJPus9r4fi7b3+6e4B8Hg=="], - "@rspack/binding-linux-arm64-gnu": ["@rspack/binding-linux-arm64-gnu@1.7.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-P0QrGRPbTWu6RKWfN0bDtbnEps3rXH0MWIMreZABoUrVmNQKtXR6e73J3ub6a+di5s2+K0M2LJ9Bh2/H4UsDUA=="], + "@rspack/binding-linux-arm64-gnu": ["@rspack/binding-linux-arm64-gnu@1.7.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-C8owWG+yvo7X0oVLIXetkoJhIFBP1LYNcAQqtgLmJnQLQDklGuP83dKC+zISGQWpjawHfZ1ER96vLgoTrxKZdw=="], - "@rspack/binding-linux-arm64-musl": ["@rspack/binding-linux-arm64-musl@1.7.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-6ky7R43VMjWwmx3Yx7Jl7faLBBMAgMDt+/bN35RgwjiPgsIByz65EwytUVuW9rikB43BGHvA/eqlnjLrUzNBqw=="], + "@rspack/binding-linux-arm64-musl": ["@rspack/binding-linux-arm64-musl@1.7.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-i51WWI64aRpsfSki6rN0aepPqXkVfS+vZM7+4bWDcmnhUmdMvhIPcYg0QRk3DtyJnu33jqNLM0WHY78k00NyfA=="], - "@rspack/binding-linux-x64-gnu": ["@rspack/binding-linux-x64-gnu@1.7.11", "", { "os": "linux", "cpu": "x64" }, "sha512-cuOJMfCOvb2Wgsry5enXJ3iT1FGUjdPqtGUBVupQlEG4ntSYsQ2PtF4wIDVasR3wdxC5nQbipOrDiN/u6fYsdQ=="], + "@rspack/binding-linux-x64-gnu": ["@rspack/binding-linux-x64-gnu@1.7.12", "", { "os": "linux", "cpu": "x64" }, "sha512-MSos0FuPEefqo9V92ULd5hggKG29EkSNg1zDcypy0OkpsKh5pfjVxTLYFXgTcVyFoUQQbdG8zFBzYbwmJ8V4ew=="], - "@rspack/binding-linux-x64-musl": ["@rspack/binding-linux-x64-musl@1.7.11", "", { "os": "linux", "cpu": "x64" }, "sha512-CoK37hva4AmHGh3VCsQXmGr40L36m1/AdnN5LEjUX6kx5rEH7/1nEBN6Ii72pejqDVvk9anEROmPDiPw10tpFg=="], + "@rspack/binding-linux-x64-musl": ["@rspack/binding-linux-x64-musl@1.7.12", "", { "os": "linux", "cpu": "x64" }, "sha512-JcAMVKXOnjfpC3coWjCFPWD3Yl8RBw6a+IXQQ8mfRlHaHMIiOv8IfZqx15XRxMUn49CtP7Z0Na8iiAg2aKrcfw=="], - "@rspack/binding-wasm32-wasi": ["@rspack/binding-wasm32-wasi@1.7.11", "", { "dependencies": { "@napi-rs/wasm-runtime": "1.0.7" }, "cpu": "none" }, "sha512-OtrmnPUVJMxjNa3eDMfHyPdtlLRmmp/aIm0fQHlAOATbZvlGm12q7rhPW5BXTu1yh+1rQ1/uqvz+SzKEZXuJaQ=="], + "@rspack/binding-wasm32-wasi": ["@rspack/binding-wasm32-wasi@1.7.12", "", { "dependencies": { "@napi-rs/wasm-runtime": "1.0.7" }, "cpu": "none" }, "sha512-n+ZqP6ZMc0nhOgvadg5VhEs9ojtbES80AcWeFnmGkbzIszvGSO63GKNiRkXtjJ9KFuRzytbbmsCqkUVH+Tywxg=="], - "@rspack/binding-win32-arm64-msvc": ["@rspack/binding-win32-arm64-msvc@1.7.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-lObFW6e5lCWNgTBNwT//yiEDbsxm9QG4BYUojqeXxothuzJ/L6ibXz6+gLMvbOvLGV3nKgkXmx8GvT9WDKR0mA=="], + "@rspack/binding-win32-arm64-msvc": ["@rspack/binding-win32-arm64-msvc@1.7.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-8+h5fYDXYdmugbdfZ+D1y8IQ3rv2EhSfyGP7vBe+bjNyaMa4jWrpucmZbtxojUL1AzaeuHbvMdj9UO/gelk/+g=="], - "@rspack/binding-win32-ia32-msvc": ["@rspack/binding-win32-ia32-msvc@1.7.11", "", { "os": "win32", "cpu": "ia32" }, "sha512-0pYGnZd8PPqNR68zQ8skamqNAXEA1sUfXuAdYcknIIRq2wsbiwFzIc0Pov1cIfHYab37G7sSIPBiOUdOWF5Ivw=="], + "@rspack/binding-win32-ia32-msvc": ["@rspack/binding-win32-ia32-msvc@1.7.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-cDMGwTRSa2p9fNBVe1wTRkF2AEXZ9ARWW36QeC5CkLaI0Ezz8lvhF2+CSOPnhaQ1O1qtn0L0SF+lFnrY+I7xGQ=="], - "@rspack/binding-win32-x64-msvc": ["@rspack/binding-win32-x64-msvc@1.7.11", "", { "os": "win32", "cpu": "x64" }, "sha512-EeQXayoQk/uBkI3pdoXfQBXNIUrADq56L3s/DFyM2pJeUDrWmhfIw2UFIGkYPTMSCo8F2JcdcGM32FGJrSnU0Q=="], + "@rspack/binding-win32-x64-msvc": ["@rspack/binding-win32-x64-msvc@1.7.12", "", { "os": "win32", "cpu": "x64" }, "sha512-wIqFvlgFqrgUyj/6S/FJcvShnkZOmIeXTfqvheLY67MGq8qd8jb1YimQVKAIrmWB3yuJKUFACI3Ag1UBtEedEA=="], - "@rspack/core": ["@rspack/core@1.7.11", "", { "dependencies": { "@module-federation/runtime-tools": "0.22.0", "@rspack/binding": "1.7.11", "@rspack/lite-tapable": "1.1.0" }, "peerDependencies": { "@swc/helpers": ">=0.5.1" }, "optionalPeers": ["@swc/helpers"] }, "sha512-rsD9b+Khmot5DwCMiB3cqTQo53ioPG3M/A7BySu8+0+RS7GCxKm+Z+mtsjtG/vsu4Tn2tcqCdZtA3pgLoJB+ew=="], + "@rspack/core": ["@rspack/core@1.7.12", "", { "dependencies": { "@module-federation/runtime-tools": "0.22.0", "@rspack/binding": "1.7.12", "@rspack/lite-tapable": "1.1.0" }, "peerDependencies": { "@swc/helpers": ">=0.5.1" }, "optionalPeers": ["@swc/helpers"] }, "sha512-6CwFIHlhRmXfZoMj3v9MZ1SMTPBn+cHVXeMIeaGp5sufqinKsISbsqHu6ZMJu2wDSmZLdmQJX6zLxkhcAUlhkQ=="], "@rspack/lite-tapable": ["@rspack/lite-tapable@1.1.0", "", {}, "sha512-E2B0JhYFmVAwdDiG14+DW0Di4Ze4Jg10Pc4/lILUrd5DRCaklduz2OvJ5HYQ6G+hd+WTzqQb3QnDNfK4yvAFYw=="], @@ -982,7 +983,7 @@ "@sideway/pinpoint": ["@sideway/pinpoint@2.0.0", "", {}, "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="], - "@sinclair/typebox": ["@sinclair/typebox@0.27.10", "", {}, "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA=="], + "@sinclair/typebox": ["@sinclair/typebox@0.27.12", "", {}, "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g=="], "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], @@ -1018,79 +1019,79 @@ "@svgr/webpack": ["@svgr/webpack@8.1.0", "", { "dependencies": { "@babel/core": "^7.21.3", "@babel/plugin-transform-react-constant-elements": "^7.21.3", "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@svgr/core": "8.1.0", "@svgr/plugin-jsx": "8.1.0", "@svgr/plugin-svgo": "8.1.0" } }, "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA=="], - "@swc/core": ["@swc/core@1.15.40", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.26" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.40", "@swc/core-darwin-x64": "1.15.40", "@swc/core-linux-arm-gnueabihf": "1.15.40", "@swc/core-linux-arm64-gnu": "1.15.40", "@swc/core-linux-arm64-musl": "1.15.40", "@swc/core-linux-ppc64-gnu": "1.15.40", "@swc/core-linux-s390x-gnu": "1.15.40", "@swc/core-linux-x64-gnu": "1.15.40", "@swc/core-linux-x64-musl": "1.15.40", "@swc/core-win32-arm64-msvc": "1.15.40", "@swc/core-win32-ia32-msvc": "1.15.40", "@swc/core-win32-x64-msvc": "1.15.40" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-2kwzJikRvgtNAG7MwVZY2vEzZjTxKIq5jXOihuSV/8U+Hej8Va22t65aKnJZs3P+NwojZvR8Mf8kyM7O+V8sQg=="], + "@swc/core": ["@swc/core@1.15.43", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.27" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.43", "@swc/core-darwin-x64": "1.15.43", "@swc/core-linux-arm-gnueabihf": "1.15.43", "@swc/core-linux-arm64-gnu": "1.15.43", "@swc/core-linux-arm64-musl": "1.15.43", "@swc/core-linux-ppc64-gnu": "1.15.43", "@swc/core-linux-s390x-gnu": "1.15.43", "@swc/core-linux-x64-gnu": "1.15.43", "@swc/core-linux-x64-musl": "1.15.43", "@swc/core-win32-arm64-msvc": "1.15.43", "@swc/core-win32-ia32-msvc": "1.15.43", "@swc/core-win32-x64-msvc": "1.15.43" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-1CuKjFkPxIgGdeHVuNbkxmBxkcbdc08u0aiI43pFq6yY1tTVKmXT9hFEooyyKs/sJ3xf1GPHyEwTtk9Xl8dvQw=="], - "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.40", "", { "os": "darwin", "cpu": "arm64" }, "sha512-PaYyclfmQ++77D8ityYvmmVzHv9aG8ROwt2GfG6/ccloy4Hgf80qtOnzb9VYvPsUT7Ty1uhuDRhv3XYpf62qhQ=="], + "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.43", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v1aVuvXdo/BHxJzco9V2xpHrvwWmhfS8t6gziY5wJxd+Z2h8AeJRnAwPD8itCDaGXVBwJ/CaKfxEzTkG0Va0OA=="], - "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.15.40", "", { "os": "darwin", "cpu": "x64" }, "sha512-HbbPzvfLBUXjIB1Ezks+//lNUjmLjfyd63XSwprJgrZaXYdm70kohXPJUWdqKZozolFxbPaO+xtBaiUp6BoueA=="], + "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.15.43", "", { "os": "darwin", "cpu": "x64" }, "sha512-lp3d4Lamc8dt5huYdGLSR+9hLxmfr1jb0l+4XXG2zPqZwYWRN9R0U2qYoTrggiU2RWW0oV9VbWM3kBnqIc2kdQ=="], - "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.15.40", "", { "os": "linux", "cpu": "arm" }, "sha512-SlRZsCjOCPR2LvFs0Ri/Xrx/5o5TCt8vl4gW6mX1hEZOG0a625RxzRHpHdAQNGykmAN/7IeaFAJG+QnNmxlHcA=="], + "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.15.43", "", { "os": "linux", "cpu": "arm" }, "sha512-JWTQQELtsG5GgphDrr/XqqmM2pDN3cZqbMS0Mrg+iTiXL3F74sn/S2IyYE/5u4h2KLkTf9qQ7dXyxsbx7YzkeA=="], - "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-Q8byxJt2fh8CR3EUX6snBpy47AoBVm+In/+Z3rjDHMjC38ZvR9/gtUUNCT0tfrn4EdVsO8/QPi59nxrxvqxvBQ=="], + "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.15.43", "", { "os": "linux", "cpu": "arm64" }, "sha512-B4otJRdPWIsmiSBf0uG7Z/+vMWmkufjz5MmYxubwKuZazDW14Zd3symga1N62QR4RT+kEFeHEgsXfZGyn/w0hw=="], - "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-4z0MgHU+7M0pZDqBN1El7mFXDI1SBwinfcUkAyA4v8QrhOIUOZltySt2aStQLZGrdXVXM4Y4ylfiTC04ED+MoQ=="], + "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.15.43", "", { "os": "linux", "cpu": "arm64" }, "sha512-6zB6OnpViBxYy4tgY3v2i6AZY9fwkcHZ032UOwtwUuW1d19sdT07qF0kZe6/3UR1tUaK6jjg2rmVcUIBCEYVjQ=="], - "@swc/core-linux-ppc64-gnu": ["@swc/core-linux-ppc64-gnu@1.15.40", "", { "os": "linux", "cpu": "ppc64" }, "sha512-fLI4iUgeSZu0eRWUXwe6YzPFx9gHbFiPkl8Rp3mJfP8OpNR3nTQCGPvHdDh9xniW7mVvgMY4ni7A4VzqI1KrpA=="], + "@swc/core-linux-ppc64-gnu": ["@swc/core-linux-ppc64-gnu@1.15.43", "", { "os": "linux", "cpu": "ppc64" }, "sha512-coxE1ZWdB3uSDVNoEtYNrRi/1epvckZx9cTJ8ICUxTMTxGk+yvQ/Twacp3ruZSaMPGCriUjP86C37VhaT6nyRg=="], - "@swc/core-linux-s390x-gnu": ["@swc/core-linux-s390x-gnu@1.15.40", "", { "os": "linux", "cpu": "s390x" }, "sha512-YqeKMAb7d4nQSGMJQ454IlaCENpzcDqhvBE9+CPfdnYpnUXxd+BSrB6Xk0YjW8UyoEhUj4p6quATCxbsp6J3jg=="], + "@swc/core-linux-s390x-gnu": ["@swc/core-linux-s390x-gnu@1.15.43", "", { "os": "linux", "cpu": "s390x" }, "sha512-lXfLhs+LpBsD5inuYx+YDH5WsPPBQ95KPUiy8P5wq9ob9xKDZFqwNfU2QW6bGO8NqRO/H9JQomTSt5Yyh+FGfA=="], - "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-7HOuS1iGcme/j/TuL1TfmmLGiMQrjv/GmjyZeydl00FKPtpGXEldwqfI56xgd1YzrzoB2svWjxbGGyQ0TEASxg=="], + "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.15.43", "", { "os": "linux", "cpu": "x64" }, "sha512-07XnKwTmKy8TGOZG3D9fRnLWGynxPjwQnZLVmBFbo6F+7vHYzBIOuwXEhemrChBWb6yDNZsVCcMWCPX6FDD2xg=="], - "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-h4kZYHc7dpc9P9u4brRJaS8Pl7tPVHAeiLSzw7T5RfIJgAoSdaCMKzI/2Uay9gFhaw8uyCDl0L5q37r0EpAfIA=="], + "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.15.43", "", { "os": "linux", "cpu": "x64" }, "sha512-TJc+bsSIaBh+hZvZ5GRtW/K1bw66TJ9vsUwvVIsZdiWxU5ObLwZvfcnZ3UpgVfMnFibRes9uriJrQNBHEEogRQ=="], - "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.15.40", "", { "os": "win32", "cpu": "arm64" }, "sha512-+mQgKZXSj6mV38Zh05QaxSjUDmGP/R2JWlXZTDLSPkDzHU6p3GxN9eeSf5dfyDVU86946fmCvSzyl/ucImx8+A=="], + "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.15.43", "", { "os": "win32", "cpu": "arm64" }, "sha512-jfd7s2/bUQYkOHLs+LWQNKZdmDa8+sufKLllhpWAhVQ2GDCwsHe3vR/j+OSiItZNtkzFuaawa3+SAKz9y5gYfw=="], - "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.15.40", "", { "os": "win32", "cpu": "ia32" }, "sha512-yvwdPLGd25mcj/mNatjNQ0lZujtQD6psH3v9PNmMb+fSzjbNG8KIDxjFWrcV+fsFVLOkyOmdJsFmX7NAFjVyPw=="], + "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.15.43", "", { "os": "win32", "cpu": "ia32" }, "sha512-rLAE8JvucqEW1ZGohxPQrQWPBQeJG4+ypKbWfdlU/qmKScvCkxf9/Jxnzki1dkUQCQ7P5Enp13RlvqOlvx/32g=="], - "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.15.40", "", { "os": "win32", "cpu": "x64" }, "sha512-OXtKsLU1bVtInzzDEAY2sYiF/rl4tvAnLLLpuMp3HzAOQZ5A+i69AKDhA1YLQTaMAqO3vzyYNVAYVRMPtSYD4w=="], + "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.15.43", "", { "os": "win32", "cpu": "x64" }, "sha512-h8MLDHZcfIukwQWj03rIJZx1I0E81AYj2X7J/nGErG4nz+QAv6G1Z+peotvinL3lqpbo32tLYSMFo32/ySzxKg=="], "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], - "@swc/html": ["@swc/html@1.15.40", "", { "dependencies": { "@swc/counter": "^0.1.3" }, "optionalDependencies": { "@swc/html-darwin-arm64": "1.15.40", "@swc/html-darwin-x64": "1.15.40", "@swc/html-linux-arm-gnueabihf": "1.15.40", "@swc/html-linux-arm64-gnu": "1.15.40", "@swc/html-linux-arm64-musl": "1.15.40", "@swc/html-linux-ppc64-gnu": "1.15.40", "@swc/html-linux-s390x-gnu": "1.15.40", "@swc/html-linux-x64-gnu": "1.15.40", "@swc/html-linux-x64-musl": "1.15.40", "@swc/html-win32-arm64-msvc": "1.15.40", "@swc/html-win32-ia32-msvc": "1.15.40", "@swc/html-win32-x64-msvc": "1.15.40" } }, "sha512-YVWNrh3wZWH2oXz7uL+s1WZbFIsnAp9cCl/b+C7ufDJqhsOvbr0un9IOYZ/CxRIRdnHGfhVD199n8baD/kRQew=="], + "@swc/html": ["@swc/html@1.15.43", "", { "dependencies": { "@swc/counter": "^0.1.3" }, "optionalDependencies": { "@swc/html-darwin-arm64": "1.15.43", "@swc/html-darwin-x64": "1.15.43", "@swc/html-linux-arm-gnueabihf": "1.15.43", "@swc/html-linux-arm64-gnu": "1.15.43", "@swc/html-linux-arm64-musl": "1.15.43", "@swc/html-linux-ppc64-gnu": "1.15.43", "@swc/html-linux-s390x-gnu": "1.15.43", "@swc/html-linux-x64-gnu": "1.15.43", "@swc/html-linux-x64-musl": "1.15.43", "@swc/html-win32-arm64-msvc": "1.15.43", "@swc/html-win32-ia32-msvc": "1.15.43", "@swc/html-win32-x64-msvc": "1.15.43" } }, "sha512-SKbkbdGi9SDO9cTdV+6H0/AYifnb2nDOlz5BlWxlWMXACV3kmX6WwZDo0bBdyGlO/G4jCVWdR5r84qfotU2now=="], - "@swc/html-darwin-arm64": ["@swc/html-darwin-arm64@1.15.40", "", { "os": "darwin", "cpu": "arm64" }, "sha512-A9oxSh60pMEsX/4VBpn3e6s8DfGWsHzAeG+Vd9mXgkTqt/ouX12owP6RyqfqK8v0WuEsBKkGY0+MbwLvlOG8NQ=="], + "@swc/html-darwin-arm64": ["@swc/html-darwin-arm64@1.15.43", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+PFbHbeeN+zB0zfvR1V1NmvPriuWPI+sijQXpI+wq/nLIujxvtENWjOKVHgouC9TIN/uKmL2zu9HAq6L6YxnPA=="], - "@swc/html-darwin-x64": ["@swc/html-darwin-x64@1.15.40", "", { "os": "darwin", "cpu": "x64" }, "sha512-GZ5KxJ/1pqnpOAjaa9hnkSk3M1LHjc5ci5GCt5/llAgDKFLDHzydIflHXTOIaS4nRCtfVMmD0joKX+ZWruSkJw=="], + "@swc/html-darwin-x64": ["@swc/html-darwin-x64@1.15.43", "", { "os": "darwin", "cpu": "x64" }, "sha512-LQJ2U8Oxcx4T1rRF25y4h+/p05nn58FugTe/uGxC5OT3K83c2MftcSZLYaahOu4GVHRZeS1NI94CkSvQV++TVw=="], - "@swc/html-linux-arm-gnueabihf": ["@swc/html-linux-arm-gnueabihf@1.15.40", "", { "os": "linux", "cpu": "arm" }, "sha512-Bbwtl0G6vYcWlDQmjeuyFx8YIvqi1StlQWjRNB1ZtvrRNL3JadFARhijBONiUIyTK9MgUbWtTV3QU69qzjNENQ=="], + "@swc/html-linux-arm-gnueabihf": ["@swc/html-linux-arm-gnueabihf@1.15.43", "", { "os": "linux", "cpu": "arm" }, "sha512-DKIen6DuIRO7Xc5gAbgBT5QyRHJGEGXreIdM1VBosYWTGnnrQ//Hwd7bLD6UbT8X8eU1vqvpXwQ1E24QRqRaBQ=="], - "@swc/html-linux-arm64-gnu": ["@swc/html-linux-arm64-gnu@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-buu4fGyCIhkwmCetI4CfWOPn7cphJHwQ9ksK685hlL0R0PUaDCNdIxo+JAz0mK2JgPhoGqnKsVEmV6gLIL5GBw=="], + "@swc/html-linux-arm64-gnu": ["@swc/html-linux-arm64-gnu@1.15.43", "", { "os": "linux", "cpu": "arm64" }, "sha512-0AuHiyfcE86CZ/CajFIszLzZVzbM2wn5p01oet8Q9RikflCGwyH79Nv9TrAKD1Cx7juUrONzDk+f2b/x73wLTg=="], - "@swc/html-linux-arm64-musl": ["@swc/html-linux-arm64-musl@1.15.40", "", { "os": "linux", "cpu": "arm64" }, "sha512-BwWtpAGEHIP1QwKExWqBIjGpAHMahjT26ORZv3+TbwW4IuEl2QP5FrcYc30O8abCG5J1lWRl1vXKYDpzbIDz1A=="], + "@swc/html-linux-arm64-musl": ["@swc/html-linux-arm64-musl@1.15.43", "", { "os": "linux", "cpu": "arm64" }, "sha512-TweIdl/g9ugkoiYvcL/qbu+gbglDY3TqNxfXH84WXc4rSqEP20owVlxLya2NjVct8LIP2wDrtutpOwAXWC+Eew=="], - "@swc/html-linux-ppc64-gnu": ["@swc/html-linux-ppc64-gnu@1.15.40", "", { "os": "linux", "cpu": "ppc64" }, "sha512-wLtHgwmZu5K7PvuTROklgWJO6D+KwywpYR1geI8dSWX/AYnx/KCGVK9ncPzWVfnLXWhXbkgua3Ujdrfoxf+qSw=="], + "@swc/html-linux-ppc64-gnu": ["@swc/html-linux-ppc64-gnu@1.15.43", "", { "os": "linux", "cpu": "ppc64" }, "sha512-4oue1pB38/W6mbudp+w0q1jbwxuwdbdbaOj85ay0pisCs213WkgP+MPN8Zqa5VVPjQnVk2CTY9kmEc74XQI/sA=="], - "@swc/html-linux-s390x-gnu": ["@swc/html-linux-s390x-gnu@1.15.40", "", { "os": "linux", "cpu": "s390x" }, "sha512-WbWzQBCmvECZG6ep9D5SMMZTFCbFmRSCc7lPD3YhhaK16BNqr1AybvybZYOgxX9Ot5tq7gTWCgjFZXLDOn6Y/g=="], + "@swc/html-linux-s390x-gnu": ["@swc/html-linux-s390x-gnu@1.15.43", "", { "os": "linux", "cpu": "s390x" }, "sha512-/tceMNvAxK70SKUZtcn3X+K0vcElMGk3i8Sz0CmPdtooso8MZ7WfAvVP1qi3TWgh1rpQ3cC+Al3433AHlET6+w=="], - "@swc/html-linux-x64-gnu": ["@swc/html-linux-x64-gnu@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-i+/JqL5j9mTGMcVshWLMzciqyE3Np+gN5+UqMyO1D5zSmniJD5MHRlGXCtLaWx/MIKX0Q4Xkre33o56fmxp+uA=="], + "@swc/html-linux-x64-gnu": ["@swc/html-linux-x64-gnu@1.15.43", "", { "os": "linux", "cpu": "x64" }, "sha512-YE7ltlTt5ZFl59GsoHTDrIHnCBY8EDBio66CVj4bqkElFXbE/28xmpVE5ksdGoI5c5aQ/8byUCfHxqzCzQQSVg=="], - "@swc/html-linux-x64-musl": ["@swc/html-linux-x64-musl@1.15.40", "", { "os": "linux", "cpu": "x64" }, "sha512-mroZnb5omFc4iE01UsJgta+Nm0sIFWpGfTPk+BHfH165MZAM4wNndeczX5RpGZbQSF1nNpCoNgqJyT7l3hITMg=="], + "@swc/html-linux-x64-musl": ["@swc/html-linux-x64-musl@1.15.43", "", { "os": "linux", "cpu": "x64" }, "sha512-nS20HmbOk+dEEzdosJqqxAeyjMIiS5yrCAti8LUf0+dgr4eRmjkH4MlkjfPjf49aayR8o+eMJ1jsDZ7whx4zog=="], - "@swc/html-win32-arm64-msvc": ["@swc/html-win32-arm64-msvc@1.15.40", "", { "os": "win32", "cpu": "arm64" }, "sha512-qg1LXRrsY9FXy0S7vouSF0kkn1vdkTD//FW66iuezH7HMm5/DJGwEj7oc1zTKPWU0HnwOINOUbl6rUHrRuXHAQ=="], + "@swc/html-win32-arm64-msvc": ["@swc/html-win32-arm64-msvc@1.15.43", "", { "os": "win32", "cpu": "arm64" }, "sha512-Yz7aQQhXT/Yc6QcuMDQDZP9jqf2phkVyU+qSu8ZRWEcJgIorrPL6q7YLqMk+MB5PpZyu5XJEODvc1/UVDE1Kyg=="], - "@swc/html-win32-ia32-msvc": ["@swc/html-win32-ia32-msvc@1.15.40", "", { "os": "win32", "cpu": "ia32" }, "sha512-5NwMmgt9A70LQzcYOl4OiIJk5AhsGP69fNRfkmXXop+iIcAGUmYy+d6F2/Gc0u05j9G0R04NPWcHBQrHQhr0Gw=="], + "@swc/html-win32-ia32-msvc": ["@swc/html-win32-ia32-msvc@1.15.43", "", { "os": "win32", "cpu": "ia32" }, "sha512-muUgfsSQRZk6YBRuhaGKSLvXy0bV9BW6/mHLI0N/06btWuf0hekoHhIzR7dUmS98NXKCA7Hv+buBPE/0vXUwyA=="], - "@swc/html-win32-x64-msvc": ["@swc/html-win32-x64-msvc@1.15.40", "", { "os": "win32", "cpu": "x64" }, "sha512-WUNZqCZ+8WY1pr8t3X3fq4gI5+FL/tCCzlrJ2lLn0s+TyA2SLm/RPfXxQIr94EnjJWcIV21G//6/uXeBN8cPzw=="], + "@swc/html-win32-x64-msvc": ["@swc/html-win32-x64-msvc@1.15.43", "", { "os": "win32", "cpu": "x64" }, "sha512-tuLDy4MxPXsLi6jW+ozCdFWO61AoMMnlhePWJxMafefC2Ojm+iILxP2zI2Hgfu6F16y1q7ITdXdpEuqptu5fHw=="], - "@swc/types": ["@swc/types@0.1.26", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw=="], + "@swc/types": ["@swc/types@0.1.27", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-K6h3iUlqeM946U4sXFYeahefR1YBbXJvko+hv8WS8/0BNJ4OHiHRywMnQUJCqkR7Y9+hqQ1TvEpiKqUhz7NEFg=="], "@szmarczak/http-timer": ["@szmarczak/http-timer@5.0.1", "", { "dependencies": { "defer-to-connect": "^2.0.1" } }, "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw=="], "@tanstack/history": ["@tanstack/history@1.162.0", "", {}, "sha512-79pf/RkhteYZTRgcR4F9kbk84P2N8rugQJswxfIqovlbRiT3yI7eBE+5QorIrZaOKktsgzRlXh1l/du/xpl4iA=="], - "@tanstack/react-router": ["@tanstack/react-router@1.170.15", "", { "dependencies": { "@tanstack/history": "1.162.0", "@tanstack/react-store": "^0.9.3", "@tanstack/router-core": "1.171.13", "isbot": "^5.1.22" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-GawYz7HEjj8rTUUDoT/SemDEVm63pZUO+2mOcXHY9Jl3EwMS5gFBnPu/2UvcrwRm1jN1k79fokc0d4aFmrLatg=="], + "@tanstack/react-router": ["@tanstack/react-router@1.170.18", "", { "dependencies": { "@tanstack/history": "1.162.0", "@tanstack/react-store": "^0.9.3", "@tanstack/router-core": "1.171.15", "isbot": "^5.1.22" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-wpbGYZEp/fmz1q4bn7BD8VZ+/VZ7GBqSJv5V969pU+chP8y7dquWDmKTFMohvUegb9lg12m1uPVvD6kB2wORvQ=="], "@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.167.0", "", { "dependencies": { "@tanstack/router-devtools-core": "1.168.0" }, "peerDependencies": { "@tanstack/react-router": "^1.170.0", "@tanstack/router-core": "^1.170.0", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["@tanstack/router-core"] }, "sha512-nGw095EG7IHx0h5NtlEmzf6vcCTaFNPWdTSuDKazajhN0ct/v/TkekJ9J6KYUCeV1a8/2ZmToc58M+0rrOyn7w=="], "@tanstack/react-store": ["@tanstack/react-store@0.9.3", "", { "dependencies": { "@tanstack/store": "0.9.3", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg=="], - "@tanstack/router-core": ["@tanstack/router-core@1.171.13", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-+NOwEj1kO/6IGmpHRIZHasYxYWpyBQGNIZAST9aNrk9Q3YlU9SgqVnl1pbLa9qAKfeNdXQIRve0RQb/0kyDeDA=="], + "@tanstack/router-core": ["@tanstack/router-core@1.171.15", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "^3.0.0", "seroval": "^1.5.4", "seroval-plugins": "^1.5.4" } }, "sha512-IILCDcLaItMZQ2jEmCABHY1Nhjjn5XUvwpQp3e4Nmu+vfg0BgYFuu/QASz2SwE2ZNbVMrvt8X/wxa+Gg5aErxA=="], "@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.168.0", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16" }, "peerDependencies": { "@tanstack/router-core": "^1.170.0", "csstype": "^3.0.10" }, "optionalPeers": ["csstype"] }, "sha512-wQoQhlBK7nlZgqzaqdYXKWNTpdHdsaREdaPhFZVH0/Ador+F+eM3/NF2i3f2LPeS0GgKraZUQXe1Q/1+KHyEYg=="], - "@tanstack/router-generator": ["@tanstack/router-generator@1.167.17", "", { "dependencies": { "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.13", "@tanstack/router-utils": "1.162.2", "@tanstack/virtual-file-routes": "1.162.0", "jiti": "^2.7.0", "magic-string": "^0.30.21", "prettier": "^3.5.0", "zod": "^4.4.3" } }, "sha512-xtB9tB2Ws0tWR6Pi7nc3Qk9IYgoh1mQCKWjHqIl9tf6BNUpKoqniJoPAQ4+LGrK8FeZYU0o0p/qlZEyj9FAulA=="], + "@tanstack/router-generator": ["@tanstack/router-generator@1.167.20", "", { "dependencies": { "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.15", "@tanstack/router-utils": "1.162.2", "@tanstack/virtual-file-routes": "1.162.0", "jiti": "^2.7.0", "magic-string": "^0.30.21", "prettier": "^3.5.0", "zod": "^4.4.3" } }, "sha512-SCLPDE1ne+l1pf30T2mMGKwG3Q5rffGAs/lDqEXmoj0PwYeMwpChs/pLzLN+KH/oDGzSmXKmiK9aGKZy3aSwXA=="], - "@tanstack/router-plugin": ["@tanstack/router-plugin@1.168.18", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.13", "@tanstack/router-generator": "1.167.17", "@tanstack/router-utils": "1.162.2", "chokidar": "^5.0.0", "unplugin": "^3.0.0", "zod": "^4.4.3" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2 || ^2.0.0", "@tanstack/react-router": "^1.170.15", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-MofS28/axfnfnhOD2RSgJEaU882aX5RsAzhGz5Vc4XhAmvCjy919u9JrNs4QsTWFbTD1P7IJ8WFlFVsrg0pStg=="], + "@tanstack/router-plugin": ["@tanstack/router-plugin@1.168.21", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.171.15", "@tanstack/router-generator": "1.167.20", "@tanstack/router-utils": "1.162.2", "chokidar": "^5.0.0", "unplugin": "^3.0.0", "zod": "^4.4.3" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2 || ^2.0.0", "@tanstack/react-router": "^1.170.18", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-76erhrm1jGJ4NvwQZdEZjgUfwaw9jJJjv+w45qx5TNZwemW0zeskYSNSDhxmfnW7ZnMTY7bFCy3zUUBoR6cF7Q=="], "@tanstack/router-utils": ["@tanstack/router-utils@1.162.2", "", { "dependencies": { "@babel/generator": "^7.28.5", "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "ansis": "^4.1.0", "babel-dead-code-elimination": "^1.0.12", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-hTWqJtqIFFdvuCl8WXNyrodp2L9zo2G37xKRrcVmVRWpAB2h+U1LuRAfS4tsFTiWOIoE/B+WDVFB8JpoEdw6jQ=="], @@ -1102,19 +1103,19 @@ "@testing-library/react": ["@testing-library/react@16.3.2", "", { "dependencies": { "@babel/runtime": "^7.12.5" }, "peerDependencies": { "@testing-library/dom": "^10.0.0", "@types/react": "^18.0.0 || ^19.0.0", "@types/react-dom": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g=="], - "@turbo/darwin-64": ["@turbo/darwin-64@2.9.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-jLjApWTSNd7JZ5JaLYfelW1ytnGQOvB7ivl+2RD1xQvJTbi8I9gBjzcga7tDZVPyaxpl10YTfJt3BrYXR18KDw=="], + "@turbo/darwin-64": ["@turbo/darwin-64@2.10.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-ENvPwy3x5yS7MwNYHeWjqOBXkwIMp39Pd+/zXC6PoiNzF8EIvvLZOZZ+ny6L9x4WgS5vxUii2LM5gM+zjPdnWw=="], - "@turbo/darwin-arm64": ["@turbo/darwin-arm64@2.9.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-YPgrn+5HIGzrx0O2a631SV4MBQUe4W/DafMFUuBVgaU32PW9/OTT0ehviF0QSxTXuRJlHvW2eUTemddF5/spmw=="], + "@turbo/darwin-arm64": ["@turbo/darwin-arm64@2.10.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rqROo9zsF/P9RqsdtbLD1nFJicjSrYyvQ9kNJC38AbxA3pAs6VAlATvtvOFx7bqOv6vicf20SP9kF33avJjy2w=="], - "@turbo/linux-64": ["@turbo/linux-64@2.9.16", "", { "os": "linux", "cpu": "x64" }, "sha512-vAEf1H6l26lTpl9FJ/peQo1NUB8RC0sbEJJz5mPcUhHA2bPDup2x3CZPgo/bH8S4cUcBLm4FN3UHd5iUO2RAew=="], + "@turbo/linux-64": ["@turbo/linux-64@2.10.5", "", { "os": "linux", "cpu": "x64" }, "sha512-RoSSiNFUxi27zLJuM9F6GyWWjHgLch9t6nwD6K0FkXRirZkTLlzIj6IhFnK8H9++nefLtdFqylE4vGjZAv6AAA=="], - "@turbo/linux-arm64": ["@turbo/linux-arm64@2.9.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-xDBLR2PZg4BrQOchfG6svgpv5FCNJ2TOtT2psLdEJcdKo1BH+pnPs9Xj6pvUjgfkHbuvBOfeE4R6tvxMoQKDHQ=="], + "@turbo/linux-arm64": ["@turbo/linux-arm64@2.10.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-4ZComcpzmHGmVynQqvvi+iZOSq/tBvY1SltXB8g4NZRsrA01W8E+yRL8RNM+PLoyWsrCnJa8xa+DkWkv+xg4iQ=="], - "@turbo/windows-64": ["@turbo/windows-64@2.9.16", "", { "os": "win32", "cpu": "x64" }, "sha512-NBAJnaUiGdgkSzQwUIdOvkCkcpTSu58G/sBGa0mvBtzfvFOOgrQwepKOOQ8cp6sWM6OcKDNFj2p1dsZA1OWjPg=="], + "@turbo/windows-64": ["@turbo/windows-64@2.10.5", "", { "os": "win32", "cpu": "x64" }, "sha512-eL2Iyj4DbMINq1Sr1w0iAi6nAiZOF16KSlRGwCJpVh+IWZeY33MAsLHVOBMj1xoFtncVJXclCVpTPL2nBoYkFg=="], - "@turbo/windows-arm64": ["@turbo/windows-arm64@2.9.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-Y7SJppD0Z8wjO3Ec0ZGd9KQ4Yv0BMnA8CIowj5Vp+OEVsosXDG2weK6/t1RRLfJmc2Ozrnd6y4DOgQys+mn3WQ=="], + "@turbo/windows-arm64": ["@turbo/windows-arm64@2.10.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-sog+wP+8YSJrdWZ/rUJg8xghVTrwoG+BrSlDQpnK5fzSgJHn1INRWXbVWRH0d3vX8dBI01E3yxXRre9Dn+OXQA=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], "@typed/id": ["@typed/id@0.17.2", "", { "peerDependencies": { "effect": "^3.14.7" } }, "sha512-z/Z14/moeu9x45IpkGaRwuvb+CQ3s3UCc/agcpZibTz1yPb3RgSDXx4rOHIuyb6hG6oNzqe9yY4GbbMq3Hb5Ug=="], @@ -1142,11 +1143,11 @@ "@types/express": ["@types/express@4.17.25", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "^1" } }, "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw=="], - "@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.8", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA=="], + "@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.9", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-QP2ESEe/ImWY0HDwNAnK9PvEffUyhLTnWkk7KXzHfyeWAnlrDe1fN77bXl6ia8KT3wPlmA7t9/VPRpnf4Ex9sg=="], "@types/gtag.js": ["@types/gtag.js@0.0.20", "", {}, "sha512-wwAbk3SA2QeU67unN7zPxjEHmPmlXwZXZvQEpbEUQuMCRGgKyE1m6XDuTUA9b6pCGb/GqJmdfMOY5LuDjJSbbg=="], - "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + "@types/hast": ["@types/hast@3.0.5", "", { "dependencies": { "@types/unist": "*" } }, "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g=="], "@types/history": ["@types/history@4.7.11", "", {}, "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA=="], @@ -1174,7 +1175,7 @@ "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - "@types/node": ["@types/node@25.9.2", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw=="], + "@types/node": ["@types/node@26.1.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw=="], "@types/prismjs": ["@types/prismjs@1.26.6", "", {}, "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw=="], @@ -1196,7 +1197,7 @@ "@types/sax": ["@types/sax@1.2.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A=="], - "@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="], + "@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="], "@types/serve-index": ["@types/serve-index@1.9.4", "", { "dependencies": { "@types/express": "*" } }, "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug=="], @@ -1212,23 +1213,23 @@ "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], - "@ungap/structured-clone": ["@ungap/structured-clone@1.3.1", "", {}, "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ=="], + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.3", "", {}, "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg=="], - "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.2", "", { "dependencies": { "@rolldown/pluginutils": "^1.0.0" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg=="], + "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.3", "", { "dependencies": { "@rolldown/pluginutils": "^1.0.1" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-vmFvco5/QuC2f9Oj+wTk0+9XeDFkHxSamwZKYc7MxYwKICfvUvlMhqKI0VuICPltGqh1neqBKDvO4kes1ya8vg=="], - "@vitest/expect": ["@vitest/expect@3.2.6", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.6", "@vitest/utils": "3.2.6", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-1+7q9BtaKzEmO+fmNT3kYvoNn5Y71XWAx2Q5HRim4tTVRQVRv4uJFAQ5FbK0OPUeNP/WmVCpxYxoJdvuHVjzBQ=="], + "@vitest/expect": ["@vitest/expect@3.2.7", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.7", "@vitest/utils": "3.2.7", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w=="], - "@vitest/mocker": ["@vitest/mocker@3.2.6", "", { "dependencies": { "@vitest/spy": "3.2.6", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-EZOrpDbkKotFAP7wPAQV1UIyoGOk4oX7ynWhBhLB7v+meMHbQhU16oPpIYGTTe4oFlhpryGpgpcZP/sin3hYuw=="], + "@vitest/mocker": ["@vitest/mocker@3.2.7", "", { "dependencies": { "@vitest/spy": "3.2.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA=="], - "@vitest/pretty-format": ["@vitest/pretty-format@3.2.6", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-lb7XXXzmm2h2ASzFnRvQpDo6onT1NmMJA3tkGTWiBFtRJ9lxGY3d3mm/Apt36gej2bkkOVLL/yTOtufDaFa/jA=="], + "@vitest/pretty-format": ["@vitest/pretty-format@3.2.7", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA=="], - "@vitest/runner": ["@vitest/runner@3.2.6", "", { "dependencies": { "@vitest/utils": "3.2.6", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-HYcoSj1w5tcgUnzoF0HcyaAQjpA1gj9ftUJ7iSJSuipc02jW9gKkigwZbjFldAfYHA1fa8UZVRftdMY5msWM9Q=="], + "@vitest/runner": ["@vitest/runner@3.2.7", "", { "dependencies": { "@vitest/utils": "3.2.7", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA=="], - "@vitest/snapshot": ["@vitest/snapshot@3.2.6", "", { "dependencies": { "@vitest/pretty-format": "3.2.6", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-H+ZjNTWGpObenh0YnlBctAPnJSI20P81PL8BPzWpx54YXLLTm8hEsWawtcYLMrwvpK48hGxLLbCS+1KRXhsKhw=="], + "@vitest/snapshot": ["@vitest/snapshot@3.2.7", "", { "dependencies": { "@vitest/pretty-format": "3.2.7", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g=="], - "@vitest/spy": ["@vitest/spy@3.2.6", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-oq6BbH68WzcWmwtBrU9nqLeaXTR4XwJF7FSLkKEZo4i6eoXcrxjcwSuTvWBIRUTC6VC72nXYunzqgZA+IKdtxg=="], + "@vitest/spy": ["@vitest/spy@3.2.7", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ=="], - "@vitest/utils": ["@vitest/utils@3.2.6", "", { "dependencies": { "@vitest/pretty-format": "3.2.6", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-lI23nIs4bnT3T8NIoh+vFaz5s2/DdP0Jgt2jxwgWljvwn82cLJtyi/If+fjFyoLMGIOz0U/fKvWE0d4jsNQEfg=="], + "@vitest/utils": ["@vitest/utils@3.2.7", "", { "dependencies": { "@vitest/pretty-format": "3.2.7", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw=="], "@webassemblyjs/ast": ["@webassemblyjs/ast@1.14.1", "", { "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ=="], @@ -1266,7 +1267,7 @@ "accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="], - "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], + "acorn": ["acorn@8.17.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg=="], "acorn-import-phases": ["acorn-import-phases@1.0.4", "", { "peerDependencies": { "acorn": "^8.14.0" } }, "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ=="], @@ -1286,9 +1287,9 @@ "ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], - "algoliasearch": ["algoliasearch@5.53.0", "", { "dependencies": { "@algolia/abtesting": "1.19.0", "@algolia/client-abtesting": "5.53.0", "@algolia/client-analytics": "5.53.0", "@algolia/client-common": "5.53.0", "@algolia/client-insights": "5.53.0", "@algolia/client-personalization": "5.53.0", "@algolia/client-query-suggestions": "5.53.0", "@algolia/client-search": "5.53.0", "@algolia/ingestion": "1.53.0", "@algolia/monitoring": "1.53.0", "@algolia/recommend": "5.53.0", "@algolia/requester-browser-xhr": "5.53.0", "@algolia/requester-fetch": "5.53.0", "@algolia/requester-node-http": "5.53.0" } }, "sha512-OGW1q6b91CRSSeiOnM8LxuR5NYJ2esvw66jUZ4IIvdv+ItNkx3pwLuyR+jaCdbGee4ov5WgUnyPryyh11xvByQ=="], + "algoliasearch": ["algoliasearch@5.56.0", "", { "dependencies": { "@algolia/abtesting": "1.22.0", "@algolia/client-abtesting": "5.56.0", "@algolia/client-analytics": "5.56.0", "@algolia/client-common": "5.56.0", "@algolia/client-insights": "5.56.0", "@algolia/client-personalization": "5.56.0", "@algolia/client-query-suggestions": "5.56.0", "@algolia/client-search": "5.56.0", "@algolia/ingestion": "1.56.0", "@algolia/monitoring": "1.56.0", "@algolia/recommend": "5.56.0", "@algolia/requester-browser-xhr": "5.56.0", "@algolia/requester-fetch": "5.56.0", "@algolia/requester-node-http": "5.56.0" } }, "sha512-PrqppUmhT4ENdas2pH9caE7efUcxy6EcSFhWzosiVuQBzu2tQ5yLTI6jwomT/1cuBnivzGfxiJCqDNN9FRRh+Q=="], - "algoliasearch-helper": ["algoliasearch-helper@3.29.1", "", { "dependencies": { "@algolia/events": "^4.0.1" }, "peerDependencies": { "algoliasearch": ">= 3.1 < 6" } }, "sha512-6ck2YFudF2Pje7szQoPBiRFTGfd+1I+0I/WfLPGn0bj1kvrFoOQmNyedNiDxTk3/r4IfSLDYk+RA4G7u8H6+yA=="], + "algoliasearch-helper": ["algoliasearch-helper@3.29.2", "", { "dependencies": { "@algolia/events": "^4.0.1" }, "peerDependencies": { "algoliasearch": ">= 3.1 < 6" } }, "sha512-SaV+rZM3drExb0punEYYjT+sNcH74YFwN8ocjya7IDOyQvKWeQpEaSMVG3+IGTVos+feuatj7ljQ4BXlXdUp3w=="], "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="], @@ -1320,7 +1321,7 @@ "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], - "autoprefixer": ["autoprefixer@10.5.0", "", { "dependencies": { "browserslist": "^4.28.2", "caniuse-lite": "^1.0.30001787", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong=="], + "autoprefixer": ["autoprefixer@10.5.4", "", { "dependencies": { "browserslist": "^4.28.6", "caniuse-lite": "^1.0.30001806", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA=="], "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="], @@ -1338,7 +1339,7 @@ "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.34", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.10.43", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ=="], "batch": ["batch@0.6.1", "", {}, "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw=="], @@ -1346,19 +1347,19 @@ "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], - "body-parser": ["body-parser@1.20.5", "", { "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "~1.2.0", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.15.1", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA=="], + "body-parser": ["body-parser@1.20.6", "", { "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "~1.2.0", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.15.1", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g=="], - "bonjour-service": ["bonjour-service@1.4.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "sha512-fGQtj1qdR9vIKjFiWPQd52qIqwjaYqhcI40JEiDuvlZ86E7ZBPBwY9fPgHy9r2rYGIjiRfctNPYz6OQU73ww2w=="], + "bonjour-service": ["bonjour-service@1.4.3", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "sha512-2Kd5UYlFUVgAKMTyuBLl6w49wqfOnbxHqmuH0oCl/n7TfAikR0zoowNOP5BU4dfXmm+Vr9JyEN370auSMx+CNg=="], "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], "boxen": ["boxen@6.2.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^6.2.0", "chalk": "^4.1.2", "cli-boxes": "^3.0.0", "string-width": "^5.0.1", "type-fest": "^2.5.0", "widest-line": "^4.0.1", "wrap-ansi": "^8.0.1" } }, "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw=="], - "brace-expansion": ["brace-expansion@1.1.15", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg=="], + "brace-expansion": ["brace-expansion@1.1.16", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], - "browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", "electron-to-chromium": "^1.5.328", "node-releases": "^2.0.36", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="], + "browserslist": ["browserslist@4.28.6", "", { "dependencies": { "baseline-browser-mapping": "^2.10.42", "caniuse-lite": "^1.0.30001803", "electron-to-chromium": "^1.5.389", "node-releases": "^2.0.51", "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw=="], "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], @@ -1390,7 +1391,7 @@ "caniuse-api": ["caniuse-api@3.0.0", "", { "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw=="], - "caniuse-lite": ["caniuse-lite@1.0.30001797", "", {}, "sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w=="], + "caniuse-lite": ["caniuse-lite@1.0.30001806", "", {}, "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], @@ -1508,7 +1509,7 @@ "css-select": ["css-select@4.3.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" } }, "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ=="], - "css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="], + "css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], @@ -1608,15 +1609,15 @@ "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], - "effect": ["effect@3.21.3", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-RqwU7WnJ6CqYhyjpOVJA5vh1Sgkn6eVECO6mnD0EjlbWcC2M3LJaPglXXr13Rdo/Y+B+wTEPzGRYFNL2xKxNeQ=="], + "effect": ["effect@3.22.0", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-jhYFe0zTlIRqYFrKTS+6luhmS/Tm0f+JLo0K9KUxvtFab1SUGEszQi2ehOP6QzAZvy831lDmTwwzvVDZSPNz3g=="], "effect-fc": ["effect-fc@workspace:packages/effect-fc"], "effect-fc-next": ["effect-fc-next@workspace:packages/effect-fc-next"], - "effect-lens": ["effect-lens@0.2.0", "", { "peerDependencies": { "effect": "^3.21.0" } }, "sha512-Cfyps811WQVSxnbxm6xqJldL08YXUU1jAzWtdKXSKWZfF6LAEqm1l8swnw4ltVky1TSfi2vvS+I/tFPqwObrMg=="], + "effect-lens": ["effect-lens@0.2.2", "", { "peerDependencies": { "effect": "^3.21.0" } }, "sha512-kt+aLq9djFFAH3sj+/YapcIzx/tqmkTO+ofU2HiEIm34zB/zx+0PvWLXqhK1EuCEjl9Ueififg711J1FvvzIqw=="], - "electron-to-chromium": ["electron-to-chromium@1.5.368", "", {}, "sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw=="], + "electron-to-chromium": ["electron-to-chromium@1.5.393", "", {}, "sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg=="], "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], @@ -1628,7 +1629,7 @@ "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], - "enhanced-resolve": ["enhanced-resolve@5.23.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA=="], + "enhanced-resolve": ["enhanced-resolve@5.24.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-rpsZEGT1jFuve6QlpyRp9ckQ+kN61hvF9BzCPyMdaKTm8UJce96KBn3sorXOFXlzjPrs3Vc4T1NsSroZ3PxlFw=="], "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], @@ -1638,7 +1639,7 @@ "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], - "es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], + "es-module-lexer": ["es-module-lexer@2.3.1", "", {}, "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA=="], "es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="], @@ -1646,7 +1647,7 @@ "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], - "esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="], + "esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="], "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], @@ -1694,7 +1695,7 @@ "execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], - "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], + "expect-type": ["expect-type@1.4.0", "", {}, "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA=="], "express": ["express@4.22.2", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.5", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q=="], @@ -1710,7 +1711,7 @@ "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], - "fast-uri": ["fast-uri@3.1.2", "", {}, "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ=="], + "fast-uri": ["fast-uri@3.1.3", "", {}, "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg=="], "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], @@ -1748,7 +1749,7 @@ "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="], - "fs-extra": ["fs-extra@11.3.5", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg=="], + "fs-extra": ["fs-extra@11.3.6", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -1772,11 +1773,9 @@ "glob-to-regex.js": ["glob-to-regex.js@1.2.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ=="], - "glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="], - "global-dirs": ["global-dirs@3.0.1", "", { "dependencies": { "ini": "2.0.0" } }, "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA=="], - "globals": ["globals@17.6.0", "", {}, "sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA=="], + "globals": ["globals@17.7.0", "", {}, "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg=="], "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], @@ -1854,7 +1853,7 @@ "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], - "http-proxy-middleware": ["http-proxy-middleware@2.0.9", "", { "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", "is-glob": "^4.0.1", "is-plain-obj": "^3.0.0", "micromatch": "^4.0.2" }, "peerDependencies": { "@types/express": "^4.17.13" }, "optionalPeers": ["@types/express"] }, "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q=="], + "http-proxy-middleware": ["http-proxy-middleware@2.0.10", "", { "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", "is-glob": "^4.0.1", "is-plain-obj": "^3.0.0", "micromatch": "^4.0.2" }, "peerDependencies": { "@types/express": "^4.17.13" }, "optionalPeers": ["@types/express"] }, "sha512-RKzRWNPxUZqbuk3BC5mGVJbBnWgr+diEnjJexIOytFbBzDy88Fbh/YvBr3DsNrl1jYAfjWfpATEv0NO35FDuPQ=="], "http2-wrapper": ["http2-wrapper@2.2.1", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" } }, "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ=="], @@ -1950,7 +1949,7 @@ "isarray": ["isarray@0.0.1", "", {}, "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="], - "isbot": ["isbot@5.1.41", "", {}, "sha512-9WFV/Vhh0FEj6CQ7MoHweEL9/vLKPjeoD2I2htbAjX7kbW7VJs3OCpWOVyd+JraNTWVU6/DRx2MZy2KaUNXHcg=="], + "isbot": ["isbot@5.2.1", "", {}, "sha512-dJ+LpKyClQZ7NG+j3OensC/mAZkGpukE9YUrgPYvAZj2doVL0edfDgywTUh5CXa0o+nW9a1V9e5+CJTX8+SxRw=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], @@ -1962,11 +1961,11 @@ "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], - "joi": ["joi@17.13.3", "", { "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } }, "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA=="], + "joi": ["joi@17.13.4", "", { "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } }, "sha512-1RuuER6kmt8K8I3nIWvPZKi5RQCb568ZPyY4Pwjlua+yo+63ZTmIwxLZH0heBmiKN4uxjvCiarDrjaeH84xicQ=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - "js-yaml": ["js-yaml@4.2.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw=="], + "js-yaml": ["js-yaml@4.3.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q=="], "jsdom": ["jsdom@26.1.0", "", { "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", "decimal.js": "^10.5.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.6", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.16", "parse5": "^7.2.1", "rrweb-cssom": "^0.8.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^5.1.1", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.1.1", "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg=="], @@ -2096,11 +2095,11 @@ "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], - "mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="], + "mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], "media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], - "memfs": ["memfs@4.57.6", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.57.6", "@jsonjoy.com/fs-fsa": "4.57.6", "@jsonjoy.com/fs-node": "4.57.6", "@jsonjoy.com/fs-node-builtins": "4.57.6", "@jsonjoy.com/fs-node-to-fsa": "4.57.6", "@jsonjoy.com/fs-node-utils": "4.57.6", "@jsonjoy.com/fs-print": "4.57.6", "@jsonjoy.com/fs-snapshot": "4.57.6", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", "thingies": "^2.5.0", "tree-dump": "^1.0.3", "tslib": "^2.0.0" } }, "sha512-WQK+DGjKCnPdpSyJUXphz+COF2uEhhsxQ3VIWBSbzpbbXuch3h4FePMqXrXGdLjsTgo4JFzBFsP6AWd9pVazGw=="], + "memfs": ["memfs@4.64.0", "", { "dependencies": { "@jsonjoy.com/fs-core": "4.64.0", "@jsonjoy.com/fs-fsa": "4.64.0", "@jsonjoy.com/fs-node": "4.64.0", "@jsonjoy.com/fs-node-builtins": "4.64.0", "@jsonjoy.com/fs-node-to-fsa": "4.64.0", "@jsonjoy.com/fs-node-utils": "4.64.0", "@jsonjoy.com/fs-print": "4.64.0", "@jsonjoy.com/fs-snapshot": "4.64.0", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", "thingies": "^2.5.0", "tree-dump": "^1.0.3", "tslib": "^2.0.0" } }, "sha512-Kw72fgY7Wn+sD8KmtNWSafl1dz0UvAsE/PHs3YVfLiaZuA3HxNm9sRLqAu0ATiBGJvME1PxZXbBZPv5GycDeAw=="], "merge-descriptors": ["merge-descriptors@1.0.3", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="], @@ -2204,19 +2203,21 @@ "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + "minimizer-webpack-plugin": ["minimizer-webpack-plugin@5.6.1", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", "terser": "^5.31.1" }, "peerDependencies": { "@minify-html/node": "*", "@swc/core": "*", "@swc/css": "*", "@swc/html": "*", "clean-css": "*", "cssnano": "*", "csso": "*", "esbuild": "*", "html-minifier-terser": "*", "lightningcss": "*", "postcss": "*", "uglify-js": "*", "webpack": "^5.1.0" }, "optionalPeers": ["@minify-html/node", "@swc/core", "@swc/css", "@swc/html", "clean-css", "cssnano", "csso", "esbuild", "html-minifier-terser", "lightningcss", "postcss", "uglify-js"] }, "sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw=="], + "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "msgpackr": ["msgpackr@1.11.14", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-suPZQcjFtPGp0cksn70ICfLuxsO9F2/sRrbJzeNepojZ+OPwGzA0lNdLyU4SJUKAd5ZgvUWWPojzzdlVuOYcrQ=="], + "msgpackr": ["msgpackr@1.12.1", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-4EUH9tQHnMmEgzW/MdAP0KIfa1T9AF+htl0ffe2n5vb2EKn9y2co8ccpgWko6S52Jy1PQZKwRnx5/KkYjtd9MQ=="], "msgpackr-extract": ["msgpackr-extract@3.0.4", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw=="], "multicast-dns": ["multicast-dns@7.2.5", "", { "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" }, "bin": { "multicast-dns": "cli.js" } }, "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg=="], - "multipasta": ["multipasta@0.2.7", "", {}, "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA=="], + "multipasta": ["multipasta@0.2.8", "", {}, "sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q=="], - "nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], + "nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="], "negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="], @@ -2228,13 +2229,13 @@ "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="], - "node-releases": ["node-releases@2.0.47", "", {}, "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og=="], + "node-releases": ["node-releases@2.0.51", "", {}, "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], "normalize-url": ["normalize-url@8.1.1", "", {}, "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ=="], - "npm-check-updates": ["npm-check-updates@22.2.3", "", { "bin": { "npm-check-updates": "build/cli.js", "ncu": "build/cli.js" } }, "sha512-n8HZ0ywZugYRgEqIm67hbZC5L/9S/gLX+MkGchJB43pP2xib1+u76OpVEJRZ4QP2BksPRi5M1CCStJVfc16+/A=="], + "npm-check-updates": ["npm-check-updates@22.2.9", "", { "bin": { "npm-check-updates": "build/cli.js", "ncu": "build/cli.js" } }, "sha512-DVeZ0KirHfliSsHuR2o7cHE+tW439sVHfJjF6cGWeDiY0Wyl3BI/jS4zV0eixtcMOquFbcF1Su/FsxOvk5MoYA=="], "npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], @@ -2322,13 +2323,13 @@ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], + "picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="], "pkg-dir": ["pkg-dir@7.0.0", "", { "dependencies": { "find-up": "^6.3.0" } }, "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA=="], "pkijs": ["pkijs@3.4.0", "", { "dependencies": { "@noble/hashes": "1.4.0", "asn1js": "^3.0.6", "bytestreamjs": "^2.0.1", "pvtsutils": "^1.3.6", "pvutils": "^1.1.3", "tslib": "^2.8.1" } }, "sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw=="], - "postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="], + "postcss": ["postcss@8.5.19", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ=="], "postcss-attribute-case-insensitive": ["postcss-attribute-case-insensitive@7.0.1", "", { "dependencies": { "postcss-selector-parser": "^7.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw=="], @@ -2448,7 +2449,7 @@ "postcss-selector-not": ["postcss-selector-not@8.0.1", "", { "dependencies": { "postcss-selector-parser": "^7.0.0" }, "peerDependencies": { "postcss": "^8.4" } }, "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA=="], - "postcss-selector-parser": ["postcss-selector-parser@7.1.1", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg=="], + "postcss-selector-parser": ["postcss-selector-parser@7.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg=="], "postcss-sort-media-queries": ["postcss-sort-media-queries@5.2.0", "", { "dependencies": { "sort-css-media-queries": "2.2.0" }, "peerDependencies": { "postcss": "^8.4.23" } }, "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA=="], @@ -2460,7 +2461,7 @@ "postcss-zindex": ["postcss-zindex@6.0.2", "", { "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg=="], - "prettier": ["prettier@3.8.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="], + "prettier": ["prettier@3.9.5", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg=="], "pretty-error": ["pretty-error@4.0.0", "", { "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" } }, "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw=="], @@ -2494,13 +2495,13 @@ "pvutils": ["pvutils@1.1.5", "", {}, "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA=="], - "qs": ["qs@6.15.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw=="], + "qs": ["qs@6.15.3", "", { "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" } }, "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A=="], "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], - "radix-ui": ["radix-ui@1.5.0", "", { "dependencies": { "@radix-ui/primitive": "1.1.4", "@radix-ui/react-accessible-icon": "1.1.9", "@radix-ui/react-accordion": "1.2.13", "@radix-ui/react-alert-dialog": "1.1.16", "@radix-ui/react-arrow": "1.1.9", "@radix-ui/react-aspect-ratio": "1.1.9", "@radix-ui/react-avatar": "1.1.12", "@radix-ui/react-checkbox": "1.3.4", "@radix-ui/react-collapsible": "1.1.13", "@radix-ui/react-collection": "1.1.9", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.1.4", "@radix-ui/react-context-menu": "2.3.0", "@radix-ui/react-dialog": "1.1.16", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.12", "@radix-ui/react-dropdown-menu": "2.1.17", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.9", "@radix-ui/react-form": "0.1.9", "@radix-ui/react-hover-card": "1.1.16", "@radix-ui/react-label": "2.1.9", "@radix-ui/react-menu": "2.1.17", "@radix-ui/react-menubar": "1.1.17", "@radix-ui/react-navigation-menu": "1.2.15", "@radix-ui/react-one-time-password-field": "0.1.9", "@radix-ui/react-password-toggle-field": "0.1.4", "@radix-ui/react-popover": "1.1.16", "@radix-ui/react-popper": "1.3.0", "@radix-ui/react-portal": "1.1.11", "@radix-ui/react-presence": "1.1.6", "@radix-ui/react-primitive": "2.1.5", "@radix-ui/react-progress": "1.1.9", "@radix-ui/react-radio-group": "1.4.0", "@radix-ui/react-roving-focus": "1.1.12", "@radix-ui/react-scroll-area": "1.2.11", "@radix-ui/react-select": "2.3.0", "@radix-ui/react-separator": "1.1.9", "@radix-ui/react-slider": "1.4.0", "@radix-ui/react-slot": "1.2.5", "@radix-ui/react-switch": "1.3.0", "@radix-ui/react-tabs": "1.1.14", "@radix-ui/react-toast": "1.2.16", "@radix-ui/react-toggle": "1.1.11", "@radix-ui/react-toggle-group": "1.1.12", "@radix-ui/react-toolbar": "1.1.12", "@radix-ui/react-tooltip": "1.2.9", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-escape-keydown": "1.1.2", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.5" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nzh2HNpClgB31FBHRqt2xG8XNUfVfQRpf34hACC5PNrXTd5JdXdqOXwLs3BL+D8CNYiNQiJiT8QGr5Q4vq+00w=="], + "radix-ui": ["radix-ui@1.6.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.5", "@radix-ui/react-accessible-icon": "1.1.11", "@radix-ui/react-accordion": "1.2.16", "@radix-ui/react-alert-dialog": "1.1.19", "@radix-ui/react-arrow": "1.1.11", "@radix-ui/react-aspect-ratio": "1.1.11", "@radix-ui/react-avatar": "1.2.2", "@radix-ui/react-checkbox": "1.3.7", "@radix-ui/react-collapsible": "1.1.16", "@radix-ui/react-collection": "1.1.12", "@radix-ui/react-compose-refs": "1.1.3", "@radix-ui/react-context": "1.2.0", "@radix-ui/react-context-menu": "2.3.3", "@radix-ui/react-dialog": "1.1.19", "@radix-ui/react-direction": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.15", "@radix-ui/react-dropdown-menu": "2.1.20", "@radix-ui/react-focus-guards": "1.1.4", "@radix-ui/react-focus-scope": "1.1.12", "@radix-ui/react-form": "0.1.12", "@radix-ui/react-hover-card": "1.1.19", "@radix-ui/react-label": "2.1.11", "@radix-ui/react-menu": "2.1.20", "@radix-ui/react-menubar": "1.1.20", "@radix-ui/react-navigation-menu": "1.2.18", "@radix-ui/react-one-time-password-field": "0.1.12", "@radix-ui/react-password-toggle-field": "0.1.7", "@radix-ui/react-popover": "1.1.19", "@radix-ui/react-popper": "1.3.3", "@radix-ui/react-portal": "1.1.13", "@radix-ui/react-presence": "1.1.7", "@radix-ui/react-primitive": "2.1.7", "@radix-ui/react-progress": "1.1.12", "@radix-ui/react-radio-group": "1.4.3", "@radix-ui/react-roving-focus": "1.1.15", "@radix-ui/react-scroll-area": "1.2.14", "@radix-ui/react-select": "2.3.3", "@radix-ui/react-separator": "1.1.11", "@radix-ui/react-slider": "1.4.3", "@radix-ui/react-slot": "1.3.0", "@radix-ui/react-switch": "1.3.3", "@radix-ui/react-tabs": "1.1.17", "@radix-ui/react-toast": "1.2.19", "@radix-ui/react-toggle": "1.1.14", "@radix-ui/react-toggle-group": "1.1.15", "@radix-ui/react-toolbar": "1.1.15", "@radix-ui/react-tooltip": "1.2.12", "@radix-ui/react-use-callback-ref": "1.1.2", "@radix-ui/react-use-controllable-state": "1.2.3", "@radix-ui/react-use-effect-event": "0.0.3", "@radix-ui/react-use-escape-keydown": "1.1.3", "@radix-ui/react-use-is-hydrated": "0.1.1", "@radix-ui/react-use-layout-effect": "1.1.2", "@radix-ui/react-use-size": "1.1.2", "@radix-ui/react-visually-hidden": "1.2.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-OwYUjzMwiInCUxgAWpPsavXC3Kh4iyi/49uU1/qZTG3RQDlvegyk1GOMiGvSkjua1RDb3JD3fo3eroL9FV4GQw=="], "randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="], @@ -2518,7 +2519,7 @@ "react-helmet-async": ["@slorber/react-helmet-async@1.3.0", "", { "dependencies": { "@babel/runtime": "^7.12.5", "invariant": "^2.2.4", "prop-types": "^15.7.2", "react-fast-compare": "^3.2.0", "shallowequal": "^1.1.0" }, "peerDependencies": { "react": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A=="], - "react-icons": ["react-icons@5.6.0", "", { "peerDependencies": { "react": "*" } }, "sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA=="], + "react-icons": ["react-icons@5.7.0", "", { "peerDependencies": { "react": "*" } }, "sha512-LBLy340Rzqy6+/yVhZKT3B/QpP1BZaesGqasf09HPOBzRarcDIFH0WwXlXQfE7q7ipxK4MSiC5DIBWURCny6fw=="], "react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], @@ -2566,7 +2567,7 @@ "regjsgen": ["regjsgen@0.8.0", "", {}, "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q=="], - "regjsparser": ["regjsparser@0.13.1", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw=="], + "regjsparser": ["regjsparser@0.13.2", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ=="], "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", "vfile": "^6.0.0" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], @@ -2612,9 +2613,9 @@ "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - "rolldown": ["rolldown@1.0.3", "", { "dependencies": { "@oxc-project/types": "=0.133.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.3", "@rolldown/binding-darwin-arm64": "1.0.3", "@rolldown/binding-darwin-x64": "1.0.3", "@rolldown/binding-freebsd-x64": "1.0.3", "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", "@rolldown/binding-linux-arm64-gnu": "1.0.3", "@rolldown/binding-linux-arm64-musl": "1.0.3", "@rolldown/binding-linux-ppc64-gnu": "1.0.3", "@rolldown/binding-linux-s390x-gnu": "1.0.3", "@rolldown/binding-linux-x64-gnu": "1.0.3", "@rolldown/binding-linux-x64-musl": "1.0.3", "@rolldown/binding-openharmony-arm64": "1.0.3", "@rolldown/binding-wasm32-wasi": "1.0.3", "@rolldown/binding-win32-arm64-msvc": "1.0.3", "@rolldown/binding-win32-x64-msvc": "1.0.3" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g=="], + "rolldown": ["rolldown@1.1.5", "", { "dependencies": { "@oxc-project/types": "=0.139.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.5", "@rolldown/binding-darwin-arm64": "1.1.5", "@rolldown/binding-darwin-x64": "1.1.5", "@rolldown/binding-freebsd-x64": "1.1.5", "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", "@rolldown/binding-linux-arm64-gnu": "1.1.5", "@rolldown/binding-linux-arm64-musl": "1.1.5", "@rolldown/binding-linux-ppc64-gnu": "1.1.5", "@rolldown/binding-linux-s390x-gnu": "1.1.5", "@rolldown/binding-linux-x64-gnu": "1.1.5", "@rolldown/binding-linux-x64-musl": "1.1.5", "@rolldown/binding-openharmony-arm64": "1.1.5", "@rolldown/binding-wasm32-wasi": "1.1.5", "@rolldown/binding-win32-arm64-msvc": "1.1.5", "@rolldown/binding-win32-x64-msvc": "1.1.5" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA=="], - "rollup": ["rollup@4.61.1", "", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.61.1", "@rollup/rollup-android-arm64": "4.61.1", "@rollup/rollup-darwin-arm64": "4.61.1", "@rollup/rollup-darwin-x64": "4.61.1", "@rollup/rollup-freebsd-arm64": "4.61.1", "@rollup/rollup-freebsd-x64": "4.61.1", "@rollup/rollup-linux-arm-gnueabihf": "4.61.1", "@rollup/rollup-linux-arm-musleabihf": "4.61.1", "@rollup/rollup-linux-arm64-gnu": "4.61.1", "@rollup/rollup-linux-arm64-musl": "4.61.1", "@rollup/rollup-linux-loong64-gnu": "4.61.1", "@rollup/rollup-linux-loong64-musl": "4.61.1", "@rollup/rollup-linux-ppc64-gnu": "4.61.1", "@rollup/rollup-linux-ppc64-musl": "4.61.1", "@rollup/rollup-linux-riscv64-gnu": "4.61.1", "@rollup/rollup-linux-riscv64-musl": "4.61.1", "@rollup/rollup-linux-s390x-gnu": "4.61.1", "@rollup/rollup-linux-x64-gnu": "4.61.1", "@rollup/rollup-linux-x64-musl": "4.61.1", "@rollup/rollup-openbsd-x64": "4.61.1", "@rollup/rollup-openharmony-arm64": "4.61.1", "@rollup/rollup-win32-arm64-msvc": "4.61.1", "@rollup/rollup-win32-ia32-msvc": "4.61.1", "@rollup/rollup-win32-x64-gnu": "4.61.1", "@rollup/rollup-win32-x64-msvc": "4.61.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-I4KW6iuRpuu2uHBLraZ1wNZe0DP7lnRha+VJ9tNaYVaVgKhW0aI3h4RYnoRPeql0flHm/Co55b7snEDcOfOJrA=="], + "rollup": ["rollup@4.62.2", "", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.62.2", "@rollup/rollup-android-arm64": "4.62.2", "@rollup/rollup-darwin-arm64": "4.62.2", "@rollup/rollup-darwin-x64": "4.62.2", "@rollup/rollup-freebsd-arm64": "4.62.2", "@rollup/rollup-freebsd-x64": "4.62.2", "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", "@rollup/rollup-linux-arm-musleabihf": "4.62.2", "@rollup/rollup-linux-arm64-gnu": "4.62.2", "@rollup/rollup-linux-arm64-musl": "4.62.2", "@rollup/rollup-linux-loong64-gnu": "4.62.2", "@rollup/rollup-linux-loong64-musl": "4.62.2", "@rollup/rollup-linux-ppc64-gnu": "4.62.2", "@rollup/rollup-linux-ppc64-musl": "4.62.2", "@rollup/rollup-linux-riscv64-gnu": "4.62.2", "@rollup/rollup-linux-riscv64-musl": "4.62.2", "@rollup/rollup-linux-s390x-gnu": "4.62.2", "@rollup/rollup-linux-x64-gnu": "4.62.2", "@rollup/rollup-linux-x64-musl": "4.62.2", "@rollup/rollup-openbsd-x64": "4.62.2", "@rollup/rollup-openharmony-arm64": "4.62.2", "@rollup/rollup-win32-arm64-msvc": "4.62.2", "@rollup/rollup-win32-ia32-msvc": "4.62.2", "@rollup/rollup-win32-x64-gnu": "4.62.2", "@rollup/rollup-win32-x64-msvc": "4.62.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA=="], "rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="], @@ -2646,7 +2647,7 @@ "selfsigned": ["selfsigned@5.5.0", "", { "dependencies": { "@peculiar/x509": "^1.14.2", "pkijs": "^3.3.3" } }, "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew=="], - "semver": ["semver@7.8.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ=="], + "semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], "semver-diff": ["semver-diff@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA=="], @@ -2654,9 +2655,9 @@ "serialize-javascript": ["serialize-javascript@6.0.2", "", { "dependencies": { "randombytes": "^2.1.0" } }, "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g=="], - "seroval": ["seroval@1.5.4", "", {}, "sha512-46uFvgrXTVxZcUorgSSRZ4y+ieqLLQRMlG4bnCZKW3qI6BZm7Rg4ntMW4p1mILEEBZWrFlcpp0AyIIlM6jD9iw=="], + "seroval": ["seroval@1.5.5", "", {}, "sha512-bSjOuPcwPKLSJNhr9+bZxA20nQxVle5J5MNsYRVE6cIg7KpRLXGupymePavu0jrxlPiPsr4xGZSB8yUY2sH2sw=="], - "seroval-plugins": ["seroval-plugins@1.5.4", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-S0xQPhUTefAhNvNWFg0c1J8qJArHt5KdtJ/cFAofo06KD1MVSeFWyl4iiu+ApDIuw0WhjpOfCdgConOfAnLgkw=="], + "seroval-plugins": ["seroval-plugins@1.5.5", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-+BDhqYM6CEn3x09v44dpa9p6974FuUB2dxk+Ctn04k0cO1Zt6QODTXfmEZK0eBaTe/fJBvP4NMGuNJ+R8T+QMg=="], "serve-handler": ["serve-handler@6.1.7", "", { "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", "mime-types": "2.1.18", "minimatch": "3.1.5", "path-is-inside": "1.0.2", "path-to-regexp": "3.3.0", "range-parser": "1.2.0" } }, "sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg=="], @@ -2676,9 +2677,9 @@ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], - "shell-quote": ["shell-quote@1.8.4", "", {}, "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ=="], + "shell-quote": ["shell-quote@1.10.0", "", {}, "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA=="], - "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], + "side-channel": ["side-channel@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="], "side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="], @@ -2758,7 +2759,7 @@ "svg-parser": ["svg-parser@2.0.4", "", {}, "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ=="], - "svgo": ["svgo@3.3.3", "", { "dependencies": { "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0", "sax": "^1.5.0" }, "bin": "./bin/svgo" }, "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng=="], + "svgo": ["svgo@3.3.4", "", { "dependencies": { "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0", "sax": "^1.5.0" }, "bin": "./bin/svgo" }, "sha512-GsNRis4e8jxn2Y9ENz/8lbJ93CstG8svtMnuRaHbiF2LTJ5tK0/q3t/URPq9Zc7zVWBJnNnJMIp6bevK7bSmNg=="], "swc-loader": ["swc-loader@0.2.7", "", { "dependencies": { "@swc/counter": "^0.1.3" }, "peerDependencies": { "@swc/core": "^1.2.147", "webpack": ">=2" } }, "sha512-nwYWw3Fh9ame3Rtm7StS9SBLpHRRnYcK7bnpF3UKZmesAK0gw2/ADvlURFAINmPvKtDLzp+GBiP9yLoEjg6S9w=="], @@ -2768,7 +2769,7 @@ "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="], - "terser": ["terser@5.48.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q=="], + "terser": ["terser@5.49.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA=="], "terser-webpack-plugin": ["terser-webpack-plugin@5.6.1", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", "terser": "^5.31.1" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ=="], @@ -2800,7 +2801,7 @@ "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], - "toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="], + "toml": ["toml@4.3.0", "", {}, "sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A=="], "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], @@ -2818,9 +2819,9 @@ "tsyringe": ["tsyringe@4.10.0", "", { "dependencies": { "tslib": "^1.9.3" } }, "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw=="], - "turbo": ["turbo@2.9.16", "", { "optionalDependencies": { "@turbo/darwin-64": "2.9.16", "@turbo/darwin-arm64": "2.9.16", "@turbo/linux-64": "2.9.16", "@turbo/linux-arm64": "2.9.16", "@turbo/windows-64": "2.9.16", "@turbo/windows-arm64": "2.9.16" }, "bin": { "turbo": "bin/turbo" } }, "sha512-NqgRQy6j6dPYcdSdv0q1g9QsZg7SWg87RERM8otw/1AtKU2yTFVClOM7cbwKzOonZr/Ek1blTBucw64L9H0Bwg=="], + "turbo": ["turbo@2.10.5", "", { "optionalDependencies": { "@turbo/darwin-64": "2.10.5", "@turbo/darwin-arm64": "2.10.5", "@turbo/linux-64": "2.10.5", "@turbo/linux-arm64": "2.10.5", "@turbo/windows-64": "2.10.5", "@turbo/windows-arm64": "2.10.5" }, "bin": { "turbo": "bin/turbo" } }, "sha512-07Y/C7OUp23l4P92PJoYtFNbHjLhftrZH5Ce7dbczS4kX2Re+wtbXvZLoxn/pUtzgsQaRCBaRuZPJp4zmAn0WQ=="], - "type-fest": ["type-fest@5.7.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg=="], + "type-fest": ["type-fest@5.8.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA=="], "type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="], @@ -2828,7 +2829,7 @@ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], - "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], + "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="], @@ -2860,7 +2861,7 @@ "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], - "unplugin": ["unplugin@3.0.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg=="], + "unplugin": ["unplugin@3.3.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.4", "webpack-virtual-modules": "^0.6.2" }, "peerDependencies": { "@farmfe/core": "*", "@rspack/core": "*", "bun-types-no-globals": "*", "esbuild": "*", "rolldown": "*", "rollup": "*", "unloader": "*", "vite": "*", "webpack": "*" }, "optionalPeers": ["@farmfe/core", "@rspack/core", "bun-types-no-globals", "esbuild", "rolldown", "rollup", "unloader", "vite", "webpack"] }, "sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg=="], "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], @@ -2896,15 +2897,15 @@ "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - "vite": ["vite@8.0.16", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", "rolldown": "1.0.3", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.18", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw=="], + "vite": ["vite@8.1.5", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", "postcss": "^8.5.17", "rolldown": "~1.1.5", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw=="], "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], - "vitest": ["vitest@3.2.6", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.6", "@vitest/mocker": "3.2.6", "@vitest/pretty-format": "^3.2.6", "@vitest/runner": "3.2.6", "@vitest/snapshot": "3.2.6", "@vitest/spy": "3.2.6", "@vitest/utils": "3.2.6", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.6", "@vitest/ui": "3.2.6", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-xejya+bT/j/+R/AGa1XOfRxLmNUlLtlwjRsFUILF+xHfzElmGcmFydy2gqqIrd62ptIEfwVMofd19uNWD9L7Nw=="], + "vitest": ["vitest@3.2.7", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.7", "@vitest/mocker": "3.2.7", "@vitest/pretty-format": "^3.2.7", "@vitest/runner": "3.2.7", "@vitest/snapshot": "3.2.7", "@vitest/spy": "3.2.7", "@vitest/utils": "3.2.7", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.7", "@vitest/ui": "3.2.7", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "./vitest.mjs" } }, "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg=="], "w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="], - "watchpack": ["watchpack@2.5.1", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg=="], + "watchpack": ["watchpack@2.5.2", "", { "dependencies": { "graceful-fs": "^4.1.2" } }, "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg=="], "wbuf": ["wbuf@1.7.3", "", { "dependencies": { "minimalistic-assert": "^1.0.0" } }, "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA=="], @@ -2912,17 +2913,17 @@ "webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], - "webpack": ["webpack@5.107.2", "", { "dependencies": { "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.22.0", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "loader-runner": "^4.3.2", "mime-db": "^1.54.0", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "terser-webpack-plugin": "^5.5.0", "watchpack": "^2.5.1", "webpack-sources": "^3.5.0" }, "bin": { "webpack": "bin/webpack.js" } }, "sha512-v7RhXaJbpMlV0D7hC7lb2EbnxkoeUqf9qhKr6lozx3Q48pmFrqqNRmZFUEGmi7pSwm6fCQ2H1IjvCkHqdpVdjQ=="], + "webpack": ["webpack@5.108.4", "", { "dependencies": { "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.22.2", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "graceful-fs": "^4.2.11", "loader-runner": "^4.3.2", "mime-db": "^1.54.0", "minimizer-webpack-plugin": "^5.6.1", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "watchpack": "^2.5.2", "webpack-sources": "^3.5.0" }, "peerDependencies": { "webpack-cli": "*" }, "optionalPeers": ["webpack-cli"], "bin": { "webpack": "bin/webpack.js" } }, "sha512-yur8LyJoeiWh47dErD+Ok7vlbmDsJ3UbbRPAoxbGJ54WpE2y5yVo5G/inUzujnYgw3tPmBRdn+G7PoxXaYC33w=="], "webpack-bundle-analyzer": ["webpack-bundle-analyzer@4.10.2", "", { "dependencies": { "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", "commander": "^7.2.0", "debounce": "^1.2.1", "escape-string-regexp": "^4.0.0", "gzip-size": "^6.0.0", "html-escaper": "^2.0.2", "opener": "^1.5.2", "picocolors": "^1.0.0", "sirv": "^2.0.3", "ws": "^7.3.1" }, "bin": { "webpack-bundle-analyzer": "lib/bin/analyzer.js" } }, "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw=="], "webpack-dev-middleware": ["webpack-dev-middleware@7.4.5", "", { "dependencies": { "colorette": "^2.0.10", "memfs": "^4.43.1", "mime-types": "^3.0.1", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" }, "peerDependencies": { "webpack": "^5.0.0" }, "optionalPeers": ["webpack"] }, "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA=="], - "webpack-dev-server": ["webpack-dev-server@5.2.4", "", { "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", "@types/express": "^4.17.25", "@types/express-serve-static-core": "^4.17.21", "@types/serve-index": "^1.9.4", "@types/serve-static": "^1.15.5", "@types/sockjs": "^0.3.36", "@types/ws": "^8.5.10", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.2.1", "chokidar": "^3.6.0", "colorette": "^2.0.10", "compression": "^1.8.1", "connect-history-api-fallback": "^2.0.0", "express": "^4.22.1", "graceful-fs": "^4.2.6", "http-proxy-middleware": "^2.0.9", "ipaddr.js": "^2.1.0", "launch-editor": "^2.6.1", "open": "^10.0.3", "p-retry": "^6.2.0", "schema-utils": "^4.2.0", "selfsigned": "^5.5.0", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", "webpack-dev-middleware": "^7.4.2", "ws": "^8.18.0" }, "peerDependencies": { "webpack": "^5.0.0" }, "optionalPeers": ["webpack"], "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" } }, "sha512-GqDPGZN9bRqKBTkp4aWkobDDHMsrXKoGSdOH56smIri8qR0JG8gfL8/v/f/OZR3/OKXjG8uwJbFVhKm/FNU/UA=="], + "webpack-dev-server": ["webpack-dev-server@5.2.6", "", { "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", "@types/express": "^4.17.25", "@types/express-serve-static-core": "^4.17.21", "@types/serve-index": "^1.9.4", "@types/serve-static": "^1.15.5", "@types/sockjs": "^0.3.36", "@types/ws": "^8.5.10", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.2.1", "chokidar": "^3.6.0", "colorette": "^2.0.10", "compression": "^1.8.1", "connect-history-api-fallback": "^2.0.0", "express": "^4.22.1", "graceful-fs": "^4.2.6", "http-proxy-middleware": "^2.0.9", "ipaddr.js": "^2.1.0", "launch-editor": "^2.14.1", "open": "^10.0.3", "p-retry": "^6.2.0", "schema-utils": "^4.2.0", "selfsigned": "^5.5.0", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", "webpack-dev-middleware": "^7.4.2", "ws": "^8.18.0" }, "peerDependencies": { "webpack": "^5.0.0", "webpack-cli": "*" }, "optionalPeers": ["webpack", "webpack-cli"], "bin": { "webpack-dev-server": "bin/webpack-dev-server.js" } }, "sha512-HNLRmamRvVavZQ+avceZifmv8hmdUjg43t6MI4SqJDwFdW7RPQwH5vzGhDRZSX59SgfbeHhLnq3g+uooWo7pVw=="], "webpack-merge": ["webpack-merge@5.10.0", "", { "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", "wildcard": "^2.0.0" } }, "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA=="], - "webpack-sources": ["webpack-sources@3.5.0", "", {}, "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ=="], + "webpack-sources": ["webpack-sources@3.5.1", "", {}, "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw=="], "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], @@ -2950,7 +2951,7 @@ "write-file-atomic": ["write-file-atomic@3.0.3", "", { "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q=="], - "ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], + "ws": ["ws@8.21.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw=="], "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], @@ -2994,6 +2995,8 @@ "@docusaurus/core/webpack-merge": ["webpack-merge@6.0.1", "", { "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", "wildcard": "^2.0.1" } }, "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg=="], + "@docusaurus/faster/@docusaurus/types": ["@docusaurus/types@3.10.2", "", { "dependencies": { "@mdx-js/mdx": "^3.0.0", "@types/history": "^4.7.11", "@types/mdast": "^4.0.2", "@types/react": "*", "commander": "^5.1.0", "joi": "^17.9.2", "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", "utility-types": "^3.10.0", "webpack": "^5.95.0", "webpack-merge": "^5.9.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" } }, "sha512-B6rvfwIFSapUqUJjMriZswX13K8l5Z7AcmVE6uTEJpYddQieSTR12DsGaFtcZAIDsQd4p+0WTl0Vc6jmZK0Trw=="], + "@docusaurus/utils/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], "@effect-fc/example-next/effect": ["effect@4.0.0-beta.85", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.8.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.1", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^14.0.0", "yaml": "^2.9.0" } }, "sha512-Cjv9YQyv4CiIccmRAQIWAoeESCpCpiuHYY8zb5vqiYs3Ac2yE5RQAnKq7z4Ir/3VJYZb8kxh6rS8czDDnpTdkQ=="], @@ -3012,8 +3015,6 @@ "@svgr/hast-util-to-babel-ast/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - "@types/serve-static/@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="], - "accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], "accepts/negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], @@ -3056,8 +3057,6 @@ "css-select/domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="], - "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], - "decompress-response/mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], @@ -3088,7 +3087,7 @@ "got/@sindresorhus/is": ["@sindresorhus/is@5.6.0", "", {}, "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g=="], - "gray-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], + "gray-matter/js-yaml": ["js-yaml@3.15.0", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog=="], "hpack.js/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], @@ -3238,17 +3237,17 @@ "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], - "postcss-calc/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + "postcss-calc/postcss-selector-parser": ["postcss-selector-parser@6.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ=="], - "postcss-discard-unused/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + "postcss-discard-unused/postcss-selector-parser": ["postcss-selector-parser@6.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ=="], "postcss-loader/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], - "postcss-merge-rules/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + "postcss-merge-rules/postcss-selector-parser": ["postcss-selector-parser@6.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ=="], - "postcss-minify-selectors/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + "postcss-minify-selectors/postcss-selector-parser": ["postcss-selector-parser@6.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ=="], - "postcss-unique-selectors/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + "postcss-unique-selectors/postcss-selector-parser": ["postcss-selector-parser@6.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ=="], "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], @@ -3290,12 +3289,14 @@ "strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], - "stylehacks/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + "stylehacks/postcss-selector-parser": ["postcss-selector-parser@6.1.4", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ=="], "svgo/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], "svgo/css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], + "svgo/css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="], + "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], "tsyringe/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], @@ -3312,13 +3313,13 @@ "vite-node/es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], - "vite-node/vite": ["vite@7.3.5", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww=="], + "vite-node/vite": ["vite@7.3.6", "", { "dependencies": { "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg=="], - "vitest/vite": ["vite@7.3.5", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww=="], + "vitest/vite": ["vite@7.3.6", "", { "dependencies": { "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg=="], "webpack-bundle-analyzer/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], - "webpack-bundle-analyzer/ws": ["ws@7.5.11", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA=="], + "webpack-bundle-analyzer/ws": ["ws@7.5.13", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA=="], "webpack-dev-middleware/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], @@ -3340,7 +3341,7 @@ "@docusaurus/core/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - "@effect-fc/example-next/effect/fast-check": ["fast-check@4.8.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg=="], + "@effect-fc/example-next/effect/fast-check": ["fast-check@4.9.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg=="], "@effect-fc/example-next/effect/msgpackr": ["msgpackr@2.0.4", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA=="], @@ -3372,18 +3373,10 @@ "css-select/domutils/dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="], - "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], - - "effect-fc-next/@effect/platform-browser/multipasta": ["multipasta@0.2.8", "", {}, "sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q=="], - "effect-fc-next/effect/fast-check": ["fast-check@4.9.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg=="], "effect-fc-next/effect/msgpackr": ["msgpackr@2.0.4", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA=="], - "effect-fc-next/effect/multipasta": ["multipasta@0.2.8", "", {}, "sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q=="], - - "effect-fc-next/effect/toml": ["toml@4.3.0", "", {}, "sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A=="], - "express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "file-loader/schema-utils/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], @@ -3424,6 +3417,8 @@ "serve-index/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "svgo/css-tree/mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="], + "type-is/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], "update-notifier/boxen/camelcase": ["camelcase@7.0.1", "", {}, "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw=="], @@ -3442,11 +3437,11 @@ "@docusaurus/core/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "@effect-fc/example-next/effect/fast-check/pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], + "@effect-fc/example-next/effect/fast-check/pure-rand": ["pure-rand@8.4.2", "", {}, "sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng=="], "css-select/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="], - "effect-fc-next/effect/fast-check/pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], + "effect-fc-next/effect/fast-check/pure-rand": ["pure-rand@8.4.2", "", {}, "sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng=="], "file-loader/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], diff --git a/packages/effect-fc-next/package.json b/packages/effect-fc-next/package.json index 2375e0e..91b4e19 100644 --- a/packages/effect-fc-next/package.json +++ b/packages/effect-fc-next/package.json @@ -51,6 +51,7 @@ "react": "^19.2.0" }, "dependencies": { + "@standard-schema/spec": "^1.1.0", "effect-lens": "^2.0.0-beta.1" } } diff --git a/packages/effect-fc-next/src/Form.ts b/packages/effect-fc-next/src/Form.ts index e3ce5ea..2ff3fba 100644 --- a/packages/effect-fc-next/src/Form.ts +++ b/packages/effect-fc-next/src/Form.ts @@ -1,3 +1,4 @@ +import type { StandardSchemaV1 } from "@standard-schema/spec" import { Array, type Cause, Chunk, type Duration, Effect, Equal, Function, identity, Option, Pipeable, Predicate, type Scope, Stream, SubscriptionRef } from "effect" import type * as React from "react" import * as Component from "./Component.js" @@ -8,11 +9,6 @@ import * as View from "./View.js" export const FormTypeId: unique symbol = Symbol.for("@effect-fc/Form/Form") export type FormTypeId = typeof FormTypeId -export interface FormIssue { - readonly path: readonly PropertyKey[] - readonly message: string -} - export interface Form extends Pipeable.Pipeable { readonly [FormTypeId]: FormTypeId @@ -20,8 +16,8 @@ extends Pipeable.Pipeable { readonly path: P readonly value: View.View, ER, never> readonly encodedValue: Lens.Lens - readonly issues: View.View - readonly isValidating: View.View + readonly issues: View.View + readonly isValidating: View.View readonly canCommit: View.View readonly isCommitting: View.View } @@ -34,7 +30,7 @@ extends Pipeable.Class implements Form { readonly path: P, readonly value: View.View, ER, never>, readonly encodedValue: Lens.Lens, - readonly issues: View.View, + readonly issues: View.View, readonly isValidating: View.View, readonly canCommit: View.View, readonly isCommitting: View.View, @@ -43,16 +39,17 @@ extends Pipeable.Class implements Form { } } - export const isForm = (u: unknown): u is Form => Predicate.hasProperty(u, FormTypeId) const filterIssuesByPath = ( - issues: readonly FormIssue[], + issues: readonly StandardSchemaV1.Issue[], path: readonly PropertyKey[], -): readonly FormIssue[] => Array.filter(issues, issue => - issue.path.length >= path.length && Array.every(path, (p, i) => p === issue.path[i]) -) +): readonly StandardSchemaV1.Issue[] => Array.filter(issues, issue => { + const issuePath = issue.path + if (!issuePath) return false + return issuePath.length >= path.length && Array.every(path, (p, i) => p === issuePath[i]) +}) export const focusObjectOn: {

( @@ -66,7 +63,7 @@ export const focusObjectOn: { self: Form, key: K, ): Form => { - const form = self as unknown as FormImpl + const form = self as FormImpl const path = [...form.path, key] as const return new FormImpl( @@ -92,12 +89,12 @@ export const focusArrayAt: { self: Form, index: number, ): Form => { - const form = self as unknown as FormImpl + const form = self as FormImpl const path = [...form.path, index] as const return new FormImpl( path, - View.mapOptionEffect(form.value, values => Effect.fromOption(Array.get(values, index))), + View.mapOptionEffect(form.value, value => Effect.fromOption(Array.get(value, index))), Lens.focusArrayAt(form.encodedValue, index), View.map(form.issues, issues => filterIssuesByPath(issues, path)), form.isValidating, @@ -118,12 +115,12 @@ export const focusTupleAt: { self: Form, index: K, ): Form => { - const form = self as unknown as FormImpl + const form = self as FormImpl const path = [...form.path, index] as const return new FormImpl( path, - View.mapOption(form.value, values => values[index]), + View.mapOption(form.value, Array.getUnsafe(index)), Lens.focusTupleAt(form.encodedValue, index), View.map(form.issues, issues => filterIssuesByPath(issues, path)), form.isValidating, @@ -144,12 +141,12 @@ export const focusChunkAt: { self: Form, Chunk.Chunk, ER, EW>, index: number, ): Form => { - const form = self as unknown as FormImpl, Chunk.Chunk, ER, EW> + const form = self as FormImpl, Chunk.Chunk, ER, EW> const path = [...form.path, index] as const return new FormImpl( path, - View.mapOptionEffect(form.value, values => Effect.fromOption(Chunk.get(values, index))), + View.mapOptionEffect(form.value, value => Effect.fromOption(Chunk.get(value, index))), Lens.focusChunkAt(form.encodedValue, index), View.map(form.issues, issues => filterIssuesByPath(issues, path)), form.isValidating, @@ -183,11 +180,9 @@ export const useInput = Effect.fnUntraced(function*

Effect.flatMap( - Lens.get(internalValueLens), - internalValue => !Equal.equals(upstreamEncodedValue, internalValue) - ? Lens.set(internalValueLens, upstreamEncodedValue) - : Effect.succeed(undefined), + upstreamEncodedValue => Effect.when( + Lens.set(internalValueLens, upstreamEncodedValue), + Effect.map(Lens.get(internalValueLens), internalValue => !Equal.equals(upstreamEncodedValue, internalValue)), ), ), @@ -242,11 +237,8 @@ export const useOptionalInput = Effect.fnUntraced(function*

Effect.flatMap( - Effect.all([Lens.get(enabledLens), Lens.get(internalValueLens)]), - ([enabled, internalValue]) => Equal.equals(upstreamEncodedValue, enabled ? Option.some(internalValue) : Option.none()) - ? Effect.succeed(undefined) - : Option.match(upstreamEncodedValue, { + upstreamEncodedValue => Effect.when( + Option.match(upstreamEncodedValue, { onSome: v => Effect.andThen( Lens.set(enabledLens, true), Lens.set(internalValueLens, v), @@ -256,6 +248,11 @@ export const useOptionalInput = Effect.fnUntraced(function*

!Equal.equals(upstreamEncodedValue, enabled ? Option.some(internalValue) : Option.none()), + ), ), ), diff --git a/packages/effect-fc-next/src/SubmittableForm.ts b/packages/effect-fc-next/src/SubmittableForm.ts index a08b59c..122c9a3 100644 --- a/packages/effect-fc-next/src/SubmittableForm.ts +++ b/packages/effect-fc-next/src/SubmittableForm.ts @@ -1,212 +1,213 @@ -import { - Array, - Cause, - type Context, - Effect, - Fiber, - Option, - Pipeable, - Predicate, - Schema, - SchemaIssue, - SchemaParser, - type Scope, - Semaphore, - SubscriptionRef, -} from "effect" +import type { StandardSchemaV1 } from "@standard-schema/spec" +import { Array, Cause, type Context, Effect, Fiber, Option, Pipeable, Predicate, Schema, SchemaError, SchemaIssue, type Scope, Semaphore, SubscriptionRef } from "effect" +import { AsyncResult } from "effect/unstable/reactivity" import * as Form from "./Form.js" import * as Lens from "./Lens.js" import * as Mutation from "./Mutation.js" -import * as Result from "./Result.js" import * as View from "./View.js" -type FormSchema = Schema.Top & { - readonly Type: A - readonly Encoded: I - readonly DecodingServices: R -} - export const SubmittableFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SubmittableForm") export type SubmittableFormTypeId = typeof SubmittableFormTypeId -export interface SubmittableForm +export interface SubmittableForm extends Form.Form { readonly [SubmittableFormTypeId]: SubmittableFormTypeId - readonly schema: FormSchema + + readonly schema: Schema.ConstraintCodec readonly context: Context.Context readonly mutation: Mutation.Mutation< readonly [value: A, form: SubmittableForm], - MA, ME, MR, MP + MA, ME, MR > - readonly validationFiber: View.View>, never, never> + readonly validationFiber: View.View>, never, never> + readonly run: Effect.Effect - readonly submit: Effect.Effect>, Cause.NoSuchElementError> + readonly submit: Effect.Effect | AsyncResult.Failure>, Cause.NoSuchElementError> } -export class SubmittableFormImpl -extends Pipeable.Class implements SubmittableForm { +export class SubmittableFormImpl +extends Pipeable.Class implements SubmittableForm { readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId readonly [SubmittableFormTypeId]: SubmittableFormTypeId = SubmittableFormTypeId + readonly path = [] as const + readonly encodedValue: Lens.Lens readonly isValidating: View.View readonly canCommit: View.View readonly isCommitting: View.View constructor( - readonly schema: FormSchema, + readonly schema: Schema.ConstraintCodec, readonly context: Context.Context, readonly mutation: Mutation.Mutation< readonly [value: A, form: SubmittableForm], - MA, ME, MR, MP + MA, ME, MR >, readonly value: Lens.Lens, never, never, never, never>, readonly internalEncodedValue: Lens.Lens, - readonly issues: Lens.Lens, - readonly validationFiber: Lens.Lens>, never, never, never, never>, + readonly issues: Lens.Lens, + readonly validationFiber: Lens.Lens>, never, never, never, never>, + readonly runSemaphore: Semaphore.Semaphore, ) { super() - this.encodedValue = Lens.make({ - get: Lens.get(internalEncodedValue), - changes: internalEncodedValue.changes, - commit: encoded => Effect.andThen( - Lens.set(internalEncodedValue, encoded), - this.synchronizeEncodedValue(encoded), - ), - lock: Lens.asLensImpl(internalEncodedValue).lock, - }) - this.isValidating = View.map(validationFiber, Option.isSome) - const commitState = View.zipLatestAll( - value as any, - issues as any, - validationFiber as any, - mutation.result as any, - ) as unknown as View.View, - readonly Form.FormIssue[], - Option.Option>, - Result.Result, - ]> - this.canCommit = View.map( - commitState, - ([current, currentIssues, fiber, result]: readonly [Option.Option, readonly Form.FormIssue[], Option.Option>, Result.Result]) => Option.isSome(current) - && currentIssues.length === 0 - && Option.isNone(fiber) - && !(Result.isRunning(result) || Result.hasRefreshingFlag(result)), - ) - this.isCommitting = View.map( - mutation.result, - result => Result.isRunning(result) || Result.hasRefreshingFlag(result), - ) - } - synchronizeEncodedValue(encodedValue: I): Effect.Effect { - const self = this - return Effect.gen(function*() { - const current = yield* Lens.get(self.validationFiber) - if (Option.isSome(current)) yield* Fiber.interrupt(current.value) - const fiber = yield* Effect.forkScoped( - Effect.ensuring( - SchemaParser.decodeEffect(self.schema)(encodedValue), - Lens.set(self.validationFiber, Option.none()), + this.encodedValue = Effect.all([ + Effect.succeed(this), + Effect.succeed(Lens.asLensImpl(this.internalEncodedValue)), + ]).pipe( + Effect.map(([self, parent]) => Lens.make({ + get: parent.get, + get changes() { return parent.changes }, + commit: a => Effect.andThen( + Effect.flatMap( + parent.resolve, + resolved => resolved.commit(Effect.succeed(a)), + ), + self.synchronizeEncodedValue(a), ), - ) - yield* Lens.set(self.validationFiber, Option.some(fiber)) - const decoded = yield* Fiber.join(fiber).pipe( - Effect.tap(value => Effect.andThen( - Lens.set(self.issues, Array.empty()), - Lens.set(self.value, Option.some(value)), - )), - Effect.catchIf(SchemaIssue.isIssue, issue => Lens.set(self.issues, formatIssue(issue))), - ) - void decoded - }).pipe(Effect.provide(this.context)) as Effect.Effect + lock: parent.lock, + })), + Lens.unwrap, + ) + this.isValidating = Effect.succeed(this).pipe( + Effect.map(self => View.map(self.validationFiber, Option.isSome)), + View.unwrap, + ) + this.canCommit = Effect.succeed(this).pipe( + Effect.map(self => View.map( + View.zipLatestAll(self.value, self.issues, self.validationFiber, self.mutation.state), + ([value, issues, validationFiber, result]) => ( + Option.isSome(value) && + Array.isReadonlyArrayEmpty(issues) && + Option.isNone(validationFiber) && + !AsyncResult.isWaiting(result) + ), + )), + View.unwrap, + ) + this.isCommitting = Effect.succeed(this).pipe( + Effect.map(self => View.map(self.mutation.state, AsyncResult.isWaiting)), + View.unwrap, + ) } - get run(): Effect.Effect { - return Effect.flatMap( - Lens.get(this.encodedValue), - SchemaParser.decodeEffect(this.schema), - ).pipe( + synchronizeEncodedValue(encodedValue: I): Effect.Effect { + return Lens.get(this.validationFiber).pipe( + Effect.andThen(Option.match({ + onSome: Fiber.interrupt, + onNone: () => Effect.void, + })), + Effect.andThen(Effect.forkScoped( + Effect.ensuring( + Schema.decodeEffect(this.schema, { errors: "all" })(encodedValue), + Lens.set(this.validationFiber, Option.none()), + ) + )), + Effect.tap(fiber => Lens.set(this.validationFiber, Option.some(fiber))), + Effect.flatMap(Fiber.join), + + Effect.tap(() => Lens.set(this.issues, Array.empty())), + Effect.flatMap(value => Lens.set(this.value, Option.some(value))), + Effect.catchIf( + SchemaError.isSchemaError, + error => Lens.set(this.issues, SchemaIssue.makeFormatterStandardSchemaV1()(error.issue).issues), + ), + + Effect.provide(this.context), + ) + } + + get run(): Effect.Effect { + return Lens.get(this.encodedValue).pipe( + Effect.flatMap(v => Schema.decodeEffect(this.schema)(v)), Effect.option, - Effect.flatMap(value => Lens.set(this.value, value)), + Effect.flatMap(v => Lens.set(this.value, v)), Effect.provide(this.context), this.runSemaphore.withPermits(1), ) } - get submit(): Effect.Effect>, Cause.NoSuchElementError> { - return Effect.flatMap(Lens.get(this.value), value => Effect.flatMap(Effect.fromOption(value), decoded => this.submitValue(decoded))) + get submit(): Effect.Effect | AsyncResult.Failure>, Cause.NoSuchElementError, never> { + return Lens.get(this.value).pipe( + Effect.flatMap(Effect.fromOption), + Effect.flatMap(value => this.submitValue(value)), + ) } - submitValue(value: A): Effect.Effect>> { - return Effect.flatMap(this.canCommit.get, canCommit => { - if (!canCommit) return Effect.succeed(Option.none()) - return Effect.map( - Effect.tap(this.mutation.mutate([value, this as any]), result => { - if (!Result.isFailure(result)) return Effect.succeed(undefined) - const issue = Cause.findErrorOption(result.cause) - return Option.isSome(issue) && SchemaIssue.isIssue(issue.value) - ? Lens.set(this.issues, formatIssue(issue.value)) - : Effect.succeed(undefined) - }), - Option.some, - ) - }) + submitValue(value: A): Effect.Effect | AsyncResult.Failure>, never, never> { + return Effect.when( + Effect.tap( + this.mutation.mutate([value, this as any]), + result => AsyncResult.isFailure(result) + ? Option.match( + Array.findFirst( + result.cause.reasons, + reason => Cause.isFailReason(reason) && SchemaError.isSchemaError(reason.error) + ? Option.some(reason.error) + : Option.none(), + ), + { + onSome: error => Lens.set(this.issues, SchemaIssue.makeFormatterStandardSchemaV1()(error.issue).issues), + onNone: () => Effect.void, + }, + ) + : Effect.void, + ), + View.get(this.canCommit), + ) } } -const formatIssue = (issue: SchemaIssue.Issue): readonly Form.FormIssue[] => { - const formatted = SchemaIssue.makeFormatterStandardSchemaV1()(issue) - return formatted.issues.map(item => ({ - path: (item.path ?? []) as readonly PropertyKey[], - message: item.message, - })) -} +export const isSubmittableForm = (u: unknown): u is SubmittableForm => Predicate.hasProperty(u, SubmittableFormTypeId) -export const isSubmittableForm = (u: unknown): u is SubmittableForm => Predicate.hasProperty(u, SubmittableFormTypeId) export declare namespace make { - export interface Options + export interface Options extends Mutation.make.Options< readonly [value: NoInfer, form: SubmittableForm, NoInfer, NoInfer, unknown, unknown, unknown>], - MA, ME, MR, MP + MA, ME, MR > { - readonly schema: FormSchema + readonly schema: Schema.ConstraintCodec readonly initialEncodedValue: NoInfer } } -export const make = Effect.fnUntraced(function* ( - options: make.Options, +export const make = Effect.fnUntraced(function* ( + options: make.Options ): Effect.fn.Return< - SubmittableForm, MP>, + SubmittableForm, never, - Scope.Scope | R | Result.forkEffect.OutputContext + Scope.Scope | R | MR > { return new SubmittableFormImpl( options.schema, - yield* Effect.context(), + yield* Effect.context(), yield* Mutation.make(options), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none())), Lens.fromSubscriptionRef(yield* SubscriptionRef.make(options.initialEncodedValue)), - Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Array.empty())), - Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Array.empty())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), + yield* Semaphore.make(1), ) }) export declare namespace service { - export interface Options - extends make.Options {} + export interface Options + extends make.Options {} } export const service = ( - options: service.Options, + options: service.Options ): Effect.Effect< - SubmittableForm, MP>, + SubmittableForm, never, - Scope.Scope | R | Result.forkEffect.OutputContext -> => Effect.tap(make(options), form => Effect.asVoid(Effect.forkScoped(form.run))) + Scope.Scope | R | MR +> => Effect.tap( + make(options), + form => Effect.forkScoped(form.run), +) -- 2.52.0 From feced4732f49d1f15b8ec77e5c853b0231f86949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 19 Jul 2026 02:43:48 +0200 Subject: [PATCH 53/61] Refactor Form subtypes --- .../effect-fc-next/src/SubmittableForm.ts | 46 +-- .../effect-fc-next/src/SynchronizedForm.ts | 272 +++++++++--------- 2 files changed, 160 insertions(+), 158 deletions(-) diff --git a/packages/effect-fc-next/src/SubmittableForm.ts b/packages/effect-fc-next/src/SubmittableForm.ts index 122c9a3..0ba9a56 100644 --- a/packages/effect-fc-next/src/SubmittableForm.ts +++ b/packages/effect-fc-next/src/SubmittableForm.ts @@ -10,14 +10,14 @@ import * as View from "./View.js" export const SubmittableFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SubmittableForm") export type SubmittableFormTypeId = typeof SubmittableFormTypeId -export interface SubmittableForm +export interface SubmittableForm extends Form.Form { readonly [SubmittableFormTypeId]: SubmittableFormTypeId - readonly schema: Schema.ConstraintCodec - readonly context: Context.Context + readonly schema: Schema.ConstraintCodec + readonly context: Context.Context readonly mutation: Mutation.Mutation< - readonly [value: A, form: SubmittableForm], + readonly [value: A, form: SubmittableForm], MA, ME, MR > readonly validationFiber: View.View>, never, never> @@ -26,8 +26,8 @@ extends Form.Form { readonly submit: Effect.Effect | AsyncResult.Failure>, Cause.NoSuchElementError> } -export class SubmittableFormImpl -extends Pipeable.Class implements SubmittableForm { +export class SubmittableFormImpl +extends Pipeable.Class implements SubmittableForm { readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId readonly [SubmittableFormTypeId]: SubmittableFormTypeId = SubmittableFormTypeId @@ -39,10 +39,10 @@ extends Pipeable.Class implements SubmittableForm { readonly isCommitting: View.View constructor( - readonly schema: Schema.ConstraintCodec, - readonly context: Context.Context, + readonly schema: Schema.ConstraintCodec, + readonly context: Context.Context, readonly mutation: Mutation.Mutation< - readonly [value: A, form: SubmittableForm], + readonly [value: A, form: SubmittableForm], MA, ME, MR >, readonly value: Lens.Lens, never, never, never, never>, @@ -165,26 +165,26 @@ export const isSubmittableForm = (u: unknown): u is SubmittableForm + export interface Options extends Mutation.make.Options< - readonly [value: NoInfer, form: SubmittableForm, NoInfer, NoInfer, unknown, unknown, unknown>], + readonly [value: NoInfer, form: SubmittableForm, NoInfer, NoInfer, NoInfer, unknown, unknown, unknown>], MA, ME, MR > { - readonly schema: Schema.ConstraintCodec + readonly schema: Schema.ConstraintCodec readonly initialEncodedValue: NoInfer } } -export const make = Effect.fnUntraced(function* ( - options: make.Options +export const make = Effect.fnUntraced(function* ( + options: make.Options ): Effect.fn.Return< - SubmittableForm, + SubmittableForm, never, - Scope.Scope | R | MR + Scope.Scope | RD | RE | MR > { return new SubmittableFormImpl( options.schema, - yield* Effect.context(), + yield* Effect.context(), yield* Mutation.make(options), Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none())), @@ -197,16 +197,16 @@ export const make = Effect.fnUntraced(function* - extends make.Options {} + export interface Options + extends make.Options {} } -export const service = ( - options: service.Options +export const service = ( + options: service.Options ): Effect.Effect< - SubmittableForm, + SubmittableForm, never, - Scope.Scope | R | MR + Scope.Scope | RD | RE | MR > => Effect.tap( make(options), form => Effect.forkScoped(form.run), diff --git a/packages/effect-fc-next/src/SynchronizedForm.ts b/packages/effect-fc-next/src/SynchronizedForm.ts index 96d6915..4cccb9f 100644 --- a/packages/effect-fc-next/src/SynchronizedForm.ts +++ b/packages/effect-fc-next/src/SynchronizedForm.ts @@ -1,204 +1,206 @@ -import { - Array, - type Context, - Effect, - Equal, - Fiber, - Option, - Pipeable, - Predicate, - Schema, - SchemaIssue, - SchemaParser, - type Scope, - Semaphore, - Stream, - SubscriptionRef, -} from "effect" +import type { StandardSchemaV1 } from "@standard-schema/spec" +import { Array, type Context, Effect, Equal, Fiber, Option, Pipeable, Predicate, Schema, SchemaIssue, type Scope, Semaphore, Stream, SubscriptionRef } from "effect" import * as Form from "./Form.js" import * as Lens from "./Lens.js" import * as View from "./View.js" -type FormSchema = Schema.Top & { - readonly Type: A - readonly Encoded: I - readonly DecodingServices: R - readonly EncodingServices: R -} - export const SynchronizedFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SynchronizedForm") export type SynchronizedFormTypeId = typeof SynchronizedFormTypeId -export interface SynchronizedForm< - in out A, - in out I = A, - in out R = never, - in out TER = never, - in out TEW = never, - in out TRR = never, - in out TRW = never, -> extends Form.Form { +export interface SynchronizedForm +extends Form.Form { readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId - readonly schema: FormSchema - readonly context: Context.Context + + readonly schema: Schema.ConstraintCodec + readonly context: Context.Context readonly target: Lens.Lens - readonly validationFiber: View.View>, never, never> + readonly validationFiber: View.View>, never, never> + readonly run: Effect.Effect } -export class SynchronizedFormImpl< - in out A, - in out I = A, - in out R = never, - in out TER = never, - in out TEW = never, - in out TRR = never, - in out TRW = never, -> extends Pipeable.Class implements SynchronizedForm { +export class SynchronizedFormImpl +extends Pipeable.Class implements SynchronizedForm { readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId = SynchronizedFormTypeId + readonly path = [] as const - readonly value: View.View, TER, never> + + readonly value: View.View, never, never> readonly encodedValue: Lens.Lens readonly isValidating: View.View readonly canCommit: View.View constructor( - readonly schema: FormSchema, - readonly context: Context.Context, + readonly schema: Schema.ConstraintCodec, + readonly context: Context.Context, readonly target: Lens.Lens, + readonly internalEncodedValue: Lens.Lens, - readonly issues: Lens.Lens, - readonly validationFiber: Lens.Lens>, never, never, never, never>, - readonly isCommitting: Lens.Lens, + readonly issues: Lens.Lens, + readonly validationFiber: Lens.Lens>, never, never, never, never>, + readonly isCommitting: Lens.Lens, + readonly runSemaphore: Semaphore.Semaphore, ) { super() - this.value = View.make({ - get: Effect.provide(Effect.map(target.get, Option.some), context), - changes: Stream.provideContext( - target.changes.pipe( - Stream.map(Option.some), - Stream.catchCause(() => Stream.make(Option.none())), + + this.value = Effect.succeed(this).pipe( + Effect.map(self => View.make({ + get: Effect.provide(Effect.option(self.target.get), self.context), + get changes() { + return Stream.provideContext( + self.target.changes.pipe( + Stream.map(Option.some), + Stream.catch(() => Stream.make(Option.none())), + ), + self.context, + ) + }, + })), + View.unwrap, + ) + this.encodedValue = Effect.all([ + Effect.succeed(this), + Effect.succeed(Lens.asLensImpl(this.internalEncodedValue)), + ]).pipe( + Effect.map(([self, parent]) => Lens.make({ + get: parent.get, + get changes() { return parent.changes }, + commit: a => Effect.andThen( + Effect.flatMap( + parent.resolve, + resolved => resolved.commit(Effect.succeed(a)), + ), + self.synchronizeEncodedValue(a), ), - context, - ), - }) - this.encodedValue = Lens.make({ - get: Lens.get(internalEncodedValue), - changes: internalEncodedValue.changes, - commit: encoded => Effect.andThen( - Lens.set(internalEncodedValue, encoded), - this.synchronizeEncodedValue(encoded), - ), - lock: Lens.asLensImpl(internalEncodedValue).lock, - }) as unknown as Lens.Lens - this.isValidating = View.map(validationFiber, Option.isSome) - const commitState = View.zipLatestAll(issues as any, validationFiber as any, isCommitting as any) as unknown as View.View>, - boolean, - ]> - this.canCommit = View.map( - commitState, - ([currentIssues, fiber, committing]) => currentIssues.length === 0 && Option.isNone(fiber) && !committing, + lock: parent.lock, + })), + Lens.unwrap, + ) + this.isValidating = Effect.succeed(this).pipe( + Effect.map(self => View.map(self.validationFiber, Option.isSome)), + View.unwrap, + ) + this.canCommit = Effect.succeed(this).pipe( + Effect.map(self => View.map( + View.zipLatestAll(self.issues, self.validationFiber, self.isCommitting), + ([issues, validationFiber, isCommitting]) => ( + Array.isReadonlyArrayEmpty(issues) && + Option.isNone(validationFiber) && + !isCommitting + ), + )), + View.unwrap, ) } - synchronizeEncodedValue(encodedValue: I): Effect.Effect { - const self = this - return Effect.gen(function*() { - const current = yield* Lens.get(self.validationFiber) - if (Option.isSome(current)) yield* Fiber.interrupt(current.value) - const fiber = yield* Effect.forkScoped( + synchronizeEncodedValue(encodedValue: I): Effect.Effect { + return Lens.get(this.validationFiber).pipe( + Effect.andThen(Option.match({ + onSome: Fiber.interrupt, + onNone: () => Effect.void, + })), + Effect.andThen(Effect.forkScoped( Effect.ensuring( - SchemaParser.decodeEffect(self.schema)(encodedValue), - Lens.set(self.validationFiber, Option.none()), + Schema.decodeEffect(this.schema, { errors: "all" })(encodedValue), + Lens.set(this.validationFiber, Option.none()), + ) + )), + Effect.tap(fiber => Lens.set(this.validationFiber, Option.some(fiber))), + Effect.flatMap(Fiber.join), + + Effect.flatMap(value => Effect.ensuring( + Lens.set(this.isCommitting, true).pipe( + Effect.andThen(Lens.set(this.issues, Array.empty())), + Effect.andThen(Lens.set(this.target, value)), ), - ) - yield* Lens.set(self.validationFiber, Option.some(fiber)) - yield* Fiber.join(fiber).pipe( - Effect.flatMap(value => Effect.ensuring( - Effect.andThen( - Lens.set(self.isCommitting, true), - Effect.andThen(Lens.set(self.issues, Array.empty()), Lens.set(self.target, value)), - ), - Lens.set(self.isCommitting, false), - )), - Effect.catchIf(SchemaIssue.isIssue, issue => Lens.set(self.issues, formatIssue(issue))), - ) - }).pipe(Effect.provide(this.context)) as Effect.Effect + Lens.set(this.isCommitting, false), + )), + Effect.catchIf( + Schema.isSchemaError, + error => Lens.set(this.issues, SchemaIssue.makeFormatterStandardSchemaV1()(error.issue).issues), + ), + + Effect.provide(this.context), + ) } - get run(): Effect.Effect { + get run(): Effect.Effect { return this.runSemaphore.withPermits(1)(Effect.provide( - Stream.runForEach(Stream.drop(this.target.changes, 1), targetValue => Effect.ignore( - Effect.flatMap(SchemaParser.encodeEffect(this.schema)(targetValue), encodedValue => Effect.flatMap( - Lens.get(this.internalEncodedValue), - current => Equal.equals(encodedValue, current) - ? Effect.succeed(undefined) - : Effect.andThen( + Stream.runForEach( + Stream.drop(Lens.changes(this.target), 1), + targetValue => Schema.encodeEffect(this.schema, { errors: "all" })(targetValue).pipe( + Effect.flatMap(encodedValue => Effect.when( + Effect.andThen( Lens.set(this.issues, Array.empty()), Lens.set(this.internalEncodedValue, encodedValue), ), - )), - )), + Effect.map( + Lens.get(this.internalEncodedValue), + currentEncodedValue => !Equal.equals(encodedValue, currentEncodedValue), + ), + )), + Effect.ignore, + ), + ), this.context, )) } } -const formatIssue = (issue: SchemaIssue.Issue): readonly Form.FormIssue[] => { - const formatted = SchemaIssue.makeFormatterStandardSchemaV1()(issue) - return formatted.issues.map(item => ({ - path: (item.path ?? []) as readonly PropertyKey[], - message: item.message, - })) -} - export const isSynchronizedForm = (u: unknown): u is SynchronizedForm => Predicate.hasProperty(u, SynchronizedFormTypeId) + export declare namespace make { - export interface Options { - readonly schema: FormSchema + export interface Options { + readonly schema: Schema.ConstraintCodec readonly target: Lens.Lens readonly initialEncodedValue?: NoInfer } } -export const make = Effect.fnUntraced(function* ( - options: make.Options, +export const make = Effect.fnUntraced(function* ( + options: make.Options ): Effect.fn.Return< - SynchronizedForm, - SchemaIssue.Issue | TER, - Scope.Scope | R | TRR | TRW + SynchronizedForm, + Schema.SchemaError | TER, + Scope.Scope | RD | RE | TRR | TRW > { const initialEncodedValue = options.initialEncodedValue !== undefined ? options.initialEncodedValue - : yield* Effect.flatMap(Lens.get(options.target), SchemaParser.encodeEffect(options.schema)) + : yield* Effect.flatMap( + Lens.get(options.target), + Schema.encodeEffect(options.schema), + ) return new SynchronizedFormImpl( options.schema, - yield* Effect.context(), + yield* Effect.context(), options.target, + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(initialEncodedValue)), - Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Array.empty())), - Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Array.empty())), + Lens.fromSubscriptionRef(yield* SubscriptionRef.make(Option.none>())), Lens.fromSubscriptionRef(yield* SubscriptionRef.make(false)), + yield* Semaphore.make(1), ) }) export declare namespace service { - export interface Options - extends make.Options {} + export interface Options + extends make.Options {} } -export const service = ( - options: service.Options, +export const service = ( + options: service.Options ): Effect.Effect< - SynchronizedForm, - SchemaIssue.Issue | TER, - Scope.Scope | R | TRR | TRW -> => Effect.tap(make(options), form => Effect.asVoid(Effect.forkScoped(form.run))) + SynchronizedForm, + Schema.SchemaError | TER, + Scope.Scope | RD | RE | TRR | TRW +> => Effect.tap( + make(options), + form => Effect.forkScoped(form.run), +) -- 2.52.0 From 985556b4303001516ac3710ff19e0ecb793c2d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 19 Jul 2026 02:50:37 +0200 Subject: [PATCH 54/61] Fix --- packages/effect-fc-next/src/Form.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/effect-fc-next/src/Form.ts b/packages/effect-fc-next/src/Form.ts index 2ff3fba..c76f3b8 100644 --- a/packages/effect-fc-next/src/Form.ts +++ b/packages/effect-fc-next/src/Form.ts @@ -179,7 +179,7 @@ export const useInput = Effect.fnUntraced(function*

Effect.when( Lens.set(internalValueLens, upstreamEncodedValue), Effect.map(Lens.get(internalValueLens), internalValue => !Equal.equals(upstreamEncodedValue, internalValue)), @@ -187,7 +187,7 @@ export const useInput = Effect.fnUntraced(function*

Effect.when( Option.match(upstreamEncodedValue, { @@ -257,7 +257,7 @@ export const useOptionalInput = Effect.fnUntraced(function*

Date: Sun, 19 Jul 2026 02:56:32 +0200 Subject: [PATCH 55/61] Fix --- packages/effect-fc-next/src/Form.ts | 6 +++--- packages/effect-fc-next/src/SubmittableForm.ts | 10 +++++----- packages/effect-fc-next/src/SynchronizedForm.ts | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/effect-fc-next/src/Form.ts b/packages/effect-fc-next/src/Form.ts index c76f3b8..ce404eb 100644 --- a/packages/effect-fc-next/src/Form.ts +++ b/packages/effect-fc-next/src/Form.ts @@ -9,7 +9,7 @@ import * as View from "./View.js" export const FormTypeId: unique symbol = Symbol.for("@effect-fc/Form/Form") export type FormTypeId = typeof FormTypeId -export interface Form +export interface Form extends Pipeable.Pipeable { readonly [FormTypeId]: FormTypeId @@ -22,7 +22,7 @@ extends Pipeable.Pipeable { readonly isCommitting: View.View } -export class FormImpl +export class FormImpl extends Pipeable.Class implements Form { readonly [FormTypeId]: FormTypeId = FormTypeId @@ -39,7 +39,7 @@ extends Pipeable.Class implements Form { } } -export const isForm = (u: unknown): u is Form => Predicate.hasProperty(u, FormTypeId) +export const isForm = (u: unknown): u is Form => Predicate.hasProperty(u, FormTypeId) const filterIssuesByPath = ( diff --git a/packages/effect-fc-next/src/SubmittableForm.ts b/packages/effect-fc-next/src/SubmittableForm.ts index 0ba9a56..68604d7 100644 --- a/packages/effect-fc-next/src/SubmittableForm.ts +++ b/packages/effect-fc-next/src/SubmittableForm.ts @@ -10,7 +10,7 @@ import * as View from "./View.js" export const SubmittableFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SubmittableForm") export type SubmittableFormTypeId = typeof SubmittableFormTypeId -export interface SubmittableForm +export interface SubmittableForm extends Form.Form { readonly [SubmittableFormTypeId]: SubmittableFormTypeId @@ -26,7 +26,7 @@ extends Form.Form { readonly submit: Effect.Effect | AsyncResult.Failure>, Cause.NoSuchElementError> } -export class SubmittableFormImpl +export class SubmittableFormImpl extends Pipeable.Class implements SubmittableForm { readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId readonly [SubmittableFormTypeId]: SubmittableFormTypeId = SubmittableFormTypeId @@ -161,11 +161,11 @@ extends Pipeable.Class implements SubmittableForm { } } -export const isSubmittableForm = (u: unknown): u is SubmittableForm => Predicate.hasProperty(u, SubmittableFormTypeId) +export const isSubmittableForm = (u: unknown): u is SubmittableForm => Predicate.hasProperty(u, SubmittableFormTypeId) export declare namespace make { - export interface Options + export interface Options extends Mutation.make.Options< readonly [value: NoInfer, form: SubmittableForm, NoInfer, NoInfer, NoInfer, unknown, unknown, unknown>], MA, ME, MR @@ -197,7 +197,7 @@ export const make = Effect.fnUntraced(function* + export interface Options extends make.Options {} } diff --git a/packages/effect-fc-next/src/SynchronizedForm.ts b/packages/effect-fc-next/src/SynchronizedForm.ts index 4cccb9f..6af4f58 100644 --- a/packages/effect-fc-next/src/SynchronizedForm.ts +++ b/packages/effect-fc-next/src/SynchronizedForm.ts @@ -8,7 +8,7 @@ import * as View from "./View.js" export const SynchronizedFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SynchronizedForm") export type SynchronizedFormTypeId = typeof SynchronizedFormTypeId -export interface SynchronizedForm +export interface SynchronizedForm extends Form.Form { readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId @@ -20,7 +20,7 @@ extends Form.Form { readonly run: Effect.Effect } -export class SynchronizedFormImpl +export class SynchronizedFormImpl extends Pipeable.Class implements SynchronizedForm { readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId = SynchronizedFormTypeId @@ -150,11 +150,11 @@ extends Pipeable.Class implements SynchronizedForm => Predicate.hasProperty(u, SynchronizedFormTypeId) +export const isSynchronizedForm = (u: unknown): u is SynchronizedForm => Predicate.hasProperty(u, SynchronizedFormTypeId) export declare namespace make { - export interface Options { + export interface Options { readonly schema: Schema.ConstraintCodec readonly target: Lens.Lens readonly initialEncodedValue?: NoInfer @@ -190,7 +190,7 @@ export const make = Effect.fnUntraced(function* + export interface Options extends make.Options {} } -- 2.52.0 From be1038fc8d5534761de151408fa3317bdbd8f7d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 19 Jul 2026 03:01:38 +0200 Subject: [PATCH 56/61] Rename Form subtypes --- .../src/{SynchronizedForm.ts => LensForm.ts} | 22 +++++++-------- .../{SubmittableForm.ts => MutationForm.ts} | 28 +++++++++---------- packages/effect-fc-next/src/index.ts | 4 +-- 3 files changed, 27 insertions(+), 27 deletions(-) rename packages/effect-fc-next/src/{SynchronizedForm.ts => LensForm.ts} (87%) rename packages/effect-fc-next/src/{SubmittableForm.ts => MutationForm.ts} (85%) diff --git a/packages/effect-fc-next/src/SynchronizedForm.ts b/packages/effect-fc-next/src/LensForm.ts similarity index 87% rename from packages/effect-fc-next/src/SynchronizedForm.ts rename to packages/effect-fc-next/src/LensForm.ts index 6af4f58..576b486 100644 --- a/packages/effect-fc-next/src/SynchronizedForm.ts +++ b/packages/effect-fc-next/src/LensForm.ts @@ -5,12 +5,12 @@ import * as Lens from "./Lens.js" import * as View from "./View.js" -export const SynchronizedFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SynchronizedForm") -export type SynchronizedFormTypeId = typeof SynchronizedFormTypeId +export const LensFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/LensForm") +export type LensFormTypeId = typeof LensFormTypeId -export interface SynchronizedForm +export interface LensForm extends Form.Form { - readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId + readonly [LensFormTypeId]: LensFormTypeId readonly schema: Schema.ConstraintCodec readonly context: Context.Context @@ -20,10 +20,10 @@ extends Form.Form { readonly run: Effect.Effect } -export class SynchronizedFormImpl -extends Pipeable.Class implements SynchronizedForm { +export class LensFormImpl +extends Pipeable.Class implements LensForm { readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId - readonly [SynchronizedFormTypeId]: SynchronizedFormTypeId = SynchronizedFormTypeId + readonly [LensFormTypeId]: LensFormTypeId = LensFormTypeId readonly path = [] as const @@ -150,7 +150,7 @@ extends Pipeable.Class implements SynchronizedForm => Predicate.hasProperty(u, SynchronizedFormTypeId) +export const isLensForm = (u: unknown): u is LensForm => Predicate.hasProperty(u, LensFormTypeId) export declare namespace make { @@ -164,7 +164,7 @@ export declare namespace make { export const make = Effect.fnUntraced(function* ( options: make.Options ): Effect.fn.Return< - SynchronizedForm, + LensForm, Schema.SchemaError | TER, Scope.Scope | RD | RE | TRR | TRW > { @@ -175,7 +175,7 @@ export const make = Effect.fnUntraced(function* (), options.target, @@ -197,7 +197,7 @@ export declare namespace service { export const service = ( options: service.Options ): Effect.Effect< - SynchronizedForm, + LensForm, Schema.SchemaError | TER, Scope.Scope | RD | RE | TRR | TRW > => Effect.tap( diff --git a/packages/effect-fc-next/src/SubmittableForm.ts b/packages/effect-fc-next/src/MutationForm.ts similarity index 85% rename from packages/effect-fc-next/src/SubmittableForm.ts rename to packages/effect-fc-next/src/MutationForm.ts index 68604d7..55d5ebc 100644 --- a/packages/effect-fc-next/src/SubmittableForm.ts +++ b/packages/effect-fc-next/src/MutationForm.ts @@ -7,17 +7,17 @@ import * as Mutation from "./Mutation.js" import * as View from "./View.js" -export const SubmittableFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/SubmittableForm") -export type SubmittableFormTypeId = typeof SubmittableFormTypeId +export const MutationFormTypeId: unique symbol = Symbol.for("@effect-fc/Form/MutationForm") +export type MutationFormTypeId = typeof MutationFormTypeId -export interface SubmittableForm +export interface MutationForm extends Form.Form { - readonly [SubmittableFormTypeId]: SubmittableFormTypeId + readonly [MutationFormTypeId]: MutationFormTypeId readonly schema: Schema.ConstraintCodec readonly context: Context.Context readonly mutation: Mutation.Mutation< - readonly [value: A, form: SubmittableForm], + readonly [value: A, form: MutationForm], MA, ME, MR > readonly validationFiber: View.View>, never, never> @@ -26,10 +26,10 @@ extends Form.Form { readonly submit: Effect.Effect | AsyncResult.Failure>, Cause.NoSuchElementError> } -export class SubmittableFormImpl -extends Pipeable.Class implements SubmittableForm { +export class MutationFormImpl +extends Pipeable.Class implements MutationForm { readonly [Form.FormTypeId]: Form.FormTypeId = Form.FormTypeId - readonly [SubmittableFormTypeId]: SubmittableFormTypeId = SubmittableFormTypeId + readonly [MutationFormTypeId]: MutationFormTypeId = MutationFormTypeId readonly path = [] as const @@ -42,7 +42,7 @@ extends Pipeable.Class implements SubmittableForm { readonly schema: Schema.ConstraintCodec, readonly context: Context.Context, readonly mutation: Mutation.Mutation< - readonly [value: A, form: SubmittableForm], + readonly [value: A, form: MutationForm], MA, ME, MR >, readonly value: Lens.Lens, never, never, never, never>, @@ -161,13 +161,13 @@ extends Pipeable.Class implements SubmittableForm { } } -export const isSubmittableForm = (u: unknown): u is SubmittableForm => Predicate.hasProperty(u, SubmittableFormTypeId) +export const isMutationForm = (u: unknown): u is MutationForm => Predicate.hasProperty(u, MutationFormTypeId) export declare namespace make { export interface Options extends Mutation.make.Options< - readonly [value: NoInfer, form: SubmittableForm, NoInfer, NoInfer, NoInfer, unknown, unknown, unknown>], + readonly [value: NoInfer, form: MutationForm, NoInfer, NoInfer, NoInfer, unknown, unknown, unknown>], MA, ME, MR > { readonly schema: Schema.ConstraintCodec @@ -178,11 +178,11 @@ export declare namespace make { export const make = Effect.fnUntraced(function* ( options: make.Options ): Effect.fn.Return< - SubmittableForm, + MutationForm, never, Scope.Scope | RD | RE | MR > { - return new SubmittableFormImpl( + return new MutationFormImpl( options.schema, yield* Effect.context(), yield* Mutation.make(options), @@ -204,7 +204,7 @@ export declare namespace service { export const service = ( options: service.Options ): Effect.Effect< - SubmittableForm, + MutationForm, never, Scope.Scope | RD | RE | MR > => Effect.tap( diff --git a/packages/effect-fc-next/src/index.ts b/packages/effect-fc-next/src/index.ts index ca7e03d..b114c1c 100644 --- a/packages/effect-fc-next/src/index.ts +++ b/packages/effect-fc-next/src/index.ts @@ -3,8 +3,10 @@ export * as Component from "./Component.js" export * as ErrorObserver from "./ErrorObserver.js" export * as Form from "./Form.js" export * as Lens from "./Lens.js" +export * as LensForm from "./LensForm.js" export * as Memoized from "./Memoized.js" export * as Mutation from "./Mutation.js" +export * as MutationForm from "./MutationForm.js" export * as PubSub from "./PubSub.js" export * as Query from "./Query.js" export * as QueryClient from "./QueryClient.js" @@ -12,6 +14,4 @@ export * as ReactRuntime from "./ReactRuntime.js" export * as Result from "./Result.js" export * as SetStateAction from "./SetStateAction.js" export * as Stream from "./Stream.js" -export * as SubmittableForm from "./SubmittableForm.js" -export * as SynchronizedForm from "./SynchronizedForm.js" export * as View from "./View.js" -- 2.52.0 From 9b25ef4b57e7b882976bc8d6e4821b25e8d58cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 19 Jul 2026 03:15:55 +0200 Subject: [PATCH 57/61] Fix --- packages/effect-fc-next/src/PubSub.ts | 4 +- packages/effect-fc-next/src/QueryClient.ts | 4 +- packages/effect-fc-next/src/ReactRuntime.ts | 17 +- packages/effect-fc-next/src/Result.ts | 250 -------------------- packages/effect-fc-next/src/Stream.ts | 4 +- packages/effect-fc-next/src/index.ts | 1 - packages/effect-fc-next/src/utils.ts | 3 - 7 files changed, 10 insertions(+), 273 deletions(-) delete mode 100644 packages/effect-fc-next/src/Result.ts delete mode 100644 packages/effect-fc-next/src/utils.ts diff --git a/packages/effect-fc-next/src/PubSub.ts b/packages/effect-fc-next/src/PubSub.ts index 27401bc..17c44bc 100644 --- a/packages/effect-fc-next/src/PubSub.ts +++ b/packages/effect-fc-next/src/PubSub.ts @@ -3,6 +3,8 @@ import type * as React from "react" import * as Component from "./Component.js" +export * from "effect/PubSub" + export const useFromReactiveValues = Effect.fnUntraced(function* ( values: A ): Effect.fn.Return, never, Scope.Scope> { @@ -13,5 +15,3 @@ export const useFromReactiveValues = Effect.fnUntraced(function* Effect.forkScoped(client.run), ) +export const layer = (options?: service.Options) => Layer.effect(QueryClient, service(options)) + export const QueryClientCacheKeyTypeId: unique symbol = Symbol.for("@effect-fc/QueryClient/QueryClientCacheKey") export type QueryClientCacheKeyTypeId = typeof QueryClientCacheKeyTypeId diff --git a/packages/effect-fc-next/src/ReactRuntime.ts b/packages/effect-fc-next/src/ReactRuntime.ts index 4413e3e..c883af7 100644 --- a/packages/effect-fc-next/src/ReactRuntime.ts +++ b/packages/effect-fc-next/src/ReactRuntime.ts @@ -2,8 +2,6 @@ import { type Context, Effect, Layer, ManagedRuntime, Predicate } from "effect" import * as React from "react" import * as Component from "./Component.js" -import * as ErrorObserver from "./ErrorObserver.js" -import * as QueryClient from "./QueryClient.js" export const ReactRuntimeTypeId: unique symbol = Symbol.for("@effect-fc/ReactRuntime/ReactRuntime") @@ -16,18 +14,9 @@ export interface ReactRuntime { readonly context: React.Context> } -const ReactRuntimeProto = Object.freeze({ [ReactRuntimeTypeId]: ReactRuntimeTypeId } as const) - -export const preludeLayer: Layer.Layer< - | Component.ScopeMap - | ErrorObserver.ErrorObserver - | QueryClient.QueryClient -> = Layer.mergeAll( - Component.ScopeMap.layer, - ErrorObserver.layer, - QueryClient.QueryClient.Default, -) +const ReactRuntimePrototype = Object.freeze({ [ReactRuntimeTypeId]: ReactRuntimeTypeId } as const) +export const preludeLayer: Layer.Layer = Layer.mergeAll(Component.ScopeMap.layer) export const isReactRuntime = (u: unknown): u is ReactRuntime => Predicate.hasProperty(u, ReactRuntimeTypeId) @@ -43,7 +32,7 @@ export const make = ( // biome-ignore lint/style/noNonNullAssertion: context initialization context: React.createContext>(null!), }), - ReactRuntimeProto, + ReactRuntimePrototype, ) diff --git a/packages/effect-fc-next/src/Result.ts b/packages/effect-fc-next/src/Result.ts deleted file mode 100644 index 1c92d99..0000000 --- a/packages/effect-fc-next/src/Result.ts +++ /dev/null @@ -1,250 +0,0 @@ -import { Cause, Context, Data, Effect, Equal, Exit, type Fiber, Hash, Layer, Match, Pipeable, Predicate, pipe, type Scope, SubscriptionRef } from "effect" -import { Lens } from "effect-lens" -import type { View } from "effect-lens/View" - - -export const ResultTypeId: unique symbol = Symbol.for("@effect-fc/Result/Result") -export type ResultTypeId = typeof ResultTypeId - -export type Result = ( - | Initial - | Running

- | Final -) - -// biome-ignore lint/complexity/noBannedTypes: "{}" is relevant here -export type Final = (Success | Failure) & ({} | Flags

) -export type Flags

= WillFetch | WillRefresh | Refreshing

- -export declare namespace Result { - export type Success> = [R] extends [Result] ? A : never - export type Failure> = [R] extends [Result] ? E : never - export type Progress> = [R] extends [Result] ? P : never -} - -export declare namespace Flags { - export type Keys = keyof WillFetch & WillRefresh & Refreshing -} - -export interface Initial extends ResultPrototype { - readonly _tag: "Initial" -} - -export interface Running

extends ResultPrototype { - readonly _tag: "Running" - readonly progress: P -} - -export interface Success extends ResultPrototype { - readonly _tag: "Success" - readonly value: A -} - -export interface Failure extends ResultPrototype { - readonly _tag: "Failure" - readonly cause: Cause.Cause -} - -export interface WillFetch { - readonly _flag: "WillFetch" -} - -export interface WillRefresh { - readonly _flag: "WillRefresh" -} - -export interface Refreshing

{ - readonly _flag: "Refreshing" - readonly progress: P -} - - -export interface ResultPrototype extends Pipeable.Pipeable, Equal.Equal { - readonly [ResultTypeId]: ResultTypeId -} - -export const ResultPrototype: ResultPrototype = Object.freeze({ - ...Pipeable.Prototype, - [ResultTypeId]: ResultTypeId, - - [Equal.symbol](this: Result, that: Result): boolean { - if (this._tag !== that._tag || (this as Flags)._flag !== (that as Flags)._flag) - return false - if (hasRefreshingFlag(this) && !Equal.equals(this.progress, (that as Refreshing).progress)) - return false - return Match.value(this).pipe( - Match.tag("Initial", () => true), - Match.tag("Running", self => Equal.equals(self.progress, (that as Running).progress)), - Match.tag("Success", self => Equal.equals(self.value, (that as Success).value)), - Match.tag("Failure", self => Equal.equals(self.cause, (that as Failure).cause)), - Match.exhaustive, - ) - }, - - [Hash.symbol](this: Result): number { - return pipe(Hash.string(this._tag), - tagHash => Match.value(this).pipe( - Match.tag("Initial", () => tagHash), - Match.tag("Running", self => Hash.combine(Hash.hash(self.progress))(tagHash)), - Match.tag("Success", self => Hash.combine(Hash.hash(self.value))(tagHash)), - Match.tag("Failure", self => Hash.combine(Hash.hash(self.cause))(tagHash)), - Match.exhaustive, - ), - Hash.combine(Hash.hash((this as Flags)._flag)), - hash => hasRefreshingFlag(this) - ? Hash.combine(Hash.hash(this.progress))(hash) - : hash, - ) - }, -} as const) - - -export const isResult = (u: unknown): u is Result => Predicate.hasProperty(u, ResultTypeId) -export const isFinal = (u: unknown): u is Final => isResult(u) && (isSuccess(u) || isFailure(u)) -export const isInitial = (u: unknown): u is Initial => isResult(u) && u._tag === "Initial" -export const isRunning = (u: unknown): u is Running => isResult(u) && u._tag === "Running" -export const isSuccess = (u: unknown): u is Success => isResult(u) && u._tag === "Success" -export const isFailure = (u: unknown): u is Failure => isResult(u) && u._tag === "Failure" -export const hasFlag = (u: unknown): u is Flags => isResult(u) && Predicate.hasProperty(u, "_flag") -export const hasWillFetchFlag = (u: unknown): u is WillFetch => isResult(u) && Predicate.hasProperty(u, "_flag") && u._flag === "WillFetch" -export const hasWillRefreshFlag = (u: unknown): u is WillRefresh => isResult(u) && Predicate.hasProperty(u, "_flag") && u._flag === "WillRefresh" -export const hasRefreshingFlag = (u: unknown): u is Refreshing => isResult(u) && Predicate.hasProperty(u, "_flag") && u._flag === "Refreshing" - -export const initial: { - (): Initial - (): Result -} = (): Initial => Object.setPrototypeOf({ _tag: "Initial" }, ResultPrototype) -export const running =

(progress?: P): Running

=> Object.setPrototypeOf({ _tag: "Running", progress }, ResultPrototype) -export const succeed = (value: A): Success => Object.setPrototypeOf({ _tag: "Success", value }, ResultPrototype) -export const fail = (cause: Cause.Cause ): Failure => Object.setPrototypeOf({ _tag: "Failure", cause }, ResultPrototype) - -export const willFetch = >( - result: R -): Omit & WillFetch => Object.setPrototypeOf( - Object.assign({}, result, { _flag: "WillFetch" }), - Object.getPrototypeOf(result), -) - -export const willRefresh = >( - result: R -): Omit & WillRefresh => Object.setPrototypeOf( - Object.assign({}, result, { _flag: "WillRefresh" }), - Object.getPrototypeOf(result), -) - -export const refreshing = , P = never>( - result: R, - progress?: P, -): Omit & Refreshing

=> Object.setPrototypeOf( - Object.assign({}, result, { _flag: "Refreshing", progress }), - Object.getPrototypeOf(result), -) - -export const fromExit: { - (exit: Exit.Success): Success - (exit: Exit.Failure): Failure - (exit: Exit.Exit): Success | Failure -} = exit => (exit._tag === "Success" ? succeed(exit.value) : fail(exit.cause)) as any - -export const toExit: { - (self: Success): Exit.Success - (self: Failure): Exit.Failure - (self: Final): Exit.Exit - (self: Result): Exit.Exit -} = (self: Result): any => { - switch (self._tag) { - case "Success": - return Exit.succeed(self.value) - case "Failure": - return Exit.failCause(self.cause) - default: - return Exit.fail(new Cause.NoSuchElementError()) - } -} - - -export interface Progress

{ - readonly progress: Lens.Lens -} -export const Progress =

() => Context.Service>("@effect-fc/Result/Progress") - -export class PreviousResultNotRunningNorRefreshing extends Data.TaggedError("@effect-fc/Result/PreviousResultNotRunningNorRefreshing")<{ - readonly previous: Result -}> {} - -export const makeProgressLayer = ( - state: Lens.Lens, never, never, never, never> -): Layer.Layer | Progress, never, never> => Layer.succeed( - Progress

() as Context.Service | Progress, Progress

| Progress>, - { - progress: state.pipe( - Lens.mapEffect( - a => (isRunning(a) || hasRefreshingFlag(a)) - ? Effect.succeed(a) - : Effect.fail(new PreviousResultNotRunningNorRefreshing({ previous: a })), - (_, b) => Effect.succeed(b), - ), - Lens.map( - a => a.progress, - (a, b) => isRunning(a) - ? running(b) - : refreshing(a, b) as Final & Refreshing

, - ), - ) - }, -) - - -export namespace unsafeForkEffect { - export type OutputContext = Exclude | Progress> - - export interface Options { - readonly initial?: Initial | Final - readonly initialProgress?: P - } -} - -export const unsafeForkEffect = Effect.fnUntraced(function* ( - effect: Effect.Effect, - options?: unsafeForkEffect.Options, NoInfer, P>, -): Effect.fn.Return< - readonly [result: View, never, never>, fiber: Fiber.Fiber], - never, - Scope.Scope | unsafeForkEffect.OutputContext -> { - const state = Lens.fromSubscriptionRef(yield* SubscriptionRef.make>( - options?.initial ?? initial(), - )) - - const fiber = yield* Effect.gen(function*() { - yield* Lens.set( - state, - (isFinal(options?.initial) && hasWillRefreshFlag(options?.initial)) - ? refreshing(options.initial, options?.initialProgress) as Result - : running(options?.initialProgress), - ) - return yield* Effect.onExit(effect, exit => Lens.set(state, fromExit(exit))) - }).pipe( - Effect.forkScoped, - Effect.provide(makeProgressLayer(state)), - ) - - return [state, fiber] as const -}) - -export namespace forkEffect { - export type InputContext = R extends Progress ? [X] extends [P] ? R : never : R - export type OutputContext = unsafeForkEffect.OutputContext - export interface Options extends unsafeForkEffect.Options {} -} - -export const forkEffect: { - ( - effect: Effect.Effect>>, - options?: forkEffect.Options, NoInfer, P>, - ): Effect.Effect< - readonly [result: View, never, never>, fiber: Fiber.Fiber], - never, - Scope.Scope | forkEffect.OutputContext - > -} = unsafeForkEffect diff --git a/packages/effect-fc-next/src/Stream.ts b/packages/effect-fc-next/src/Stream.ts index 67bf82e..35af3f4 100644 --- a/packages/effect-fc-next/src/Stream.ts +++ b/packages/effect-fc-next/src/Stream.ts @@ -3,6 +3,8 @@ import * as React from "react" import * as Component from "./Component.js" +export * from "effect/Stream" + export const use: { ( stream: Stream.Stream @@ -29,5 +31,3 @@ export const use: { return reactStateValue as Option.Some }) - -export * from "effect/Stream" diff --git a/packages/effect-fc-next/src/index.ts b/packages/effect-fc-next/src/index.ts index b114c1c..33039ed 100644 --- a/packages/effect-fc-next/src/index.ts +++ b/packages/effect-fc-next/src/index.ts @@ -11,7 +11,6 @@ export * as PubSub from "./PubSub.js" export * as Query from "./Query.js" export * as QueryClient from "./QueryClient.js" export * as ReactRuntime from "./ReactRuntime.js" -export * as Result from "./Result.js" export * as SetStateAction from "./SetStateAction.js" export * as Stream from "./Stream.js" export * as View from "./View.js" diff --git a/packages/effect-fc-next/src/utils.ts b/packages/effect-fc-next/src/utils.ts deleted file mode 100644 index 44ed408..0000000 --- a/packages/effect-fc-next/src/utils.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type ExcludeKeys = K extends keyof T ? ( - { [P in K]?: never } & Omit -) : T -- 2.52.0 From cbb050673be5ab86b8b8dc0bf5a35132fdebd0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 19 Jul 2026 03:20:24 +0200 Subject: [PATCH 58/61] Fix --- bun.lock | 4 ++-- packages/effect-fc-next/src/ReactRuntime.ts | 6 +++--- packages/example-next/package.json | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bun.lock b/bun.lock index 9cee2d3..99fe735 100644 --- a/bun.lock +++ b/bun.lock @@ -104,7 +104,7 @@ "name": "@effect-fc/example-next", "version": "0.0.0", "dependencies": { - "effect": "4.0.0-beta.85", + "effect": "4.0.0-beta.98", "effect-fc-next": "workspace:*", }, "devDependencies": { @@ -2999,7 +2999,7 @@ "@docusaurus/utils/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], - "@effect-fc/example-next/effect": ["effect@4.0.0-beta.85", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.8.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.1", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^14.0.0", "yaml": "^2.9.0" } }, "sha512-Cjv9YQyv4CiIccmRAQIWAoeESCpCpiuHYY8zb5vqiYs3Ac2yE5RQAnKq7z4Ir/3VJYZb8kxh6rS8czDDnpTdkQ=="], + "@effect-fc/example-next/effect": ["effect@4.0.0-beta.98", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.9.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.4", "multipasta": "^0.2.8", "toml": "^4.1.2", "uuid": "^14.0.1", "yaml": "^2.9.0" } }, "sha512-oz+bsG5h+6RNrw4t5GMfQrk/xBS8ROoqkYsuvRhBr5O7mCOrpvH/hbw+QrDzvKIpX4HJClwm86F94c87W0sJxg=="], "@jsonjoy.com/fs-snapshot/@jsonjoy.com/json-pack": ["@jsonjoy.com/json-pack@17.67.0", "", { "dependencies": { "@jsonjoy.com/base64": "17.67.0", "@jsonjoy.com/buffers": "17.67.0", "@jsonjoy.com/codegen": "17.67.0", "@jsonjoy.com/json-pointer": "17.67.0", "@jsonjoy.com/util": "17.67.0", "hyperdyperid": "^1.2.0", "thingies": "^2.5.0", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w=="], diff --git a/packages/effect-fc-next/src/ReactRuntime.ts b/packages/effect-fc-next/src/ReactRuntime.ts index c883af7..29c738a 100644 --- a/packages/effect-fc-next/src/ReactRuntime.ts +++ b/packages/effect-fc-next/src/ReactRuntime.ts @@ -16,7 +16,7 @@ export interface ReactRuntime { const ReactRuntimePrototype = Object.freeze({ [ReactRuntimeTypeId]: ReactRuntimeTypeId } as const) -export const preludeLayer: Layer.Layer = Layer.mergeAll(Component.ScopeMap.layer) +export const preludeLayer: Layer.Layer = Component.ScopeMap.layer export const isReactRuntime = (u: unknown): u is ReactRuntime => Predicate.hasProperty(u, ReactRuntimeTypeId) @@ -26,11 +26,11 @@ export const make = ( ): ReactRuntime | R, ER> => Object.setPrototypeOf( Object.assign(function() {}, { runtime: ManagedRuntime.make( - Layer.merge(layer, preludeLayer), + Layer.merge(preludeLayer, layer), { memoMap }, ), // biome-ignore lint/style/noNonNullAssertion: context initialization - context: React.createContext>(null!), + context: React.createContext | R>>(null!), }), ReactRuntimePrototype, ) diff --git a/packages/example-next/package.json b/packages/example-next/package.json index a37ebbd..fb45b01 100644 --- a/packages/example-next/package.json +++ b/packages/example-next/package.json @@ -23,12 +23,12 @@ "vite": "^8.0.16" }, "dependencies": { - "effect": "4.0.0-beta.85", + "effect": "4.0.0-beta.98", "effect-fc-next": "workspace:*" }, "overrides": { "@types/react": "^19.2.15", - "effect": "4.0.0-beta.85", + "effect": "4.0.0-beta.98", "react": "^19.2.6" } } -- 2.52.0 From 885cff74b3927aef932598002591446989237114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 19 Jul 2026 03:27:41 +0200 Subject: [PATCH 59/61] Example fix --- bun.lock | 8 + packages/effect-fc-next/src/ReactRuntime.ts | 2 +- packages/example-next/index.html | 2 +- packages/example-next/package.json | 8 +- packages/example-next/src/domain/Todo.ts | 20 ++ packages/example-next/src/domain/index.ts | 1 + packages/example-next/src/index.css | 28 --- .../src/lib/form/TextFieldFormInputView.tsx | 56 +++++ .../form/TextFieldOptionalFormInputView.tsx | 64 ++++++ .../example-next/src/lib/schema/datetime.ts | 38 ++++ packages/example-next/src/lib/schema/index.ts | 2 + packages/example-next/src/lib/schema/json.ts | 6 + packages/example-next/src/main.tsx | 109 +++++++-- packages/example-next/src/routeTree.gen.ts | 210 ++++++++++++++++++ packages/example-next/src/routes/__root.tsx | 28 +++ packages/example-next/src/routes/async.tsx | 71 ++++++ packages/example-next/src/routes/blank.tsx | 10 + .../example-next/src/routes/dev/context.tsx | 42 ++++ packages/example-next/src/routes/dev/memo.tsx | 37 +++ packages/example-next/src/routes/form.tsx | 143 ++++++++++++ packages/example-next/src/routes/index.tsx | 24 ++ packages/example-next/src/routes/query.tsx | 117 ++++++++++ packages/example-next/src/routes/result.tsx | 60 +++++ packages/example-next/src/runtime.ts | 15 ++ .../example-next/src/todo/EditTodoView.tsx | 88 ++++++++ .../example-next/src/todo/NewTodoView.tsx | 78 +++++++ .../example-next/src/todo/TodoFormSchema.ts | 9 + packages/example-next/src/todo/TodosState.ts | 96 ++++++++ packages/example-next/src/todo/TodosView.tsx | 34 +++ packages/example-next/tsconfig.app.json | 4 + packages/example-next/vite.config.ts | 12 + 31 files changed, 1368 insertions(+), 54 deletions(-) create mode 100644 packages/example-next/src/domain/Todo.ts create mode 100644 packages/example-next/src/domain/index.ts create mode 100644 packages/example-next/src/lib/form/TextFieldFormInputView.tsx create mode 100644 packages/example-next/src/lib/form/TextFieldOptionalFormInputView.tsx create mode 100644 packages/example-next/src/lib/schema/datetime.ts create mode 100644 packages/example-next/src/lib/schema/index.ts create mode 100644 packages/example-next/src/lib/schema/json.ts create mode 100644 packages/example-next/src/routeTree.gen.ts create mode 100644 packages/example-next/src/routes/__root.tsx create mode 100644 packages/example-next/src/routes/async.tsx create mode 100644 packages/example-next/src/routes/blank.tsx create mode 100644 packages/example-next/src/routes/dev/context.tsx create mode 100644 packages/example-next/src/routes/dev/memo.tsx create mode 100644 packages/example-next/src/routes/form.tsx create mode 100644 packages/example-next/src/routes/index.tsx create mode 100644 packages/example-next/src/routes/query.tsx create mode 100644 packages/example-next/src/routes/result.tsx create mode 100644 packages/example-next/src/runtime.ts create mode 100644 packages/example-next/src/todo/EditTodoView.tsx create mode 100644 packages/example-next/src/todo/NewTodoView.tsx create mode 100644 packages/example-next/src/todo/TodoFormSchema.ts create mode 100644 packages/example-next/src/todo/TodosState.ts create mode 100644 packages/example-next/src/todo/TodosView.tsx diff --git a/bun.lock b/bun.lock index 99fe735..2a9a52f 100644 --- a/bun.lock +++ b/bun.lock @@ -104,10 +104,16 @@ "name": "@effect-fc/example-next", "version": "0.0.0", "dependencies": { + "@effect/platform-browser": "4.0.0-beta.98", + "@radix-ui/themes": "^3.3.0", "effect": "4.0.0-beta.98", "effect-fc-next": "workspace:*", + "react-icons": "^5.6.0", }, "devDependencies": { + "@tanstack/react-router": "^1.170.10", + "@tanstack/react-router-devtools": "^1.167.0", + "@tanstack/router-plugin": "^1.168.13", "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^6.0.2", @@ -2999,6 +3005,8 @@ "@docusaurus/utils/jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="], + "@effect-fc/example-next/@effect/platform-browser": ["@effect/platform-browser@4.0.0-beta.98", "", { "dependencies": { "multipasta": "^0.2.8" }, "peerDependencies": { "effect": "^4.0.0-beta.98" } }, "sha512-Y0BEe0N8clKmJTHqmZpS85pLZbqAxP5uV3IYF0tDw/1dcs8AbTRHjbRmOLdyLtmU32NBVAiaUD3Vopb5Et5R/g=="], + "@effect-fc/example-next/effect": ["effect@4.0.0-beta.98", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.9.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.4", "multipasta": "^0.2.8", "toml": "^4.1.2", "uuid": "^14.0.1", "yaml": "^2.9.0" } }, "sha512-oz+bsG5h+6RNrw4t5GMfQrk/xBS8ROoqkYsuvRhBr5O7mCOrpvH/hbw+QrDzvKIpX4HJClwm86F94c87W0sJxg=="], "@jsonjoy.com/fs-snapshot/@jsonjoy.com/json-pack": ["@jsonjoy.com/json-pack@17.67.0", "", { "dependencies": { "@jsonjoy.com/base64": "17.67.0", "@jsonjoy.com/buffers": "17.67.0", "@jsonjoy.com/codegen": "17.67.0", "@jsonjoy.com/json-pointer": "17.67.0", "@jsonjoy.com/util": "17.67.0", "hyperdyperid": "^1.2.0", "thingies": "^2.5.0", "tree-dump": "^1.1.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w=="], diff --git a/packages/effect-fc-next/src/ReactRuntime.ts b/packages/effect-fc-next/src/ReactRuntime.ts index 29c738a..87023f3 100644 --- a/packages/effect-fc-next/src/ReactRuntime.ts +++ b/packages/effect-fc-next/src/ReactRuntime.ts @@ -26,7 +26,7 @@ export const make = ( ): ReactRuntime | R, ER> => Object.setPrototypeOf( Object.assign(function() {}, { runtime: ManagedRuntime.make( - Layer.merge(preludeLayer, layer), + Layer.mergeAll(preludeLayer, layer), { memoMap }, ), // biome-ignore lint/style/noNonNullAssertion: context initialization diff --git a/packages/example-next/index.html b/packages/example-next/index.html index e7e38b3..e4b78ea 100644 --- a/packages/example-next/index.html +++ b/packages/example-next/index.html @@ -4,7 +4,7 @@ - Effect FC Next Example + Vite + React + TS

diff --git a/packages/example-next/package.json b/packages/example-next/package.json index fb45b01..78995c3 100644 --- a/packages/example-next/package.json +++ b/packages/example-next/package.json @@ -14,6 +14,9 @@ "clean:modules": "rm -rf node_modules" }, "devDependencies": { + "@tanstack/react-router": "^1.170.10", + "@tanstack/react-router-devtools": "^1.167.0", + "@tanstack/router-plugin": "^1.168.13", "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^6.0.2", @@ -23,8 +26,11 @@ "vite": "^8.0.16" }, "dependencies": { + "@effect/platform-browser": "4.0.0-beta.98", + "@radix-ui/themes": "^3.3.0", "effect": "4.0.0-beta.98", - "effect-fc-next": "workspace:*" + "effect-fc-next": "workspace:*", + "react-icons": "^5.6.0" }, "overrides": { "@types/react": "^19.2.15", diff --git a/packages/example-next/src/domain/Todo.ts b/packages/example-next/src/domain/Todo.ts new file mode 100644 index 0000000..500faab --- /dev/null +++ b/packages/example-next/src/domain/Todo.ts @@ -0,0 +1,20 @@ +import { Schema } from "effect" +import { assertEncodedJsonifiable } from "@/lib/schema" + + +export class Todo extends Schema.Class("Todo")({ + _tag: Schema.tag("Todo"), + id: Schema.String, + content: Schema.String, + completedAt: Schema.OptionFromSelf(Schema.DateTimeUtcFromSelf), +}) {} + + +export const TodoFromJsonStruct = Schema.Struct({ + ...Todo.fields, + completedAt: Schema.Option(Schema.DateTimeUtc), +}).pipe( + assertEncodedJsonifiable +) + +export const TodoFromJson = Schema.compose(TodoFromJsonStruct, Todo) diff --git a/packages/example-next/src/domain/index.ts b/packages/example-next/src/domain/index.ts new file mode 100644 index 0000000..8d70c13 --- /dev/null +++ b/packages/example-next/src/domain/index.ts @@ -0,0 +1 @@ +export * as Todo from "./Todo" diff --git a/packages/example-next/src/index.css b/packages/example-next/src/index.css index 8f84e7d..e69de29 100644 --- a/packages/example-next/src/index.css +++ b/packages/example-next/src/index.css @@ -1,28 +0,0 @@ -:root { - color: #17202a; - font-family: system-ui, sans-serif; - background: #f4f6f7; -} - -body { - display: grid; - min-width: 320px; - min-height: 100vh; - margin: 0; - place-items: center; -} - -main { - padding: 2rem; - text-align: center; -} - -button { - padding: 0.65rem 1rem; - border: 0; - border-radius: 0.5rem; - color: white; - font: inherit; - background: #7d3c98; - cursor: pointer; -} diff --git a/packages/example-next/src/lib/form/TextFieldFormInputView.tsx b/packages/example-next/src/lib/form/TextFieldFormInputView.tsx new file mode 100644 index 0000000..ca4f843 --- /dev/null +++ b/packages/example-next/src/lib/form/TextFieldFormInputView.tsx @@ -0,0 +1,56 @@ +import { Callout, Flex, Spinner, TextField } from "@radix-ui/themes" +import { Array, Option, Struct } from "effect" +import { Component, Form, Subscribable } from "effect-fc" +import type * as React from "react" + + +export declare namespace TextFieldFormInputView { + export interface Props + extends Omit, Form.useInput.Options { + readonly form: Form.Form + } + + export type Signature =

(props: Props) => React.ReactNode +} + +export const TextFieldFormInputView = Component.make("TextFieldFormInputView")(function*( + props: TextFieldFormInputView.Props +) { + const input = yield* Form.useInput(props.form, props) + const [issues, isValidating, isCommitting] = yield* Subscribable.useAll([ + props.form.issues, + props.form.isValidating, + props.form.isCommitting, + ]) + + return ( + + input.setValue(e.target.value)} + disabled={isCommitting} + {...Struct.omit(props, "form")} + > + {isValidating && + + + + } + + {props.children} + + + {Option.match(Array.head(issues), { + onSome: issue => ( + + {issue.message} + + ), + + onNone: () => <>, + })} + + ) +}).pipe( + Component.withSignature() +) diff --git a/packages/example-next/src/lib/form/TextFieldOptionalFormInputView.tsx b/packages/example-next/src/lib/form/TextFieldOptionalFormInputView.tsx new file mode 100644 index 0000000..68693ea --- /dev/null +++ b/packages/example-next/src/lib/form/TextFieldOptionalFormInputView.tsx @@ -0,0 +1,64 @@ +import { Callout, Flex, Spinner, Switch, TextField } from "@radix-ui/themes" +import { Array, Option, Struct } from "effect" +import { Component, Form, Subscribable } from "effect-fc" +import type * as React from "react" + + +export declare namespace TextFieldOptionalFormInputView { + export interface Props + extends Omit, Form.useOptionalInput.Options { + readonly form: Form.Form, ER, EW> + } + + export type Signature =

(props: Props) => React.ReactNode +} + +export const TextFieldOptionalFormInputView = Component.make("TextFieldOptionalFormInputView")(function*( + props: TextFieldOptionalFormInputView.Props +) { + const input = yield* Form.useOptionalInput(props.form, props) + const [issues, isValidating, isCommitting] = yield* Subscribable.useAll([ + props.form.issues, + props.form.isValidating, + props.form.isCommitting, + ]) + + return ( + + input.setValue(e.target.value)} + disabled={!input.enabled || isCommitting} + {...Struct.omit(props, "form", "defaultValue")} + > + + + + + {isValidating && + + + + } + + {props.children} + + + {Option.match(Array.head(issues), { + onSome: issue => ( + + {issue.message} + + ), + + onNone: () => <>, + })} + + ) +}).pipe( + Component.withSignature() +) diff --git a/packages/example-next/src/lib/schema/datetime.ts b/packages/example-next/src/lib/schema/datetime.ts new file mode 100644 index 0000000..ce85d3a --- /dev/null +++ b/packages/example-next/src/lib/schema/datetime.ts @@ -0,0 +1,38 @@ +import { DateTime, Effect, Option, ParseResult, Schema } from "effect" + + +export class DateTimeUtcFromZoned extends Schema.transformOrFail( + Schema.DateTimeZonedFromSelf, + Schema.DateTimeUtcFromSelf, + { + strict: true, + encode: DateTime.setZoneCurrent, + decode: i => ParseResult.succeed(DateTime.toUtc(i)), + }, +) {} + +export class DateTimeZonedFromUtc extends Schema.transformOrFail( + Schema.DateTimeUtcFromSelf, + Schema.DateTimeZonedFromSelf, + { + strict: true, + encode: a => ParseResult.succeed(DateTime.toUtc(a)), + decode: DateTime.setZoneCurrent, + }, +) {} + +export class DateTimeUtcFromZonedInput extends Schema.transformOrFail( + Schema.String, + DateTimeUtcFromZoned, + { + strict: true, + encode: a => ParseResult.succeed(DateTime.formatIsoZoned(a).slice(0, 16)), + decode: (i, _, ast) => Effect.flatMap( + DateTime.CurrentTimeZone, + timeZone => Option.match(DateTime.makeZoned(i, { timeZone, adjustForTimeZone: true }), { + onSome: ParseResult.succeed, + onNone: () => ParseResult.fail(new ParseResult.Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a DateTime.Zoned`)), + }), + ), + }, +) {} diff --git a/packages/example-next/src/lib/schema/index.ts b/packages/example-next/src/lib/schema/index.ts new file mode 100644 index 0000000..260895c --- /dev/null +++ b/packages/example-next/src/lib/schema/index.ts @@ -0,0 +1,2 @@ +export * from "./datetime" +export * from "./json" diff --git a/packages/example-next/src/lib/schema/json.ts b/packages/example-next/src/lib/schema/json.ts new file mode 100644 index 0000000..5b69cc4 --- /dev/null +++ b/packages/example-next/src/lib/schema/json.ts @@ -0,0 +1,6 @@ +import type { Schema } from "effect" +import type { JsonValue } from "type-fest" + + +export const assertEncodedJsonifiable = , A, I extends JsonValue, R>(schema: S & Schema.Schema): S => schema +export const assertTypeJsonifiable = , A extends JsonValue, I, R>(schema: S & Schema.Schema): S => schema diff --git a/packages/example-next/src/main.tsx b/packages/example-next/src/main.tsx index 3b4d312..59d0c0c 100644 --- a/packages/example-next/src/main.tsx +++ b/packages/example-next/src/main.tsx @@ -1,40 +1,103 @@ -import { Effect, Layer, SubscriptionRef } from "effect" -import { Component, Lens, ReactRuntime, View } from "effect-fc-next" +import { Effect, Layer, Schema, SubscriptionRef } from "effect" +import { + Component, + Form, + Lens, + LensForm, + MutationForm, + ReactRuntime, + View, +} from "effect-fc-next" import { StrictMode } from "react" import { createRoot } from "react-dom/client" import "./index.css" -const Counter = Component.make("Counter")(function*() { - const count = yield* Component.useOnMount(() => Effect.map( - SubscriptionRef.make(0), - Lens.fromSubscriptionRef, - )) - const [value] = yield* View.useAll([count]) - const increment = yield* Component.useCallbackSync( - () => Lens.update(count, n => n + 1), - [count], - ) +const runtime = ReactRuntime.make(Layer.empty) + +const MutationFormExample = Component.make("MutationFormExample")(function*() { + const form = yield* Component.useOnMount(() => MutationForm.service({ + schema: Schema.String, + initialEncodedValue: "", + f: ([value]) => Effect.log(`Submitted: ${value}`), + })) + const input = yield* Form.useInput(form) + const [canCommit, isCommitting, issues] = yield* View.useAll([ + form.canCommit, + form.isCommitting, + form.issues, + ]) + const runPromise = yield* Component.useRunPromise() return ( -

-

Effect FC Next

-

Running on Effect V4.

- -
+
+

MutationForm

+

Owns a draft and commits it explicitly through a Mutation.

+
{ + event.preventDefault() + void runPromise(form.submit) + }}> + input.setValue(event.currentTarget.value)} + disabled={isCommitting} + placeholder="Write something to submit" + /> + +
+ {issues.map((issue) =>

{issue.message}

)} +
) -}) +}).pipe(Component.withRuntime(runtime.context)) -const runtime = ReactRuntime.make(Layer.empty) -const CounterApp = Counter.pipe(Component.withRuntime(runtime.context)) +const LensFormExample = Component.make("LensFormExample")(function*() { + const target = yield* Component.useOnMount(() => Effect.map( + SubscriptionRef.make("A value owned by the application"), + Lens.fromSubscriptionRef, + )) + const form = yield* Component.useOnMount(() => LensForm.service({ + schema: Schema.String, + target, + })) + const input = yield* Form.useInput(form) + const [value, canCommit, isCommitting, issues] = yield* View.useAll([ + target, + form.canCommit, + form.isCommitting, + form.issues, + ]) + + return ( +
+

LensForm

+

Synchronizes valid input directly with a target Lens.

+ input.setValue(event.currentTarget.value)} + disabled={!canCommit || isCommitting} + /> +

Target value: {value}

+ {issues.map((issue) =>

{issue.message}

)} +
+ ) +}).pipe(Component.withRuntime(runtime.context)) + +const App = () => ( +
+

Effect FC Next

+

Effect v4 examples for the finalized form API.

+ + +
+) // biome-ignore lint/style/noNonNullAssertion: the Vite template provides this element createRoot(document.getElementById("root")!).render( - + , ) diff --git a/packages/example-next/src/routeTree.gen.ts b/packages/example-next/src/routeTree.gen.ts new file mode 100644 index 0000000..3ad431c --- /dev/null +++ b/packages/example-next/src/routeTree.gen.ts @@ -0,0 +1,210 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +import { Route as rootRouteImport } from './routes/__root' +import { Route as IndexRouteImport } from './routes/index' +import { Route as AsyncRouteImport } from './routes/async' +import { Route as BlankRouteImport } from './routes/blank' +import { Route as FormRouteImport } from './routes/form' +import { Route as QueryRouteImport } from './routes/query' +import { Route as ResultRouteImport } from './routes/result' +import { Route as DevContextRouteImport } from './routes/dev/context' +import { Route as DevMemoRouteImport } from './routes/dev/memo' + +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) +const AsyncRoute = AsyncRouteImport.update({ + id: '/async', + path: '/async', + getParentRoute: () => rootRouteImport, +} as any) +const BlankRoute = BlankRouteImport.update({ + id: '/blank', + path: '/blank', + getParentRoute: () => rootRouteImport, +} as any) +const FormRoute = FormRouteImport.update({ + id: '/form', + path: '/form', + getParentRoute: () => rootRouteImport, +} as any) +const QueryRoute = QueryRouteImport.update({ + id: '/query', + path: '/query', + getParentRoute: () => rootRouteImport, +} as any) +const ResultRoute = ResultRouteImport.update({ + id: '/result', + path: '/result', + getParentRoute: () => rootRouteImport, +} as any) +const DevContextRoute = DevContextRouteImport.update({ + id: '/dev/context', + path: '/dev/context', + getParentRoute: () => rootRouteImport, +} as any) +const DevMemoRoute = DevMemoRouteImport.update({ + id: '/dev/memo', + path: '/dev/memo', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '/async': typeof AsyncRoute + '/blank': typeof BlankRoute + '/form': typeof FormRoute + '/query': typeof QueryRoute + '/result': typeof ResultRoute + '/dev/context': typeof DevContextRoute + '/dev/memo': typeof DevMemoRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute + '/async': typeof AsyncRoute + '/blank': typeof BlankRoute + '/form': typeof FormRoute + '/query': typeof QueryRoute + '/result': typeof ResultRoute + '/dev/context': typeof DevContextRoute + '/dev/memo': typeof DevMemoRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute + '/async': typeof AsyncRoute + '/blank': typeof BlankRoute + '/form': typeof FormRoute + '/query': typeof QueryRoute + '/result': typeof ResultRoute + '/dev/context': typeof DevContextRoute + '/dev/memo': typeof DevMemoRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: + | '/' + | '/async' + | '/blank' + | '/form' + | '/query' + | '/result' + | '/dev/context' + | '/dev/memo' + fileRoutesByTo: FileRoutesByTo + to: + | '/' + | '/async' + | '/blank' + | '/form' + | '/query' + | '/result' + | '/dev/context' + | '/dev/memo' + id: + | '__root__' + | '/' + | '/async' + | '/blank' + | '/form' + | '/query' + | '/result' + | '/dev/context' + | '/dev/memo' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + AsyncRoute: typeof AsyncRoute + BlankRoute: typeof BlankRoute + FormRoute: typeof FormRoute + QueryRoute: typeof QueryRoute + ResultRoute: typeof ResultRoute + DevContextRoute: typeof DevContextRoute + DevMemoRoute: typeof DevMemoRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + '/async': { + id: '/async' + path: '/async' + fullPath: '/async' + preLoaderRoute: typeof AsyncRouteImport + parentRoute: typeof rootRouteImport + } + '/blank': { + id: '/blank' + path: '/blank' + fullPath: '/blank' + preLoaderRoute: typeof BlankRouteImport + parentRoute: typeof rootRouteImport + } + '/form': { + id: '/form' + path: '/form' + fullPath: '/form' + preLoaderRoute: typeof FormRouteImport + parentRoute: typeof rootRouteImport + } + '/query': { + id: '/query' + path: '/query' + fullPath: '/query' + preLoaderRoute: typeof QueryRouteImport + parentRoute: typeof rootRouteImport + } + '/result': { + id: '/result' + path: '/result' + fullPath: '/result' + preLoaderRoute: typeof ResultRouteImport + parentRoute: typeof rootRouteImport + } + '/dev/context': { + id: '/dev/context' + path: '/dev/context' + fullPath: '/dev/context' + preLoaderRoute: typeof DevContextRouteImport + parentRoute: typeof rootRouteImport + } + '/dev/memo': { + id: '/dev/memo' + path: '/dev/memo' + fullPath: '/dev/memo' + preLoaderRoute: typeof DevMemoRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + AsyncRoute: AsyncRoute, + BlankRoute: BlankRoute, + FormRoute: FormRoute, + QueryRoute: QueryRoute, + ResultRoute: ResultRoute, + DevContextRoute: DevContextRoute, + DevMemoRoute: DevMemoRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() diff --git a/packages/example-next/src/routes/__root.tsx b/packages/example-next/src/routes/__root.tsx new file mode 100644 index 0000000..67b0910 --- /dev/null +++ b/packages/example-next/src/routes/__root.tsx @@ -0,0 +1,28 @@ +import { Container, Flex, Theme } from "@radix-ui/themes" +import { createRootRoute, Link, Outlet } from "@tanstack/react-router" +import { TanStackRouterDevtools } from "@tanstack/react-router-devtools" + +import "@radix-ui/themes/styles.css" +import "../index.css" + + +export const Route = createRootRoute({ + component: Root +}) + +function Root() { + return ( + + + + Index + Blank + + + + + + + + ) +} diff --git a/packages/example-next/src/routes/async.tsx b/packages/example-next/src/routes/async.tsx new file mode 100644 index 0000000..62e0234 --- /dev/null +++ b/packages/example-next/src/routes/async.tsx @@ -0,0 +1,71 @@ +import { HttpClient } from "@effect/platform" +import { Container, Flex, Heading, Slider, Text, TextField } from "@radix-ui/themes" +import { createFileRoute } from "@tanstack/react-router" +import { Array, Effect, flow, Option, Schema } from "effect" +import { Async, Component, Memoized } from "effect-fc" +import * as React from "react" +import { runtime } from "@/runtime" + + +const Post = Schema.Struct({ + userId: Schema.Int, + id: Schema.Int, + title: Schema.String, + body: Schema.String, +}) + +interface AsyncFetchPostViewProps { + readonly id: number +} + +class AsyncFetchPostView extends Component.make("AsyncFetchPostView")(function*(props: AsyncFetchPostViewProps) { + const post = yield* Component.useOnChange(() => HttpClient.HttpClient.pipe( + Effect.tap(Effect.sleep("500 millis")), + Effect.andThen(client => client.get(`https://jsonplaceholder.typicode.com/posts/${ props.id }`)), + Effect.andThen(response => response.json), + Effect.andThen(Schema.decodeUnknown(Post)), + ), [props.id]) + + return ( +
+ {post.title} + {post.body} +
+ ) +}).pipe( + Async.async, + Async.withOptions({ defaultFallback: Default fallback }), + Memoized.memoized, +) {} + + +const AsyncRouteComponent = Component.make("AsyncRouteView")(function*() { + const [text, setText] = React.useState("Typing here should not trigger a refetch of the post") + const [id, setId] = React.useState(1) + + const AsyncFetchPost = yield* AsyncFetchPostView.use + + return ( + + + setText(e.currentTarget.value)} + /> + + + + Loading post...} /> + + + ) +}).pipe( + Component.withRuntime(runtime.context) +) + +export const Route = createFileRoute("/async")({ + component: AsyncRouteComponent, +}) diff --git a/packages/example-next/src/routes/blank.tsx b/packages/example-next/src/routes/blank.tsx new file mode 100644 index 0000000..4f3c7df --- /dev/null +++ b/packages/example-next/src/routes/blank.tsx @@ -0,0 +1,10 @@ +import { createFileRoute } from "@tanstack/react-router" + + +export const Route = createFileRoute("/blank")({ + component: RouteComponent +}) + +function RouteComponent() { + return
Hello "/blank"!
+} diff --git a/packages/example-next/src/routes/dev/context.tsx b/packages/example-next/src/routes/dev/context.tsx new file mode 100644 index 0000000..26048a9 --- /dev/null +++ b/packages/example-next/src/routes/dev/context.tsx @@ -0,0 +1,42 @@ +import { Container, Flex, Text, TextField } from "@radix-ui/themes" +import { createFileRoute } from "@tanstack/react-router" +import { Console, Effect } from "effect" +import { Component } from "effect-fc" +import * as React from "react" +import { runtime } from "@/runtime" + + +class SubService extends Effect.Service()("SubService", { + effect: (value: string) => Effect.succeed({ value }) +}) {} + +const SubComponent = Component.makeUntraced("SubComponent")(function*() { + const service = yield* SubService + yield* Component.useOnMount(() => Effect.gen(function*() { + yield* Effect.addFinalizer(() => Console.log("SubComponent unmounted")) + yield* Console.log("SubComponent mounted") + })) + + return {service.value} +}) + +const ContextView = Component.makeUntraced("ContextView")(function*() { + const [serviceValue, setServiceValue] = React.useState("test") + const SubServiceLayer = React.useMemo(() => SubService.Default(serviceValue), [serviceValue]) + const SubComponentFC = yield* Effect.provide(SubComponent.use, yield* Component.useContextFromLayer(SubServiceLayer)) + + return ( + + + setServiceValue(e.target.value)} /> + + + + ) +}).pipe( + Component.withRuntime(runtime.context) +) + +export const Route = createFileRoute("/dev/context")({ + component: ContextView +}) diff --git a/packages/example-next/src/routes/dev/memo.tsx b/packages/example-next/src/routes/dev/memo.tsx new file mode 100644 index 0000000..ae672bd --- /dev/null +++ b/packages/example-next/src/routes/dev/memo.tsx @@ -0,0 +1,37 @@ +import { Flex, Text, TextField } from "@radix-ui/themes" +import { createFileRoute } from "@tanstack/react-router" +import { GetRandomValues, makeUuid4 } from "@typed/id" +import { Effect } from "effect" +import { Component, Memoized } from "effect-fc" +import * as React from "react" +import { runtime } from "@/runtime" + + +const RouteComponent = Component.makeUntraced("RouteComponent")(function*() { + const [value, setValue] = React.useState("") + + return ( + + setValue(e.target.value)} + /> + + {yield* Effect.map(SubComponent.use, FC => )} + {yield* Effect.map(MemoizedSubComponent.use, FC => )} + + ) +}).pipe( + Component.withRuntime(runtime.context) +) + +class SubComponent extends Component.makeUntraced("SubComponent")(function*() { + const id = yield* makeUuid4.pipe(Effect.provide(GetRandomValues.CryptoRandom)) + return {id} +}) {} + +class MemoizedSubComponent extends Memoized.memoized(SubComponent) {} + +export const Route = createFileRoute("/dev/memo")({ + component: RouteComponent, +}) diff --git a/packages/example-next/src/routes/form.tsx b/packages/example-next/src/routes/form.tsx new file mode 100644 index 0000000..9ce3fae --- /dev/null +++ b/packages/example-next/src/routes/form.tsx @@ -0,0 +1,143 @@ +import { Button, Container, Flex, Text } from "@radix-ui/themes" +import { createFileRoute } from "@tanstack/react-router" +import { Console, Effect, Match, Option, ParseResult, Schema } from "effect" +import { Component, Form, SubmittableForm, Subscribable } from "effect-fc" +import { TextFieldFormInputView } from "@/lib/form/TextFieldFormInputView" +import { TextFieldOptionalFormInputView } from "@/lib/form/TextFieldOptionalFormInputView" +import { DateTimeUtcFromZonedInput } from "@/lib/schema" +import { runtime } from "@/runtime" + + +const email = Schema.pattern( + /^(?!\.)(?!.*\.\.)([A-Z0-9_+-.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9-]*\.)+[A-Z]{2,}$/i, + + { + identifier: "email", + title: "email", + message: () => "Not an email address", + }, +) + +const RegisterFormSchema = Schema.Struct({ + email: Schema.String.pipe(email), + password: Schema.String.pipe(Schema.minLength(3)), + birth: Schema.OptionFromSelf(DateTimeUtcFromZonedInput), +}) + +const RegisterFormSubmitSchema = Schema.Struct({ + email: Schema.transformOrFail( + Schema.String, + Schema.String, + { + decode: (input, _options, ast) => input !== "admin@admin.com" + ? ParseResult.succeed(input) + : ParseResult.fail(new ParseResult.Type(ast, input, "This email is already in use.")), + encode: ParseResult.succeed, + }, + ), + password: Schema.String, + birth: Schema.OptionFromSelf(Schema.DateTimeUtcFromSelf), +}) + +class RegisterFormService extends Effect.Service()("RegisterFormService", { + scoped: Effect.gen(function*() { + const form = yield* SubmittableForm.service({ + schema: RegisterFormSchema.pipe( + Schema.compose( + Schema.transformOrFail( + Schema.typeSchema(RegisterFormSchema), + Schema.typeSchema(RegisterFormSchema), + { + decode: v => Effect.andThen(Effect.sleep("500 millis"), ParseResult.succeed(v)), + encode: ParseResult.succeed, + }, + ), + ), + ), + + initialEncodedValue: { email: "", password: "", birth: Option.none() }, + f: Effect.fnUntraced(function*([value]) { + yield* Effect.sleep("500 millis") + return yield* Schema.decode(RegisterFormSubmitSchema)(value) + }), + }) + + return { + form, + emailField: Form.focusObjectOn(form, "email"), + passwordField: Form.focusObjectOn(form, "password"), + birthField: Form.focusObjectOn(form, "birth"), + } as const + }) +}) {} + +class RegisterFormView extends Component.make("RegisterFormView")(function*() { + const form = yield* RegisterFormService + const [canCommit, submitResult] = yield* Subscribable.useAll([ + form.form.canCommit, + form.form.mutation.result, + ]) + + const runPromise = yield* Component.useRunPromise() + const TextFieldFormInput = yield* TextFieldFormInputView.use + const TextFieldOptionalFormInput = yield* TextFieldOptionalFormInputView.use + + yield* Component.useOnMount(() => Effect.gen(function*() { + yield* Effect.addFinalizer(() => Console.log("RegisterFormView unmounted")) + yield* Console.log("RegisterFormView mounted") + })) + + + return ( + +
{ + e.preventDefault() + void runPromise(form.form.submit) + }}> + + + + + + + + + +
+ + {Match.value(submitResult).pipe( + Match.tag("Initial", () => <>), + Match.tag("Running", () => Submitting...), + Match.tag("Success", () => Submitted successfully!), + Match.tag("Failure", e => Error: {e.cause.toString()}), + Match.exhaustive, + )} +
+ ) +}) {} + +const RegisterPage = Component.make("RegisterPageView")(function*() { + const RegisterForm = yield* Effect.provide( + RegisterFormView.use, + yield* Component.useContextFromLayer(RegisterFormService.Default), + ) + + return +}).pipe( + Component.withRuntime(runtime.context) +) + + +export const Route = createFileRoute("/form")({ + component: RegisterPage +}) diff --git a/packages/example-next/src/routes/index.tsx b/packages/example-next/src/routes/index.tsx new file mode 100644 index 0000000..d747b39 --- /dev/null +++ b/packages/example-next/src/routes/index.tsx @@ -0,0 +1,24 @@ +import { createFileRoute } from "@tanstack/react-router" +import { Effect } from "effect" +import { Component } from "effect-fc" +import { runtime } from "@/runtime" +import { TodosState } from "@/todo/TodosState" +import { TodosView } from "@/todo/TodosView" + + +const TodosStateLive = TodosState.Default("todos") + +const Index = Component.make("IndexView")(function*() { + const Todos = yield* Effect.provide( + TodosView.use, + yield* Component.useContextFromLayer(TodosStateLive), + ) + + return +}).pipe( + Component.withRuntime(runtime.context) +) + +export const Route = createFileRoute("/")({ + component: Index +}) diff --git a/packages/example-next/src/routes/query.tsx b/packages/example-next/src/routes/query.tsx new file mode 100644 index 0000000..047560e --- /dev/null +++ b/packages/example-next/src/routes/query.tsx @@ -0,0 +1,117 @@ +import { HttpClient, type HttpClientError } from "@effect/platform" +import { Button, Container, Flex, Heading, Slider, Text } from "@radix-ui/themes" +import { createFileRoute } from "@tanstack/react-router" +import { Array, Cause, Chunk, Console, Effect, flow, Match, Option, Schema, Stream, SubscriptionRef } from "effect" +import { Component, ErrorObserver, Lens, Mutation, Query, Result, Subscribable } from "effect-fc" +import { runtime } from "@/runtime" + + +const Post = Schema.Struct({ + userId: Schema.Int, + id: Schema.Int, + title: Schema.String, + body: Schema.String, +}) + +const ResultView = Component.make("ResultView")(function*() { + const runPromise = yield* Component.useRunPromise() + + const [idLens, query, mutation] = yield* Component.useOnMount(() => Effect.gen(function*() { + const idLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(1)) + const key = Stream.map(idLens.changes, id => [id] as const) + + const query = yield* Query.service({ + key, + f: ([id]) => HttpClient.HttpClient.pipe( + Effect.tap(Effect.sleep("500 millis")), + Effect.andThen(client => client.get(`https://jsonplaceholder.typicode.com/posts/${ id }`)), + Effect.andThen(response => response.json), + Effect.andThen(Schema.decodeUnknown(Post)), + ), + staleTime: "10 seconds", + }) + + const mutation = yield* Mutation.make({ + f: ([id]: readonly [id: number]) => HttpClient.HttpClient.pipe( + Effect.tap(Effect.sleep("500 millis")), + Effect.andThen(client => client.get(`https://jsonplaceholder.typicode.com/posts/${ id }`)), + Effect.andThen(response => response.json), + Effect.andThen(Schema.decodeUnknown(Post)), + ), + }) + + return [idLens, query, mutation] as const + })) + + const [id, setId] = yield* Lens.useState(idLens) + const [queryResult, mutationResult] = yield* Subscribable.useAll([query.result, mutation.result]) + + yield* Component.useOnMount(() => ErrorObserver.ErrorObserver().pipe( + Effect.andThen(observer => observer.subscribe), + Effect.andThen(Stream.fromQueue), + Stream.unwrapScoped, + Stream.runForEach(flow( + Cause.failures, + Chunk.findFirst(e => e._tag === "RequestError" || e._tag === "ResponseError"), + Option.match({ + onSome: e => Console.log("ResultView HttpClient error", e), + onNone: () => Effect.void, + }), + )), + Effect.forkScoped, + )) + + return ( + + + + +
+ {Match.value(queryResult).pipe( + Match.tag("Running", () => Loading...), + Match.tag("Success", result => <> + {result.value.title} + {result.value.body} + {Result.hasRefreshingFlag(result) && Refreshing...} + ), + Match.tag("Failure", result => + An error has occured: {result.cause.toString()} + ), + Match.orElse(() => <>), + )} +
+ + + + + + +
+ {Match.value(mutationResult).pipe( + Match.tag("Running", () => Loading...), + Match.tag("Success", result => <> + {result.value.title} + {result.value.body} + {Result.hasRefreshingFlag(result) && Refreshing...} + ), + Match.tag("Failure", result => + An error has occured: {result.cause.toString()} + ), + Match.orElse(() => <>), + )} +
+ + + + +
+
+ ) +}) + +export const Route = createFileRoute("/query")({ + component: Component.withRuntime(ResultView, runtime.context) +}) diff --git a/packages/example-next/src/routes/result.tsx b/packages/example-next/src/routes/result.tsx new file mode 100644 index 0000000..0828f37 --- /dev/null +++ b/packages/example-next/src/routes/result.tsx @@ -0,0 +1,60 @@ +import { HttpClient, type HttpClientError } from "@effect/platform" +import { Container, Heading, Text } from "@radix-ui/themes" +import { createFileRoute } from "@tanstack/react-router" +import { Cause, Chunk, Console, Effect, flow, Match, Option, Schema, Stream } from "effect" +import { Component, ErrorObserver, Result, Subscribable } from "effect-fc" +import { runtime } from "@/runtime" + + +const Post = Schema.Struct({ + userId: Schema.Int, + id: Schema.Int, + title: Schema.String, + body: Schema.String, +}) + +const ResultView = Component.makeUntraced("Result")(function*() { + const [resultSubscribable] = yield* Component.useOnMount(() => HttpClient.HttpClient.pipe( + Effect.andThen(client => client.get("https://jsonplaceholder.typicode.com/posts/1")), + Effect.andThen(response => response.json), + Effect.andThen(Schema.decodeUnknown(Post)), + Effect.tap(Effect.sleep("250 millis")), + Result.forkEffect, + )) + const [result] = yield* Subscribable.useAll([resultSubscribable]) + + yield* Component.useOnMount(() => ErrorObserver.ErrorObserver().pipe( + Effect.andThen(observer => observer.subscribe), + Effect.andThen(Stream.fromQueue), + Stream.unwrapScoped, + Stream.runForEach(flow( + Cause.failures, + Chunk.findFirst(e => e._tag === "RequestError" || e._tag === "ResponseError"), + Option.match({ + onSome: e => Console.log("ResultView HttpClient error", e), + onNone: () => Effect.void, + }), + )), + Effect.forkScoped, + )) + + return ( + + {Match.value(result).pipe( + Match.tag("Running", () => Loading...), + Match.tag("Success", result => <> + {result.value.title} + {result.value.body} + ), + Match.tag("Failure", result => + An error has occured: {result.cause.toString()} + ), + Match.orElse(() => <>), + )} + + ) +}) + +export const Route = createFileRoute("/result")({ + component: Component.withRuntime(ResultView, runtime.context) +}) diff --git a/packages/example-next/src/runtime.ts b/packages/example-next/src/runtime.ts new file mode 100644 index 0000000..3467529 --- /dev/null +++ b/packages/example-next/src/runtime.ts @@ -0,0 +1,15 @@ +import { FetchHttpClient } from "@effect/platform" +import { Clipboard, Geolocation, Permissions } from "@effect/platform-browser" +import { DateTime, Layer } from "effect" +import { ReactRuntime } from "effect-fc" + + +export const AppLive = Layer.empty.pipe( + Layer.provideMerge(DateTime.layerCurrentZoneLocal), + Layer.provideMerge(Clipboard.layer), + Layer.provideMerge(Geolocation.layer), + Layer.provideMerge(Permissions.layer), + Layer.provideMerge(FetchHttpClient.layer), +) + +export const runtime = ReactRuntime.make(AppLive) diff --git a/packages/example-next/src/todo/EditTodoView.tsx b/packages/example-next/src/todo/EditTodoView.tsx new file mode 100644 index 0000000..69a9016 --- /dev/null +++ b/packages/example-next/src/todo/EditTodoView.tsx @@ -0,0 +1,88 @@ +import { Box, Flex, IconButton } from "@radix-ui/themes" +import { Effect } from "effect" +import { Component, Form, Subscribable, SynchronizedForm } from "effect-fc" +import { FaArrowDown, FaArrowUp } from "react-icons/fa" +import { FaDeleteLeft } from "react-icons/fa6" +import { TextFieldFormInputView } from "@/lib/form/TextFieldFormInputView" +import { TextFieldOptionalFormInputView } from "@/lib/form/TextFieldOptionalFormInputView" +import { TodoFormSchema } from "./TodoFormSchema" +import { TodosState } from "./TodosState" + + +export interface EditTodoViewProps { + readonly id: string +} + +export class EditTodoView extends Component.make("TodoView")(function*(props: EditTodoViewProps) { + const state = yield* TodosState + + const [ + indexSubscribable, + contentField, + completedAtField, + ] = yield* Component.useOnChange(() => Effect.gen(function*() { + const indexSubscribable = state.getIndexSubscribable(props.id) + + const form = yield* SynchronizedForm.service({ + schema: TodoFormSchema, + target: state.getElementLens(props.id), + }) + + return [ + indexSubscribable, + Form.focusObjectOn(form, "content"), + Form.focusObjectOn(form, "completedAt"), + ] as const + }), [props.id]) + + const [index, size] = yield* Subscribable.useAll([ + indexSubscribable, + state.sizeSubscribable, + ]) + + const runSync = yield* Component.useRunSync() + const TextFieldFormInput = yield* TextFieldFormInputView.use + const TextFieldOptionalFormInput = yield* TextFieldOptionalFormInputView.use + + + return ( + + + + + + + + + + + + + runSync(state.moveLeft(props.id))} + > + + + + = size - 1} + onClick={() => runSync(state.moveRight(props.id))} + > + + + + runSync(state.remove(props.id))}> + + + + + ) +}) {} diff --git a/packages/example-next/src/todo/NewTodoView.tsx b/packages/example-next/src/todo/NewTodoView.tsx new file mode 100644 index 0000000..e382778 --- /dev/null +++ b/packages/example-next/src/todo/NewTodoView.tsx @@ -0,0 +1,78 @@ +import { Box, Button, Flex } from "@radix-ui/themes" +import { GetRandomValues, makeUuid4 } from "@typed/id" +import { Chunk, type DateTime, Effect, Option, Schema } from "effect" +import { Component, Form, Lens, SubmittableForm, Subscribable } from "effect-fc" +import * as Domain from "@/domain" +import { TextFieldFormInputView } from "@/lib/form/TextFieldFormInputView" +import { TextFieldOptionalFormInputView } from "@/lib/form/TextFieldOptionalFormInputView" +import { TodoFormSchema } from "./TodoFormSchema" +import { TodosState } from "./TodosState" + + +const makeTodo = makeUuid4.pipe( + Effect.map(id => Domain.Todo.Todo.make({ + id, + content: "", + completedAt: Option.none(), + })), + Effect.provide(GetRandomValues.CryptoRandom), +) + + +export class NewTodoView extends Component.make("NewTodoView")(function*() { + const state = yield* TodosState + + const [ + form, + contentField, + completedAtField, + ] = yield* Component.useOnMount(() => Effect.gen(function*() { + const form = yield* SubmittableForm.service({ + schema: TodoFormSchema, + initialEncodedValue: yield* Schema.encode(TodoFormSchema)(yield* makeTodo), + f: ([todo, form]) => Lens.update(state.lens, Chunk.prepend(todo)).pipe( + Effect.andThen(makeTodo), + Effect.andThen(Schema.encode(TodoFormSchema)), + Effect.andThen(v => Lens.set(form.encodedValue, v)), + ), + }) + + return [ + form, + Form.focusObjectOn(form, "content"), + Form.focusObjectOn(form, "completedAt"), + ] as const + })) + + const [canCommit] = yield* Subscribable.useAll([form.canCommit]) + + const runPromise = yield* Component.useRunPromise() + const TextFieldFormInput = yield* TextFieldFormInputView.use + const TextFieldOptionalFormInput = yield* TextFieldOptionalFormInputView.use + + + return ( + + + + + + + + + + + + + + ) +}) {} diff --git a/packages/example-next/src/todo/TodoFormSchema.ts b/packages/example-next/src/todo/TodoFormSchema.ts new file mode 100644 index 0000000..b2d4153 --- /dev/null +++ b/packages/example-next/src/todo/TodoFormSchema.ts @@ -0,0 +1,9 @@ +import { Schema } from "effect" +import * as Domain from "@/domain" +import { DateTimeUtcFromZonedInput } from "@/lib/schema" + + +export const TodoFormSchema = Schema.compose(Schema.Struct({ + ...Domain.Todo.Todo.fields, + completedAt: Schema.OptionFromSelf(DateTimeUtcFromZonedInput), +}), Domain.Todo.Todo) diff --git a/packages/example-next/src/todo/TodosState.ts b/packages/example-next/src/todo/TodosState.ts new file mode 100644 index 0000000..d77041d --- /dev/null +++ b/packages/example-next/src/todo/TodosState.ts @@ -0,0 +1,96 @@ +import { KeyValueStore } from "@effect/platform" +import { BrowserKeyValueStore } from "@effect/platform-browser" +import { Chunk, Console, Effect, Option, Schema, Stream, SubscriptionRef } from "effect" +import { Lens, Subscribable } from "effect-fc" +import { Todo } from "@/domain" + + +export class TodosState extends Effect.Service()("TodosState", { + scoped: Effect.fnUntraced(function*(key: string) { + const kv = yield* KeyValueStore.KeyValueStore + + const readFromLocalStorage = Console.log("Reading todos from local storage...").pipe( + Effect.andThen(kv.get(key)), + Effect.andThen(Option.match({ + onSome: Schema.decode( + Schema.parseJson(Schema.Chunk(Todo.TodoFromJson)) + ), + onNone: () => Effect.succeed(Chunk.empty()), + })) + ) + const saveToLocalStorage = (todos: Chunk.Chunk) => Effect.andThen( + Console.log("Saving todos to local storage..."), + Chunk.isNonEmpty(todos) + ? Effect.andThen( + Schema.encode( + Schema.parseJson(Schema.Chunk(Todo.TodoFromJson)) + )(todos), + v => kv.set(key, v), + ) + : kv.remove(key) + ) + + const lens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(yield* readFromLocalStorage)) + yield* Effect.forkScoped(lens.changes.pipe( + Stream.debounce("500 millis"), + Stream.runForEach(saveToLocalStorage), + )) + yield* Effect.addFinalizer(() => Lens.get(lens).pipe( + Effect.andThen(saveToLocalStorage), + Effect.ignore, + )) + + const sizeSubscribable = Subscribable.map(lens, Chunk.size) + + const getElementLens = (id: string) => Lens.mapEffect( + lens, + Chunk.findFirst(v => v.id === id), + (a, b) => Effect.flatMap( + Chunk.findFirstIndex(a, v => v.id === id), + i => Chunk.replaceOption(a, i, b), + ) + ) + const getIndexSubscribable = (id: string) => Subscribable.mapEffect(lens, Chunk.findFirstIndex(v => v.id === id)) + + const moveLeft = (id: string) => Lens.updateEffect(lens, todos => Effect.Do.pipe( + Effect.bind("index", () => Chunk.findFirstIndex(todos, v => v.id === id)), + Effect.bind("todo", ({ index }) => Chunk.get(todos, index)), + Effect.bind("previous", ({ index }) => Chunk.get(todos, index - 1)), + Effect.andThen(({ todo, index, previous }) => index > 0 + ? todos.pipe( + Chunk.replace(index, previous), + Chunk.replace(index - 1, todo), + ) + : todos + ), + )) + const moveRight = (id: string) => Lens.updateEffect(lens, todos => Effect.Do.pipe( + Effect.bind("index", () => Chunk.findFirstIndex(todos, v => v.id === id)), + Effect.bind("todo", ({ index }) => Chunk.get(todos, index)), + Effect.bind("next", ({ index }) => Chunk.get(todos, index + 1)), + Effect.andThen(({ todo, index, next }) => index < Chunk.size(todos) - 1 + ? todos.pipe( + Chunk.replace(index, next), + Chunk.replace(index + 1, todo), + ) + : todos + ), + )) + const remove = (id: string) => Lens.updateEffect(lens, todos => Effect.andThen( + Chunk.findFirstIndex(todos, v => v.id === id), + index => Chunk.remove(todos, index), + )) + + return { + lens, + sizeSubscribable, + getElementLens, + getIndexSubscribable, + moveLeft, + moveRight, + remove, + } as const + }), + + dependencies: [BrowserKeyValueStore.layerLocalStorage], +}) {} diff --git a/packages/example-next/src/todo/TodosView.tsx b/packages/example-next/src/todo/TodosView.tsx new file mode 100644 index 0000000..b935681 --- /dev/null +++ b/packages/example-next/src/todo/TodosView.tsx @@ -0,0 +1,34 @@ +import { Container, Flex, Heading } from "@radix-ui/themes" +import { Chunk, Console, Effect } from "effect" +import { Component, Subscribable } from "effect-fc" +import { EditTodoView } from "./EditTodoView" +import { NewTodoView } from "./NewTodoView" +import { TodosState } from "./TodosState" + + +export class TodosView extends Component.make("TodosView")(function*() { + const state = yield* TodosState + const [todos] = yield* Subscribable.useAll([state.lens]) + + yield* Component.useOnMount(() => Effect.andThen( + Console.log("Todos mounted"), + Effect.addFinalizer(() => Console.log("Todos unmounted")), + )) + + const NewTodo = yield* NewTodoView.use + const EditTodo = yield* EditTodoView.use + + return ( + + Todos + + + + + {Chunk.map(todos, todo => + + )} + + + ) +}) {} diff --git a/packages/example-next/tsconfig.app.json b/packages/example-next/tsconfig.app.json index f95336a..b823bd2 100644 --- a/packages/example-next/tsconfig.app.json +++ b/packages/example-next/tsconfig.app.json @@ -22,6 +22,10 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true, + "paths": { + "@/*": ["./src/*"] + }, + "plugins": [ { "name": "@effect/language-service" } ] diff --git a/packages/example-next/vite.config.ts b/packages/example-next/vite.config.ts index 5c94b15..79367b3 100644 --- a/packages/example-next/vite.config.ts +++ b/packages/example-next/vite.config.ts @@ -1,10 +1,22 @@ +import { tanstackRouter } from "@tanstack/router-plugin/vite" import react from "@vitejs/plugin-react" +import path from "node:path" import { defineConfig } from "vite" // https://vite.dev/config/ export default defineConfig({ plugins: [ + tanstackRouter({ + target: "react", + autoCodeSplitting: true, + }), react(), ], + + resolve: { + alias: { + "@": path.resolve(__dirname, "./src"), + }, + }, }) -- 2.52.0 From 31d87ffcabdd3651c5eb861d6043e0deefe8febb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 19 Jul 2026 04:00:46 +0200 Subject: [PATCH 60/61] Fix --- packages/example-next/src/domain/Todo.ts | 20 --- packages/example-next/src/domain/index.ts | 1 - .../src/lib/form/TextFieldFormInputView.tsx | 6 +- .../form/TextFieldOptionalFormInputView.tsx | 6 +- .../example-next/src/lib/schema/datetime.ts | 38 ----- packages/example-next/src/lib/schema/index.ts | 2 - packages/example-next/src/lib/schema/json.ts | 6 - packages/example-next/src/main.tsx | 100 +---------- packages/example-next/src/post.ts | 15 ++ packages/example-next/src/routeTree.gen.ts | 67 +------- packages/example-next/src/routes/__root.tsx | 6 +- packages/example-next/src/routes/async.tsx | 39 ++--- .../example-next/src/routes/dev/context.tsx | 42 ----- packages/example-next/src/routes/dev/memo.tsx | 37 ---- packages/example-next/src/routes/form.tsx | 158 +++++------------- packages/example-next/src/routes/index.tsx | 56 +++++-- packages/example-next/src/routes/query.tsx | 128 ++++++-------- packages/example-next/src/routes/result.tsx | 79 ++++----- packages/example-next/src/runtime.ts | 15 +- .../example-next/src/todo/EditTodoView.tsx | 88 ---------- .../example-next/src/todo/NewTodoView.tsx | 78 --------- .../example-next/src/todo/TodoFormSchema.ts | 9 - packages/example-next/src/todo/TodosState.ts | 96 ----------- packages/example-next/src/todo/TodosView.tsx | 34 ---- 24 files changed, 219 insertions(+), 907 deletions(-) delete mode 100644 packages/example-next/src/domain/Todo.ts delete mode 100644 packages/example-next/src/domain/index.ts delete mode 100644 packages/example-next/src/lib/schema/datetime.ts delete mode 100644 packages/example-next/src/lib/schema/index.ts delete mode 100644 packages/example-next/src/lib/schema/json.ts create mode 100644 packages/example-next/src/post.ts delete mode 100644 packages/example-next/src/routes/dev/context.tsx delete mode 100644 packages/example-next/src/routes/dev/memo.tsx delete mode 100644 packages/example-next/src/todo/EditTodoView.tsx delete mode 100644 packages/example-next/src/todo/NewTodoView.tsx delete mode 100644 packages/example-next/src/todo/TodoFormSchema.ts delete mode 100644 packages/example-next/src/todo/TodosState.ts delete mode 100644 packages/example-next/src/todo/TodosView.tsx diff --git a/packages/example-next/src/domain/Todo.ts b/packages/example-next/src/domain/Todo.ts deleted file mode 100644 index 500faab..0000000 --- a/packages/example-next/src/domain/Todo.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Schema } from "effect" -import { assertEncodedJsonifiable } from "@/lib/schema" - - -export class Todo extends Schema.Class("Todo")({ - _tag: Schema.tag("Todo"), - id: Schema.String, - content: Schema.String, - completedAt: Schema.OptionFromSelf(Schema.DateTimeUtcFromSelf), -}) {} - - -export const TodoFromJsonStruct = Schema.Struct({ - ...Todo.fields, - completedAt: Schema.Option(Schema.DateTimeUtc), -}).pipe( - assertEncodedJsonifiable -) - -export const TodoFromJson = Schema.compose(TodoFromJsonStruct, Todo) diff --git a/packages/example-next/src/domain/index.ts b/packages/example-next/src/domain/index.ts deleted file mode 100644 index 8d70c13..0000000 --- a/packages/example-next/src/domain/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * as Todo from "./Todo" diff --git a/packages/example-next/src/lib/form/TextFieldFormInputView.tsx b/packages/example-next/src/lib/form/TextFieldFormInputView.tsx index ca4f843..48241a9 100644 --- a/packages/example-next/src/lib/form/TextFieldFormInputView.tsx +++ b/packages/example-next/src/lib/form/TextFieldFormInputView.tsx @@ -1,6 +1,6 @@ import { Callout, Flex, Spinner, TextField } from "@radix-ui/themes" import { Array, Option, Struct } from "effect" -import { Component, Form, Subscribable } from "effect-fc" +import { Component, Form, View } from "effect-fc-next" import type * as React from "react" @@ -17,7 +17,7 @@ export const TextFieldFormInputView = Component.make("TextFieldFormInputView")(f props: TextFieldFormInputView.Props ) { const input = yield* Form.useInput(props.form, props) - const [issues, isValidating, isCommitting] = yield* Subscribable.useAll([ + const [issues, isValidating, isCommitting] = yield* View.useAll([ props.form.issues, props.form.isValidating, props.form.isCommitting, @@ -29,7 +29,7 @@ export const TextFieldFormInputView = Component.make("TextFieldFormInputView")(f value={input.value} onChange={e => input.setValue(e.target.value)} disabled={isCommitting} - {...Struct.omit(props, "form")} + {...Struct.omit(props, ["form"])} > {isValidating && diff --git a/packages/example-next/src/lib/form/TextFieldOptionalFormInputView.tsx b/packages/example-next/src/lib/form/TextFieldOptionalFormInputView.tsx index 68693ea..cd2bea4 100644 --- a/packages/example-next/src/lib/form/TextFieldOptionalFormInputView.tsx +++ b/packages/example-next/src/lib/form/TextFieldOptionalFormInputView.tsx @@ -1,6 +1,6 @@ import { Callout, Flex, Spinner, Switch, TextField } from "@radix-ui/themes" import { Array, Option, Struct } from "effect" -import { Component, Form, Subscribable } from "effect-fc" +import { Component, Form, View } from "effect-fc-next" import type * as React from "react" @@ -17,7 +17,7 @@ export const TextFieldOptionalFormInputView = Component.make("TextFieldOptionalF props: TextFieldOptionalFormInputView.Props ) { const input = yield* Form.useOptionalInput(props.form, props) - const [issues, isValidating, isCommitting] = yield* Subscribable.useAll([ + const [issues, isValidating, isCommitting] = yield* View.useAll([ props.form.issues, props.form.isValidating, props.form.isCommitting, @@ -29,7 +29,7 @@ export const TextFieldOptionalFormInputView = Component.make("TextFieldOptionalF value={input.value} onChange={e => input.setValue(e.target.value)} disabled={!input.enabled || isCommitting} - {...Struct.omit(props, "form", "defaultValue")} + {...Struct.omit(props, ["form", "defaultValue"])} > ParseResult.succeed(DateTime.toUtc(i)), - }, -) {} - -export class DateTimeZonedFromUtc extends Schema.transformOrFail( - Schema.DateTimeUtcFromSelf, - Schema.DateTimeZonedFromSelf, - { - strict: true, - encode: a => ParseResult.succeed(DateTime.toUtc(a)), - decode: DateTime.setZoneCurrent, - }, -) {} - -export class DateTimeUtcFromZonedInput extends Schema.transformOrFail( - Schema.String, - DateTimeUtcFromZoned, - { - strict: true, - encode: a => ParseResult.succeed(DateTime.formatIsoZoned(a).slice(0, 16)), - decode: (i, _, ast) => Effect.flatMap( - DateTime.CurrentTimeZone, - timeZone => Option.match(DateTime.makeZoned(i, { timeZone, adjustForTimeZone: true }), { - onSome: ParseResult.succeed, - onNone: () => ParseResult.fail(new ParseResult.Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a DateTime.Zoned`)), - }), - ), - }, -) {} diff --git a/packages/example-next/src/lib/schema/index.ts b/packages/example-next/src/lib/schema/index.ts deleted file mode 100644 index 260895c..0000000 --- a/packages/example-next/src/lib/schema/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./datetime" -export * from "./json" diff --git a/packages/example-next/src/lib/schema/json.ts b/packages/example-next/src/lib/schema/json.ts deleted file mode 100644 index 5b69cc4..0000000 --- a/packages/example-next/src/lib/schema/json.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { Schema } from "effect" -import type { JsonValue } from "type-fest" - - -export const assertEncodedJsonifiable = , A, I extends JsonValue, R>(schema: S & Schema.Schema): S => schema -export const assertTypeJsonifiable = , A extends JsonValue, I, R>(schema: S & Schema.Schema): S => schema diff --git a/packages/example-next/src/main.tsx b/packages/example-next/src/main.tsx index 59d0c0c..1ed395f 100644 --- a/packages/example-next/src/main.tsx +++ b/packages/example-next/src/main.tsx @@ -1,103 +1,21 @@ -import { Effect, Layer, Schema, SubscriptionRef } from "effect" -import { - Component, - Form, - Lens, - LensForm, - MutationForm, - ReactRuntime, - View, -} from "effect-fc-next" +import { createRouter, RouterProvider } from "@tanstack/react-router" +import { ReactRuntime } from "effect-fc-next" import { StrictMode } from "react" import { createRoot } from "react-dom/client" -import "./index.css" +import { routeTree } from "./routeTree.gen" +import { runtime } from "./runtime" +const router = createRouter({ routeTree }) -const runtime = ReactRuntime.make(Layer.empty) - -const MutationFormExample = Component.make("MutationFormExample")(function*() { - const form = yield* Component.useOnMount(() => MutationForm.service({ - schema: Schema.String, - initialEncodedValue: "", - f: ([value]) => Effect.log(`Submitted: ${value}`), - })) - const input = yield* Form.useInput(form) - const [canCommit, isCommitting, issues] = yield* View.useAll([ - form.canCommit, - form.isCommitting, - form.issues, - ]) - const runPromise = yield* Component.useRunPromise() - - return ( -
-

MutationForm

-

Owns a draft and commits it explicitly through a Mutation.

-
{ - event.preventDefault() - void runPromise(form.submit) - }}> - input.setValue(event.currentTarget.value)} - disabled={isCommitting} - placeholder="Write something to submit" - /> - -
- {issues.map((issue) =>

{issue.message}

)} -
- ) -}).pipe(Component.withRuntime(runtime.context)) - -const LensFormExample = Component.make("LensFormExample")(function*() { - const target = yield* Component.useOnMount(() => Effect.map( - SubscriptionRef.make("A value owned by the application"), - Lens.fromSubscriptionRef, - )) - const form = yield* Component.useOnMount(() => LensForm.service({ - schema: Schema.String, - target, - })) - const input = yield* Form.useInput(form) - const [value, canCommit, isCommitting, issues] = yield* View.useAll([ - target, - form.canCommit, - form.isCommitting, - form.issues, - ]) - - return ( -
-

LensForm

-

Synchronizes valid input directly with a target Lens.

- input.setValue(event.currentTarget.value)} - disabled={!canCommit || isCommitting} - /> -

Target value: {value}

- {issues.map((issue) =>

{issue.message}

)} -
- ) -}).pipe(Component.withRuntime(runtime.context)) - -const App = () => ( -
-

Effect FC Next

-

Effect v4 examples for the finalized form API.

- - -
-) +declare module "@tanstack/react-router" { + interface Register { router: typeof router } +} // biome-ignore lint/style/noNonNullAssertion: the Vite template provides this element createRoot(document.getElementById("root")!).render( - + , ) diff --git a/packages/example-next/src/post.ts b/packages/example-next/src/post.ts new file mode 100644 index 0000000..2bbe6e6 --- /dev/null +++ b/packages/example-next/src/post.ts @@ -0,0 +1,15 @@ +import { Effect } from "effect" + + +export interface Post { + readonly title: string + readonly body: string +} + +export const fetchPost = (id: number) => Effect.tryPromise({ + try: () => + fetch(`https://jsonplaceholder.typicode.com/posts/${id}`) + .then(response => response.json() as Promise), + + catch: () => new Error("Unable to fetch post"), +}) diff --git a/packages/example-next/src/routeTree.gen.ts b/packages/example-next/src/routeTree.gen.ts index 3ad431c..5c09612 100644 --- a/packages/example-next/src/routeTree.gen.ts +++ b/packages/example-next/src/routeTree.gen.ts @@ -15,8 +15,6 @@ import { Route as BlankRouteImport } from './routes/blank' import { Route as FormRouteImport } from './routes/form' import { Route as QueryRouteImport } from './routes/query' import { Route as ResultRouteImport } from './routes/result' -import { Route as DevContextRouteImport } from './routes/dev/context' -import { Route as DevMemoRouteImport } from './routes/dev/memo' const IndexRoute = IndexRouteImport.update({ id: '/', @@ -48,16 +46,6 @@ const ResultRoute = ResultRouteImport.update({ path: '/result', getParentRoute: () => rootRouteImport, } as any) -const DevContextRoute = DevContextRouteImport.update({ - id: '/dev/context', - path: '/dev/context', - getParentRoute: () => rootRouteImport, -} as any) -const DevMemoRoute = DevMemoRouteImport.update({ - id: '/dev/memo', - path: '/dev/memo', - getParentRoute: () => rootRouteImport, -} as any) export interface FileRoutesByFullPath { '/': typeof IndexRoute @@ -66,8 +54,6 @@ export interface FileRoutesByFullPath { '/form': typeof FormRoute '/query': typeof QueryRoute '/result': typeof ResultRoute - '/dev/context': typeof DevContextRoute - '/dev/memo': typeof DevMemoRoute } export interface FileRoutesByTo { '/': typeof IndexRoute @@ -76,8 +62,6 @@ export interface FileRoutesByTo { '/form': typeof FormRoute '/query': typeof QueryRoute '/result': typeof ResultRoute - '/dev/context': typeof DevContextRoute - '/dev/memo': typeof DevMemoRoute } export interface FileRoutesById { __root__: typeof rootRouteImport @@ -87,40 +71,13 @@ export interface FileRoutesById { '/form': typeof FormRoute '/query': typeof QueryRoute '/result': typeof ResultRoute - '/dev/context': typeof DevContextRoute - '/dev/memo': typeof DevMemoRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: - | '/' - | '/async' - | '/blank' - | '/form' - | '/query' - | '/result' - | '/dev/context' - | '/dev/memo' + fullPaths: '/' | '/async' | '/blank' | '/form' | '/query' | '/result' fileRoutesByTo: FileRoutesByTo - to: - | '/' - | '/async' - | '/blank' - | '/form' - | '/query' - | '/result' - | '/dev/context' - | '/dev/memo' - id: - | '__root__' - | '/' - | '/async' - | '/blank' - | '/form' - | '/query' - | '/result' - | '/dev/context' - | '/dev/memo' + to: '/' | '/async' | '/blank' | '/form' | '/query' | '/result' + id: '__root__' | '/' | '/async' | '/blank' | '/form' | '/query' | '/result' fileRoutesById: FileRoutesById } export interface RootRouteChildren { @@ -130,8 +87,6 @@ export interface RootRouteChildren { FormRoute: typeof FormRoute QueryRoute: typeof QueryRoute ResultRoute: typeof ResultRoute - DevContextRoute: typeof DevContextRoute - DevMemoRoute: typeof DevMemoRoute } declare module '@tanstack/react-router' { @@ -178,20 +133,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ResultRouteImport parentRoute: typeof rootRouteImport } - '/dev/context': { - id: '/dev/context' - path: '/dev/context' - fullPath: '/dev/context' - preLoaderRoute: typeof DevContextRouteImport - parentRoute: typeof rootRouteImport - } - '/dev/memo': { - id: '/dev/memo' - path: '/dev/memo' - fullPath: '/dev/memo' - preLoaderRoute: typeof DevMemoRouteImport - parentRoute: typeof rootRouteImport - } } } @@ -202,8 +143,6 @@ const rootRouteChildren: RootRouteChildren = { FormRoute: FormRoute, QueryRoute: QueryRoute, ResultRoute: ResultRoute, - DevContextRoute: DevContextRoute, - DevMemoRoute: DevMemoRoute, } export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) diff --git a/packages/example-next/src/routes/__root.tsx b/packages/example-next/src/routes/__root.tsx index 67b0910..c9826b6 100644 --- a/packages/example-next/src/routes/__root.tsx +++ b/packages/example-next/src/routes/__root.tsx @@ -7,7 +7,7 @@ import "../index.css" export const Route = createRootRoute({ - component: Root + component: Root, }) function Root() { @@ -17,6 +17,10 @@ function Root() { Index Blank + Async + Query + Result + Form diff --git a/packages/example-next/src/routes/async.tsx b/packages/example-next/src/routes/async.tsx index 62e0234..4be061b 100644 --- a/packages/example-next/src/routes/async.tsx +++ b/packages/example-next/src/routes/async.tsx @@ -1,30 +1,22 @@ -import { HttpClient } from "@effect/platform" import { Container, Flex, Heading, Slider, Text, TextField } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" -import { Array, Effect, flow, Option, Schema } from "effect" -import { Async, Component, Memoized } from "effect-fc" +import { Async, Component, Memoized } from "effect-fc-next" import * as React from "react" +import { fetchPost } from "@/post" import { runtime } from "@/runtime" -const Post = Schema.Struct({ - userId: Schema.Int, - id: Schema.Int, - title: Schema.String, - body: Schema.String, -}) - interface AsyncFetchPostViewProps { readonly id: number } -class AsyncFetchPostView extends Component.make("AsyncFetchPostView")(function*(props: AsyncFetchPostViewProps) { - const post = yield* Component.useOnChange(() => HttpClient.HttpClient.pipe( - Effect.tap(Effect.sleep("500 millis")), - Effect.andThen(client => client.get(`https://jsonplaceholder.typicode.com/posts/${ props.id }`)), - Effect.andThen(response => response.json), - Effect.andThen(Schema.decodeUnknown(Post)), - ), [props.id]) +const AsyncFetchPostView = Component.make("AsyncFetchPostView")(function*( + props: AsyncFetchPostViewProps, +) { + const post = yield* Component.useOnChange( + () => fetchPost(props.id), + [props.id], + ) return (
@@ -34,10 +26,9 @@ class AsyncFetchPostView extends Component.make("AsyncFetchPostView")(function*( ) }).pipe( Async.async, - Async.withOptions({ defaultFallback: Default fallback }), + Async.withOptions({ defaultFallback: Loading post... }), Memoized.memoized, -) {} - +) const AsyncRouteComponent = Component.make("AsyncRouteView")(function*() { const [text, setText] = React.useState("Typing here should not trigger a refetch of the post") @@ -50,12 +41,14 @@ const AsyncRouteComponent = Component.make("AsyncRouteView")(function*() { setText(e.currentTarget.value)} + onChange={event => setText(event.currentTarget.value)} /> setId(value ?? 1)} /> Loading post...} /> @@ -63,7 +56,7 @@ const AsyncRouteComponent = Component.make("AsyncRouteView")(function*() { ) }).pipe( - Component.withRuntime(runtime.context) + Component.withRuntime(runtime.context), ) export const Route = createFileRoute("/async")({ diff --git a/packages/example-next/src/routes/dev/context.tsx b/packages/example-next/src/routes/dev/context.tsx deleted file mode 100644 index 26048a9..0000000 --- a/packages/example-next/src/routes/dev/context.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { Container, Flex, Text, TextField } from "@radix-ui/themes" -import { createFileRoute } from "@tanstack/react-router" -import { Console, Effect } from "effect" -import { Component } from "effect-fc" -import * as React from "react" -import { runtime } from "@/runtime" - - -class SubService extends Effect.Service()("SubService", { - effect: (value: string) => Effect.succeed({ value }) -}) {} - -const SubComponent = Component.makeUntraced("SubComponent")(function*() { - const service = yield* SubService - yield* Component.useOnMount(() => Effect.gen(function*() { - yield* Effect.addFinalizer(() => Console.log("SubComponent unmounted")) - yield* Console.log("SubComponent mounted") - })) - - return {service.value} -}) - -const ContextView = Component.makeUntraced("ContextView")(function*() { - const [serviceValue, setServiceValue] = React.useState("test") - const SubServiceLayer = React.useMemo(() => SubService.Default(serviceValue), [serviceValue]) - const SubComponentFC = yield* Effect.provide(SubComponent.use, yield* Component.useContextFromLayer(SubServiceLayer)) - - return ( - - - setServiceValue(e.target.value)} /> - - - - ) -}).pipe( - Component.withRuntime(runtime.context) -) - -export const Route = createFileRoute("/dev/context")({ - component: ContextView -}) diff --git a/packages/example-next/src/routes/dev/memo.tsx b/packages/example-next/src/routes/dev/memo.tsx deleted file mode 100644 index ae672bd..0000000 --- a/packages/example-next/src/routes/dev/memo.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Flex, Text, TextField } from "@radix-ui/themes" -import { createFileRoute } from "@tanstack/react-router" -import { GetRandomValues, makeUuid4 } from "@typed/id" -import { Effect } from "effect" -import { Component, Memoized } from "effect-fc" -import * as React from "react" -import { runtime } from "@/runtime" - - -const RouteComponent = Component.makeUntraced("RouteComponent")(function*() { - const [value, setValue] = React.useState("") - - return ( - - setValue(e.target.value)} - /> - - {yield* Effect.map(SubComponent.use, FC => )} - {yield* Effect.map(MemoizedSubComponent.use, FC => )} - - ) -}).pipe( - Component.withRuntime(runtime.context) -) - -class SubComponent extends Component.makeUntraced("SubComponent")(function*() { - const id = yield* makeUuid4.pipe(Effect.provide(GetRandomValues.CryptoRandom)) - return {id} -}) {} - -class MemoizedSubComponent extends Memoized.memoized(SubComponent) {} - -export const Route = createFileRoute("/dev/memo")({ - component: RouteComponent, -}) diff --git a/packages/example-next/src/routes/form.tsx b/packages/example-next/src/routes/form.tsx index 9ce3fae..88885a4 100644 --- a/packages/example-next/src/routes/form.tsx +++ b/packages/example-next/src/routes/form.tsx @@ -1,143 +1,63 @@ -import { Button, Container, Flex, Text } from "@radix-ui/themes" +import { Button, Container, Flex, Text, TextField } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" -import { Console, Effect, Match, Option, ParseResult, Schema } from "effect" -import { Component, Form, SubmittableForm, Subscribable } from "effect-fc" -import { TextFieldFormInputView } from "@/lib/form/TextFieldFormInputView" -import { TextFieldOptionalFormInputView } from "@/lib/form/TextFieldOptionalFormInputView" -import { DateTimeUtcFromZonedInput } from "@/lib/schema" +import { Effect, Schema } from "effect" +import { Component, Form, MutationForm, View } from "effect-fc-next" import { runtime } from "@/runtime" -const email = Schema.pattern( - /^(?!\.)(?!.*\.\.)([A-Z0-9_+-.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9-]*\.)+[A-Z]{2,}$/i, - - { - identifier: "email", - title: "email", - message: () => "Not an email address", - }, -) - -const RegisterFormSchema = Schema.Struct({ - email: Schema.String.pipe(email), - password: Schema.String.pipe(Schema.minLength(3)), - birth: Schema.OptionFromSelf(DateTimeUtcFromZonedInput), -}) - -const RegisterFormSubmitSchema = Schema.Struct({ - email: Schema.transformOrFail( - Schema.String, - Schema.String, - { - decode: (input, _options, ast) => input !== "admin@admin.com" - ? ParseResult.succeed(input) - : ParseResult.fail(new ParseResult.Type(ast, input, "This email is already in use.")), - encode: ParseResult.succeed, - }, - ), +const RegisterSchema = Schema.Struct({ + email: Schema.String, password: Schema.String, - birth: Schema.OptionFromSelf(Schema.DateTimeUtcFromSelf), }) -class RegisterFormService extends Effect.Service()("RegisterFormService", { - scoped: Effect.gen(function*() { - const form = yield* SubmittableForm.service({ - schema: RegisterFormSchema.pipe( - Schema.compose( - Schema.transformOrFail( - Schema.typeSchema(RegisterFormSchema), - Schema.typeSchema(RegisterFormSchema), - { - decode: v => Effect.andThen(Effect.sleep("500 millis"), ParseResult.succeed(v)), - encode: ParseResult.succeed, - }, - ), - ), - ), - - initialEncodedValue: { email: "", password: "", birth: Option.none() }, - f: Effect.fnUntraced(function*([value]) { - yield* Effect.sleep("500 millis") - return yield* Schema.decode(RegisterFormSubmitSchema)(value) - }), - }) - - return { - form, - emailField: Form.focusObjectOn(form, "email"), - passwordField: Form.focusObjectOn(form, "password"), - birthField: Form.focusObjectOn(form, "birth"), - } as const - }) -}) {} - -class RegisterFormView extends Component.make("RegisterFormView")(function*() { - const form = yield* RegisterFormService - const [canCommit, submitResult] = yield* Subscribable.useAll([ - form.form.canCommit, - form.form.mutation.result, - ]) - - const runPromise = yield* Component.useRunPromise() - const TextFieldFormInput = yield* TextFieldFormInputView.use - const TextFieldOptionalFormInput = yield* TextFieldOptionalFormInputView.use - - yield* Component.useOnMount(() => Effect.gen(function*() { - yield* Effect.addFinalizer(() => Console.log("RegisterFormView unmounted")) - yield* Console.log("RegisterFormView mounted") +const RegisterRouteComponent = Component.make("RegisterRouteView")(function*() { + const form = yield* Component.useOnMount(() => MutationForm.service({ + schema: RegisterSchema, + initialEncodedValue: { email: "", password: "" }, + f: ([value]) => Effect.log(`Registered ${value.email}`), })) - + const emailField = yield* Form.useInput( + Form.focusObjectOn(form, "email"), + ) + const passwordField = yield* Form.useInput( + Form.focusObjectOn(form, "password"), + ) + const [canCommit, isCommitting] = yield* View.useAll([ + form.canCommit, + form.isCommitting, + ]) + const runPromise = yield* Component.useRunPromise() return ( -
{ - e.preventDefault() - void runPromise(form.form.submit) + { + event.preventDefault() + void runPromise(form.submit) }}> - emailField.setValue(event.currentTarget.value)} + placeholder="Email" /> - - passwordField.setValue(event.currentTarget.value)} + placeholder="Password" + type="password" /> - - - - +
- - {Match.value(submitResult).pipe( - Match.tag("Initial", () => <>), - Match.tag("Running", () => Submitting...), - Match.tag("Success", () => Submitted successfully!), - Match.tag("Failure", e => Error: {e.cause.toString()}), - Match.exhaustive, - )} + A MutationForm validates local input, then submits it.
) -}) {} - -const RegisterPage = Component.make("RegisterPageView")(function*() { - const RegisterForm = yield* Effect.provide( - RegisterFormView.use, - yield* Component.useContextFromLayer(RegisterFormService.Default), - ) - - return }).pipe( - Component.withRuntime(runtime.context) + Component.withRuntime(runtime.context), ) - export const Route = createFileRoute("/form")({ - component: RegisterPage + component: RegisterRouteComponent, }) diff --git a/packages/example-next/src/routes/index.tsx b/packages/example-next/src/routes/index.tsx index d747b39..0b4d271 100644 --- a/packages/example-next/src/routes/index.tsx +++ b/packages/example-next/src/routes/index.tsx @@ -1,24 +1,56 @@ +import { Button, Container, Flex, Text, TextField } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" -import { Effect } from "effect" -import { Component } from "effect-fc" +import { Effect, SubscriptionRef } from "effect" +import { Component, Lens, View } from "effect-fc-next" import { runtime } from "@/runtime" -import { TodosState } from "@/todo/TodosState" -import { TodosView } from "@/todo/TodosView" -const TodosStateLive = TodosState.Default("todos") +const TodoRouteComponent = Component.make("TodoRouteView")(function*() { + const todosLens = yield* Component.useOnMount(() => Effect.map( + SubscriptionRef.make([]), + Lens.fromSubscriptionRef, + )) + const draftLens = yield* Component.useOnMount(() => Effect.map( + SubscriptionRef.make(""), + Lens.fromSubscriptionRef, + )) -const Index = Component.make("IndexView")(function*() { - const Todos = yield* Effect.provide( - TodosView.use, - yield* Component.useContextFromLayer(TodosStateLive), + const [todos] = yield* View.useAll([todosLens]) + const [draft, setDraft] = yield* Lens.useState(draftLens) + const runPromise = yield* Component.useRunPromise() + + const addTodo = Lens.update(todosLens, todos => + draft.trim() === "" + ? todos + : [...todos, draft.trim()], + ).pipe( + Effect.andThen(Lens.set(draftLens, "")), ) - return + return ( + + + A small Effect v4 todo state example backed by a Lens. + + + setDraft(event.currentTarget.value)} + /> + + + + + {todos.map(todo => • {todo})} + + + ) }).pipe( - Component.withRuntime(runtime.context) + Component.withRuntime(runtime.context), ) export const Route = createFileRoute("/")({ - component: Index + component: TodoRouteComponent, }) diff --git a/packages/example-next/src/routes/query.tsx b/packages/example-next/src/routes/query.tsx index 047560e..a97a8bf 100644 --- a/packages/example-next/src/routes/query.tsx +++ b/packages/example-next/src/routes/query.tsx @@ -1,117 +1,85 @@ -import { HttpClient, type HttpClientError } from "@effect/platform" import { Button, Container, Flex, Heading, Slider, Text } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" -import { Array, Cause, Chunk, Console, Effect, flow, Match, Option, Schema, Stream, SubscriptionRef } from "effect" -import { Component, ErrorObserver, Lens, Mutation, Query, Result, Subscribable } from "effect-fc" +import { Effect, SubscriptionRef } from "effect" +import { AsyncResult } from "effect/unstable/reactivity" +import { Component, Lens, Mutation, Query, View } from "effect-fc-next" +import { fetchPost, type Post } from "@/post" import { runtime } from "@/runtime" -const Post = Schema.Struct({ - userId: Schema.Int, - id: Schema.Int, - title: Schema.String, - body: Schema.String, -}) +interface PostResultViewProps { + readonly result: AsyncResult.AsyncResult +} -const ResultView = Component.make("ResultView")(function*() { - const runPromise = yield* Component.useRunPromise() +const PostResultView = (props: PostResultViewProps) => + AsyncResult.match(props.result, { + onInitial: () => Loading..., + onFailure: () => Request failed., + onSuccess: result => ( + <> + {result.value.title} + {result.value.body} + + ), + }) +const QueryRouteComponent = Component.make("QueryRouteView")(function*() { const [idLens, query, mutation] = yield* Component.useOnMount(() => Effect.gen(function*() { const idLens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(1)) - const key = Stream.map(idLens.changes, id => [id] as const) - const query = yield* Query.service({ - key, - f: ([id]) => HttpClient.HttpClient.pipe( - Effect.tap(Effect.sleep("500 millis")), - Effect.andThen(client => client.get(`https://jsonplaceholder.typicode.com/posts/${ id }`)), - Effect.andThen(response => response.json), - Effect.andThen(Schema.decodeUnknown(Post)), - ), + key: idLens, + f: fetchPost, staleTime: "10 seconds", }) - const mutation = yield* Mutation.make({ - f: ([id]: readonly [id: number]) => HttpClient.HttpClient.pipe( - Effect.tap(Effect.sleep("500 millis")), - Effect.andThen(client => client.get(`https://jsonplaceholder.typicode.com/posts/${ id }`)), - Effect.andThen(response => response.json), - Effect.andThen(Schema.decodeUnknown(Post)), - ), + f: fetchPost, }) return [idLens, query, mutation] as const })) - const [id, setId] = yield* Lens.useState(idLens) - const [queryResult, mutationResult] = yield* Subscribable.useAll([query.result, mutation.result]) - - yield* Component.useOnMount(() => ErrorObserver.ErrorObserver().pipe( - Effect.andThen(observer => observer.subscribe), - Effect.andThen(Stream.fromQueue), - Stream.unwrapScoped, - Stream.runForEach(flow( - Cause.failures, - Chunk.findFirst(e => e._tag === "RequestError" || e._tag === "ResponseError"), - Option.match({ - onSome: e => Console.log("ResultView HttpClient error", e), - onNone: () => Effect.void, - }), - )), - Effect.forkScoped, - )) + const [id] = yield* View.useAll([idLens]) + const [queryState, mutationResult] = yield* View.useAll([ + query.state, + mutation.state, + ]) + const runPromise = yield* Component.useRunPromise() return ( + void runPromise(Lens.set(idLens, value ?? 1)) + } /> -
- {Match.value(queryResult).pipe( - Match.tag("Running", () => Loading...), - Match.tag("Success", result => <> - {result.value.title} - {result.value.body} - {Result.hasRefreshingFlag(result) && Refreshing...} - ), - Match.tag("Failure", result => - An error has occured: {result.cause.toString()} - ), - Match.orElse(() => <>), - )} -
+ - - + + -
- {Match.value(mutationResult).pipe( - Match.tag("Running", () => Loading...), - Match.tag("Success", result => <> - {result.value.title} - {result.value.body} - {Result.hasRefreshingFlag(result) && Refreshing...} - ), - Match.tag("Failure", result => - An error has occured: {result.cause.toString()} - ), - Match.orElse(() => <>), - )} -
+ - - - +
) -}) +}).pipe( + Component.withRuntime(runtime.context), +) export const Route = createFileRoute("/query")({ - component: Component.withRuntime(ResultView, runtime.context) + component: QueryRouteComponent, }) diff --git a/packages/example-next/src/routes/result.tsx b/packages/example-next/src/routes/result.tsx index 0828f37..bfcdb0c 100644 --- a/packages/example-next/src/routes/result.tsx +++ b/packages/example-next/src/routes/result.tsx @@ -1,60 +1,45 @@ -import { HttpClient, type HttpClientError } from "@effect/platform" -import { Container, Heading, Text } from "@radix-ui/themes" +import { Button, Container, Flex, Heading, Text } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" -import { Cause, Chunk, Console, Effect, flow, Match, Option, Schema, Stream } from "effect" -import { Component, ErrorObserver, Result, Subscribable } from "effect-fc" +import { AsyncResult } from "effect/unstable/reactivity" +import { Component, Mutation, View } from "effect-fc-next" +import { fetchPost, type Post } from "@/post" import { runtime } from "@/runtime" -const Post = Schema.Struct({ - userId: Schema.Int, - id: Schema.Int, - title: Schema.String, - body: Schema.String, -}) +const PostResultView = (props: { readonly result: AsyncResult.AsyncResult }) => + AsyncResult.match(props.result, { + onInitial: () => Ready to load., + onFailure: () => Request failed., + onSuccess: result => ( + <> + {result.value.title} + {result.value.body} + + ), + }) -const ResultView = Component.makeUntraced("Result")(function*() { - const [resultSubscribable] = yield* Component.useOnMount(() => HttpClient.HttpClient.pipe( - Effect.andThen(client => client.get("https://jsonplaceholder.typicode.com/posts/1")), - Effect.andThen(response => response.json), - Effect.andThen(Schema.decodeUnknown(Post)), - Effect.tap(Effect.sleep("250 millis")), - Result.forkEffect, - )) - const [result] = yield* Subscribable.useAll([resultSubscribable]) - - yield* Component.useOnMount(() => ErrorObserver.ErrorObserver().pipe( - Effect.andThen(observer => observer.subscribe), - Effect.andThen(Stream.fromQueue), - Stream.unwrapScoped, - Stream.runForEach(flow( - Cause.failures, - Chunk.findFirst(e => e._tag === "RequestError" || e._tag === "ResponseError"), - Option.match({ - onSome: e => Console.log("ResultView HttpClient error", e), - onNone: () => Effect.void, - }), - )), - Effect.forkScoped, - )) +const ResultRouteComponent = Component.make("ResultRouteView")(function*() { + const mutation = yield* Component.useOnMount(() => Mutation.make({ + f: (_: undefined) => fetchPost(1), + })) + const [result] = yield* View.useAll([mutation.state]) + const runPromise = yield* Component.useRunPromise() return ( - {Match.value(result).pipe( - Match.tag("Running", () => Loading...), - Match.tag("Success", result => <> - {result.value.title} - {result.value.body} - ), - Match.tag("Failure", result => - An error has occured: {result.cause.toString()} - ), - Match.orElse(() => <>), - )} + + + + + ) -}) +}).pipe( + Component.withRuntime(runtime.context), +) export const Route = createFileRoute("/result")({ - component: Component.withRuntime(ResultView, runtime.context) + component: ResultRouteComponent, }) diff --git a/packages/example-next/src/runtime.ts b/packages/example-next/src/runtime.ts index 3467529..e09447f 100644 --- a/packages/example-next/src/runtime.ts +++ b/packages/example-next/src/runtime.ts @@ -1,15 +1,4 @@ -import { FetchHttpClient } from "@effect/platform" -import { Clipboard, Geolocation, Permissions } from "@effect/platform-browser" -import { DateTime, Layer } from "effect" -import { ReactRuntime } from "effect-fc" +import { QueryClient, ReactRuntime } from "effect-fc-next" -export const AppLive = Layer.empty.pipe( - Layer.provideMerge(DateTime.layerCurrentZoneLocal), - Layer.provideMerge(Clipboard.layer), - Layer.provideMerge(Geolocation.layer), - Layer.provideMerge(Permissions.layer), - Layer.provideMerge(FetchHttpClient.layer), -) - -export const runtime = ReactRuntime.make(AppLive) +export const runtime = ReactRuntime.make(QueryClient.layer()) diff --git a/packages/example-next/src/todo/EditTodoView.tsx b/packages/example-next/src/todo/EditTodoView.tsx deleted file mode 100644 index 69a9016..0000000 --- a/packages/example-next/src/todo/EditTodoView.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { Box, Flex, IconButton } from "@radix-ui/themes" -import { Effect } from "effect" -import { Component, Form, Subscribable, SynchronizedForm } from "effect-fc" -import { FaArrowDown, FaArrowUp } from "react-icons/fa" -import { FaDeleteLeft } from "react-icons/fa6" -import { TextFieldFormInputView } from "@/lib/form/TextFieldFormInputView" -import { TextFieldOptionalFormInputView } from "@/lib/form/TextFieldOptionalFormInputView" -import { TodoFormSchema } from "./TodoFormSchema" -import { TodosState } from "./TodosState" - - -export interface EditTodoViewProps { - readonly id: string -} - -export class EditTodoView extends Component.make("TodoView")(function*(props: EditTodoViewProps) { - const state = yield* TodosState - - const [ - indexSubscribable, - contentField, - completedAtField, - ] = yield* Component.useOnChange(() => Effect.gen(function*() { - const indexSubscribable = state.getIndexSubscribable(props.id) - - const form = yield* SynchronizedForm.service({ - schema: TodoFormSchema, - target: state.getElementLens(props.id), - }) - - return [ - indexSubscribable, - Form.focusObjectOn(form, "content"), - Form.focusObjectOn(form, "completedAt"), - ] as const - }), [props.id]) - - const [index, size] = yield* Subscribable.useAll([ - indexSubscribable, - state.sizeSubscribable, - ]) - - const runSync = yield* Component.useRunSync() - const TextFieldFormInput = yield* TextFieldFormInputView.use - const TextFieldOptionalFormInput = yield* TextFieldOptionalFormInputView.use - - - return ( - - - - - - - - - - - - - runSync(state.moveLeft(props.id))} - > - - - - = size - 1} - onClick={() => runSync(state.moveRight(props.id))} - > - - - - runSync(state.remove(props.id))}> - - - - - ) -}) {} diff --git a/packages/example-next/src/todo/NewTodoView.tsx b/packages/example-next/src/todo/NewTodoView.tsx deleted file mode 100644 index e382778..0000000 --- a/packages/example-next/src/todo/NewTodoView.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import { Box, Button, Flex } from "@radix-ui/themes" -import { GetRandomValues, makeUuid4 } from "@typed/id" -import { Chunk, type DateTime, Effect, Option, Schema } from "effect" -import { Component, Form, Lens, SubmittableForm, Subscribable } from "effect-fc" -import * as Domain from "@/domain" -import { TextFieldFormInputView } from "@/lib/form/TextFieldFormInputView" -import { TextFieldOptionalFormInputView } from "@/lib/form/TextFieldOptionalFormInputView" -import { TodoFormSchema } from "./TodoFormSchema" -import { TodosState } from "./TodosState" - - -const makeTodo = makeUuid4.pipe( - Effect.map(id => Domain.Todo.Todo.make({ - id, - content: "", - completedAt: Option.none(), - })), - Effect.provide(GetRandomValues.CryptoRandom), -) - - -export class NewTodoView extends Component.make("NewTodoView")(function*() { - const state = yield* TodosState - - const [ - form, - contentField, - completedAtField, - ] = yield* Component.useOnMount(() => Effect.gen(function*() { - const form = yield* SubmittableForm.service({ - schema: TodoFormSchema, - initialEncodedValue: yield* Schema.encode(TodoFormSchema)(yield* makeTodo), - f: ([todo, form]) => Lens.update(state.lens, Chunk.prepend(todo)).pipe( - Effect.andThen(makeTodo), - Effect.andThen(Schema.encode(TodoFormSchema)), - Effect.andThen(v => Lens.set(form.encodedValue, v)), - ), - }) - - return [ - form, - Form.focusObjectOn(form, "content"), - Form.focusObjectOn(form, "completedAt"), - ] as const - })) - - const [canCommit] = yield* Subscribable.useAll([form.canCommit]) - - const runPromise = yield* Component.useRunPromise() - const TextFieldFormInput = yield* TextFieldFormInputView.use - const TextFieldOptionalFormInput = yield* TextFieldOptionalFormInputView.use - - - return ( - - - - - - - - - - - - - - ) -}) {} diff --git a/packages/example-next/src/todo/TodoFormSchema.ts b/packages/example-next/src/todo/TodoFormSchema.ts deleted file mode 100644 index b2d4153..0000000 --- a/packages/example-next/src/todo/TodoFormSchema.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Schema } from "effect" -import * as Domain from "@/domain" -import { DateTimeUtcFromZonedInput } from "@/lib/schema" - - -export const TodoFormSchema = Schema.compose(Schema.Struct({ - ...Domain.Todo.Todo.fields, - completedAt: Schema.OptionFromSelf(DateTimeUtcFromZonedInput), -}), Domain.Todo.Todo) diff --git a/packages/example-next/src/todo/TodosState.ts b/packages/example-next/src/todo/TodosState.ts deleted file mode 100644 index d77041d..0000000 --- a/packages/example-next/src/todo/TodosState.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { KeyValueStore } from "@effect/platform" -import { BrowserKeyValueStore } from "@effect/platform-browser" -import { Chunk, Console, Effect, Option, Schema, Stream, SubscriptionRef } from "effect" -import { Lens, Subscribable } from "effect-fc" -import { Todo } from "@/domain" - - -export class TodosState extends Effect.Service()("TodosState", { - scoped: Effect.fnUntraced(function*(key: string) { - const kv = yield* KeyValueStore.KeyValueStore - - const readFromLocalStorage = Console.log("Reading todos from local storage...").pipe( - Effect.andThen(kv.get(key)), - Effect.andThen(Option.match({ - onSome: Schema.decode( - Schema.parseJson(Schema.Chunk(Todo.TodoFromJson)) - ), - onNone: () => Effect.succeed(Chunk.empty()), - })) - ) - const saveToLocalStorage = (todos: Chunk.Chunk) => Effect.andThen( - Console.log("Saving todos to local storage..."), - Chunk.isNonEmpty(todos) - ? Effect.andThen( - Schema.encode( - Schema.parseJson(Schema.Chunk(Todo.TodoFromJson)) - )(todos), - v => kv.set(key, v), - ) - : kv.remove(key) - ) - - const lens = Lens.fromSubscriptionRef(yield* SubscriptionRef.make(yield* readFromLocalStorage)) - yield* Effect.forkScoped(lens.changes.pipe( - Stream.debounce("500 millis"), - Stream.runForEach(saveToLocalStorage), - )) - yield* Effect.addFinalizer(() => Lens.get(lens).pipe( - Effect.andThen(saveToLocalStorage), - Effect.ignore, - )) - - const sizeSubscribable = Subscribable.map(lens, Chunk.size) - - const getElementLens = (id: string) => Lens.mapEffect( - lens, - Chunk.findFirst(v => v.id === id), - (a, b) => Effect.flatMap( - Chunk.findFirstIndex(a, v => v.id === id), - i => Chunk.replaceOption(a, i, b), - ) - ) - const getIndexSubscribable = (id: string) => Subscribable.mapEffect(lens, Chunk.findFirstIndex(v => v.id === id)) - - const moveLeft = (id: string) => Lens.updateEffect(lens, todos => Effect.Do.pipe( - Effect.bind("index", () => Chunk.findFirstIndex(todos, v => v.id === id)), - Effect.bind("todo", ({ index }) => Chunk.get(todos, index)), - Effect.bind("previous", ({ index }) => Chunk.get(todos, index - 1)), - Effect.andThen(({ todo, index, previous }) => index > 0 - ? todos.pipe( - Chunk.replace(index, previous), - Chunk.replace(index - 1, todo), - ) - : todos - ), - )) - const moveRight = (id: string) => Lens.updateEffect(lens, todos => Effect.Do.pipe( - Effect.bind("index", () => Chunk.findFirstIndex(todos, v => v.id === id)), - Effect.bind("todo", ({ index }) => Chunk.get(todos, index)), - Effect.bind("next", ({ index }) => Chunk.get(todos, index + 1)), - Effect.andThen(({ todo, index, next }) => index < Chunk.size(todos) - 1 - ? todos.pipe( - Chunk.replace(index, next), - Chunk.replace(index + 1, todo), - ) - : todos - ), - )) - const remove = (id: string) => Lens.updateEffect(lens, todos => Effect.andThen( - Chunk.findFirstIndex(todos, v => v.id === id), - index => Chunk.remove(todos, index), - )) - - return { - lens, - sizeSubscribable, - getElementLens, - getIndexSubscribable, - moveLeft, - moveRight, - remove, - } as const - }), - - dependencies: [BrowserKeyValueStore.layerLocalStorage], -}) {} diff --git a/packages/example-next/src/todo/TodosView.tsx b/packages/example-next/src/todo/TodosView.tsx deleted file mode 100644 index b935681..0000000 --- a/packages/example-next/src/todo/TodosView.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Container, Flex, Heading } from "@radix-ui/themes" -import { Chunk, Console, Effect } from "effect" -import { Component, Subscribable } from "effect-fc" -import { EditTodoView } from "./EditTodoView" -import { NewTodoView } from "./NewTodoView" -import { TodosState } from "./TodosState" - - -export class TodosView extends Component.make("TodosView")(function*() { - const state = yield* TodosState - const [todos] = yield* Subscribable.useAll([state.lens]) - - yield* Component.useOnMount(() => Effect.andThen( - Console.log("Todos mounted"), - Effect.addFinalizer(() => Console.log("Todos unmounted")), - )) - - const NewTodo = yield* NewTodoView.use - const EditTodo = yield* EditTodoView.use - - return ( - - Todos - - - - - {Chunk.map(todos, todo => - - )} - - - ) -}) {} -- 2.52.0 From 599546788d3021589704a1de662e0789d1a42f08 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 19 Jul 2026 12:03:06 +0000 Subject: [PATCH 61/61] Update dependency typescript to v7 --- bun.lock | 46 ++++++++++++++++++++++++++++++++++++-- package.json | 2 +- packages/docs/package.json | 2 +- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/bun.lock b/bun.lock index 2a9a52f..68f02b7 100644 --- a/bun.lock +++ b/bun.lock @@ -11,7 +11,7 @@ "npm-check-updates": "^22.2.1", "npm-sort": "^0.0.4", "turbo": "^2.9.16", - "typescript": "^6.0.3", + "typescript": "^7.0.0", }, }, "packages/docs": { @@ -1219,6 +1219,46 @@ "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], + "@typescript/typescript-aix-ppc64": ["@typescript/typescript-aix-ppc64@7.0.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ=="], + + "@typescript/typescript-darwin-arm64": ["@typescript/typescript-darwin-arm64@7.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA=="], + + "@typescript/typescript-darwin-x64": ["@typescript/typescript-darwin-x64@7.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA=="], + + "@typescript/typescript-freebsd-arm64": ["@typescript/typescript-freebsd-arm64@7.0.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ=="], + + "@typescript/typescript-freebsd-x64": ["@typescript/typescript-freebsd-x64@7.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw=="], + + "@typescript/typescript-linux-arm": ["@typescript/typescript-linux-arm@7.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ=="], + + "@typescript/typescript-linux-arm64": ["@typescript/typescript-linux-arm64@7.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ=="], + + "@typescript/typescript-linux-loong64": ["@typescript/typescript-linux-loong64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ=="], + + "@typescript/typescript-linux-mips64el": ["@typescript/typescript-linux-mips64el@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA=="], + + "@typescript/typescript-linux-ppc64": ["@typescript/typescript-linux-ppc64@7.0.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA=="], + + "@typescript/typescript-linux-riscv64": ["@typescript/typescript-linux-riscv64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ=="], + + "@typescript/typescript-linux-s390x": ["@typescript/typescript-linux-s390x@7.0.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw=="], + + "@typescript/typescript-linux-x64": ["@typescript/typescript-linux-x64@7.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A=="], + + "@typescript/typescript-netbsd-arm64": ["@typescript/typescript-netbsd-arm64@7.0.2", "", { "os": "none", "cpu": "arm64" }, "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA=="], + + "@typescript/typescript-netbsd-x64": ["@typescript/typescript-netbsd-x64@7.0.2", "", { "os": "none", "cpu": "x64" }, "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA=="], + + "@typescript/typescript-openbsd-arm64": ["@typescript/typescript-openbsd-arm64@7.0.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ=="], + + "@typescript/typescript-openbsd-x64": ["@typescript/typescript-openbsd-x64@7.0.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg=="], + + "@typescript/typescript-sunos-x64": ["@typescript/typescript-sunos-x64@7.0.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g=="], + + "@typescript/typescript-win32-arm64": ["@typescript/typescript-win32-arm64@7.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ=="], + + "@typescript/typescript-win32-x64": ["@typescript/typescript-win32-x64@7.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g=="], + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.3", "", {}, "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg=="], "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.3", "", { "dependencies": { "@rolldown/pluginutils": "^1.0.1" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-vmFvco5/QuC2f9Oj+wTk0+9XeDFkHxSamwZKYc7MxYwKICfvUvlMhqKI0VuICPltGqh1neqBKDvO4kes1ya8vg=="], @@ -2833,7 +2873,7 @@ "typedarray-to-buffer": ["typedarray-to-buffer@3.1.5", "", { "dependencies": { "is-typedarray": "^1.0.0" } }, "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q=="], - "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + "typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="], "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], @@ -3067,6 +3107,8 @@ "decompress-response/mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], + "docs/typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], "dot-prop/is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], diff --git a/package.json b/package.json index 3005ac9..ef6b2a3 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,6 @@ "npm-check-updates": "^22.2.1", "npm-sort": "^0.0.4", "turbo": "^2.9.16", - "typescript": "^6.0.3" + "typescript": "^7.0.0" } } diff --git a/packages/docs/package.json b/packages/docs/package.json index 52feaa1..d483cba 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -30,7 +30,7 @@ "@docusaurus/types": "3.10.1", "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", - "typescript": "~6.0.3" + "typescript": "~7.0.0" }, "browserslist": { "production": [ -- 2.52.0