From 288d444414d9490bf94101a1377fa108a3460cc7 Mon Sep 17 00:00:00 2001 From: senelway Date: Tue, 13 Jan 2026 14:06:12 +0000 Subject: [PATCH 1/5] [beta.10] feat: add hooks --- CLAUDE.md | 130 ++++++++++++++++++++ README.md | 190 +++++++++++++++++++++++++++-- lib/hooks.ts | 205 +++++++++++++++++++++++++++++++ lib/index.ts | 3 +- lib/reducer/types.ts | 9 +- package.json | 9 +- pnpm-lock.yaml | 90 +++++++++++++- tests/lib/hooks.test.ts | 264 ++++++++++++++++++++++++++++++++++++++++ tests/lib/index.test.ts | 1 + 9 files changed, 884 insertions(+), 17 deletions(-) create mode 100644 CLAUDE.md create mode 100644 lib/hooks.ts create mode 100644 tests/lib/hooks.test.ts diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..b33ff25 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,130 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Overview + +cdeebee is a Redux-based data management library that provides a normalized data storage system similar to relational databases. It's built on top of Redux Toolkit and focuses on reducing boilerplate for data fetching, normalization, and state management. + +## Development Commands + +### Building +```bash +pnpm build # Build library using Vite +``` + +### Linting +```bash +pnpm lint # Lint TypeScript files with ESLint +pnpm lint:ts # Type-check with TypeScript (no emit) +pnpm lint:all # Run both linters +``` + +### Testing +```bash +pnpm test # Run tests in watch mode with Vitest +pnpm test:run # Run tests once +pnpm test:coverage # Run tests with coverage report +``` + +To run a single test file: +```bash +pnpm test tests/lib/reducer/storage.test.ts +``` + +## Architecture + +### Core Concepts + +**Normalized Storage**: Data is stored in a normalized structure where each "list" (similar to a database table) is a JavaScript object with keys representing primary keys. API responses with format `{ data: [...], primaryKey: 'id' }` are automatically normalized into `{ '1': {...}, '2': {...} }` structures. + +**Modular System**: The library is composed of independent modules that can be enabled/disabled: +- `storage`: Normalizes and stores API responses +- `history`: Tracks request history (successful and failed requests) +- `listener`: Tracks active requests for loading states +- `cancelation`: Manages automatic request cancellation for duplicate API calls +- `queryQueue`: Processes requests sequentially to maintain order + +### Key Files and Structure + +**`lib/reducer/index.ts`**: Entry point for the Redux slice factory. The `factory()` function creates a Redux slice with the configured modules and returns it. The reducer handles three async thunk states (pending, fulfilled, rejected) for the request thunk. + +**`lib/reducer/request.ts`**: Contains the `request` async thunk that handles all API calls. This is where: +- FormData is built for file uploads +- Headers are merged (global + per-request) +- The fetch API is called with appropriate abort signals +- Response types (json/text/blob) are handled +- The queryQueue integration happens (requests are enqueued if module is enabled) + +**`lib/reducer/storage.ts`**: Contains the `defaultNormalize()` function which is the core normalization logic. It: +- Detects data with `{ data: [...], primaryKey: 'string' }` format +- Normalizes arrays into keyed objects using the specified primary key +- Applies merge strategies ('merge', 'replace', 'skip') per list +- Preserves existing keys not in the response when using 'merge' strategy + +**`lib/reducer/queryQueue.ts`**: Implements a sequential request queue using promise chaining. Ensures that even if a later request completes faster than an earlier one, they are stored in the order they were dispatched. + +**`lib/reducer/abortController.ts`**: Manages AbortController instances for request cancellation. Automatically cancels previous requests to the same API endpoint when enabled. + +**`lib/reducer/helpers.ts`**: Utility functions including: +- `checkModule()`: Conditional execution based on enabled modules +- `mergeDeepRight()`: Deep merge for objects (right takes precedence) +- `batchingUpdate()`: Mutates Redux state using Immer for the `set` action +- Type guards (`isRecord()`, `hasDataProperty()`, etc.) + +**`lib/reducer/types.ts`**: TypeScript type definitions including complex path-based types for type-safe batch updates via `CdeebeeValueList`. + +### Data Flow + +1. User dispatches `request()` thunk with API options +2. Request enters `pending` state → modules handle accordingly (cancelation, listener updates) +3. If `queryQueue` enabled, request is enqueued; otherwise executes immediately +4. Fetch executes with merged headers/body and abort signal +5. Response is parsed based on `responseType` (json/text/blob) +6. `onResult` callback is called (if provided) with response data +7. Request enters `fulfilled` or `rejected` state: + - Fulfilled → listener removes active request, history records it, storage normalizes and merges data + - Rejected → listener removes active request, history records error +8. Redux state is updated with new storage data (if not `ignore: true`) + +### Merge Strategies + +The normalization system supports three strategies per list: +- **`merge`** (default): Deep merges new data with existing, preserving keys not in response +- **`replace`**: Completely replaces the list with new data +- **`skip`**: Doesn't update the list, preserving existing data unchanged (useful for immutable reference data) + +Strategies can be set globally in settings or overridden per-request. + +### Testing + +Tests use Vitest with jsdom environment. Test files are in `tests/lib/` mirroring the `lib/` structure. Tests cover: +- Storage normalization and merge strategies +- Request lifecycle (pending, fulfilled, rejected) +- QueryQueue sequential processing +- AbortController cancellation +- Helper functions and type guards + +## Important Implementation Notes + +### State Mutation with Immer + +The `set` reducer and the `defaultNormalize` function work with Immer Draft objects. The `batchingUpdate()` helper directly mutates state objects, which is safe because Redux Toolkit uses Immer internally. This approach is more performant than creating new objects. + +### Primary Key Normalization + +When the API returns `{ data: [...], primaryKey: 'fieldName' }`, the normalization extracts the field value and converts it to a string for use as the object key. This ensures consistent key types regardless of whether the primary key is a number or string in the source data. + +### Request Callbacks + +The `onResult` callback is **always called** regardless of success or failure. It receives the parsed response data (or error) directly. This allows components to handle responses without needing to check Redux state. + +### File Uploads + +When `files` array is provided, the request automatically switches to FormData. The body is serialized to JSON and attached with the key specified by `bodyKey` (default: 'value'). Files are attached with keys specified by `fileKey` (default: 'file'). + +### Sequential vs Parallel Processing + +- Without `queryQueue`: Requests execute in parallel, may complete out of order +- With `queryQueue`: Requests execute sequentially in dispatch order, guaranteed to complete and store in order +- This is important when request order matters for data consistency (e.g., optimistic updates followed by server sync) diff --git a/README.md b/README.md index 49559eb..ca33994 100644 --- a/README.md +++ b/README.md @@ -138,15 +138,19 @@ function MyComponent() { } ``` -### 3. Access Data and Loading States +### 3. Access Data and Loading States with Hooks + +cdeebee provides React hooks to easily access data and track loading states: ```typescript -import { useAppSelector } from './hooks'; +import { useLoading, useStorageList } from '@recats/cdeebee'; function ForumsList() { - const forums = useAppSelector(state => state.cdeebee.storage.forumList); - const activeRequests = useAppSelector(state => state.cdeebee.request.active); - const isLoading = activeRequests.some(req => req.api === '/api/forums'); + // Check if specific APIs are loading + const isLoading = useLoading(['/api/forums']); + + // Get data from storage with full type safety + const forums = useStorageList('forumList'); return (
@@ -159,6 +163,17 @@ function ForumsList() { } ``` +**Available hooks:** + +- `useLoading(apiList: string[])` - Check if any of the specified APIs are loading +- `useIsLoading()` - Check if any request is loading +- `useStorageList(listName)` - Get a specific list from storage +- `useStorage()` - Get the entire storage +- `useRequestHistory(api)` - Get successful request history for an API +- `useRequestErrors(api)` - Get error history for an API + +See the [React Hooks](#react-hooks) section for detailed documentation. + ## Configuration ### Settings @@ -455,15 +470,163 @@ dispatch(cdeebeeSlice.actions.set(updates)); ### Accessing Request History +You can access request history using hooks or selectors: + ```typescript +import { useRequestHistory, useRequestErrors } from '@recats/cdeebee'; + +// Using hooks (recommended) +const apiHistory = useRequestHistory('/api/forums'); +const apiErrors = useRequestErrors('/api/forums'); + +// Or using selectors const doneRequests = useAppSelector(state => state.cdeebee.request.done); const errors = useAppSelector(state => state.cdeebee.request.errors); +``` + +## React Hooks + +cdeebee provides a comprehensive set of React hooks for accessing state without writing selectors. These hooks assume your cdeebee slice is at `state.cdeebee` (which is the default when using `combineSlices`). + +### Loading State Hooks + +#### `useLoading(apiList: string[])` + +Check if any of the specified APIs are currently loading. + +```typescript +import { useLoading } from '@recats/cdeebee'; + +function MyComponent() { + // Check if any of these APIs are loading + const isLoading = useLoading(['/api/forums', '/api/threads']); + + if (isLoading) return ; + + return
Content
; +} +``` + +#### `useIsLoading()` + +Check if any request is currently loading across all APIs. + +```typescript +import { useIsLoading } from '@recats/cdeebee'; + +function GlobalSpinner() { + const isAnythingLoading = useIsLoading(); + + return isAnythingLoading ? : null; +} +``` + +### Storage Hooks + +#### `useStorageList(listName: K)` + +Get a specific list from storage with full type safety. + +```typescript +import { useStorageList } from '@recats/cdeebee'; + +interface MyStorage { + forumList: Record; +} + +function ForumsList() { + const forums = useStorageList('forumList'); + + return ( +
+ {Object.values(forums).map(forum => ( +
{forum.title}
+ ))} +
+ ); +} +``` + +#### `useStorage()` + +Get the entire cdeebee storage. + +```typescript +import { useStorage } from '@recats/cdeebee'; + +interface MyStorage { + forumList: Record; + threadList: Record; +} -// Get history for specific API -const apiHistory = doneRequests['/api/forums'] || []; -const apiErrors = errors['/api/forums'] || []; +function DataDebug() { + const storage = useStorage(); + + return
{JSON.stringify(storage, null, 2)}
; +} ``` +### History Hooks + +#### `useRequestHistory(api: string)` + +Get successful request history for a specific API endpoint. + +```typescript +import { useRequestHistory } from '@recats/cdeebee'; + +function RequestStats({ api }: { api: string }) { + const history = useRequestHistory(api); + + return ( +
+ Total successful requests to {api}: {history.length} +
+ ); +} +``` + +#### `useRequestErrors(api: string)` + +Get error history for a specific API endpoint. + +```typescript +import { useRequestErrors } from '@recats/cdeebee'; + +function ErrorDisplay({ api }: { api: string }) { + const errors = useRequestErrors(api); + + if (errors.length === 0) return null; + + const lastError = errors[errors.length - 1]; + return
Last error: {lastError.request.message}
; +} +``` + +### Advanced: Custom State Path + +If you're **not** using `combineSlices` or have cdeebee at a custom path in your state (not `state.cdeebee`), use `createCdeebeeHooks`: + +```typescript +// hooks.ts - Create once in your app +import { createCdeebeeHooks } from '@recats/cdeebee'; +import type { RootState, MyStorage } from './store'; + +// Tell the hooks where to find cdeebee in your state +export const { + useLoading, + useStorageList, + useStorage, + useRequestHistory, + useRequestErrors, + useIsLoading, +} = createCdeebeeHooks( + state => state.myCustomPath // Your custom path +); +``` + +**Note:** Most users won't need `createCdeebeeHooks` because `combineSlices` automatically places the slice at `state.cdeebee`. + ## TypeScript Support cdeebee is fully typed. Define your storage type and get full type safety: @@ -489,6 +652,17 @@ export { factory } from '@recats/cdeebee'; // Create cdeebee slice export { request } from '@recats/cdeebee'; // Request thunk export { batchingUpdate } from '@recats/cdeebee'; // Batch update helper +// React hooks +export { + createCdeebeeHooks, // Hook factory for custom state paths + useLoading, // Check if APIs are loading + useIsLoading, // Check if any request is loading + useStorageList, // Get a list from storage + useStorage, // Get entire storage + useRequestHistory, // Get successful request history + useRequestErrors, // Get error history +} from '@recats/cdeebee'; + // Types export type { CdeebeeState, diff --git a/lib/hooks.ts b/lib/hooks.ts new file mode 100644 index 0000000..19a917c --- /dev/null +++ b/lib/hooks.ts @@ -0,0 +1,205 @@ +import { useSelector } from 'react-redux'; +import { type CdeebeeState } from './reducer/types'; + +/** + * Generic hook factory that creates a selector hook for cdeebee state. + * This allows the hooks to work with any Redux root state structure. + * + * @template RootState - The shape of the Redux root state + * @template Storage - The shape of the cdeebee storage + * @param selectCdeebee - Function to select the cdeebee slice from root state + * @returns An object containing all cdeebee hooks + */ +export function createCdeebeeHooks( + selectCdeebee: (state: RootState) => CdeebeeState +) { + /** + * Check if any of the specified APIs are currently loading. + * + * @param apiList - Array of API endpoints to check + * @returns true if any of the APIs are currently active/loading + * + * @example + * const isLoading = useLoading(['/api/forums', '/api/threads']); + * if (isLoading) return ; + */ + function useLoading(apiList: string[]): boolean { + return useSelector((state: RootState) => { + const cdeebee = selectCdeebee(state); + return cdeebee.request.active.some(q => apiList.includes(q.api)); + }); + } + + /** + * Get the successful request history for a specific API endpoint. + * + * @param api - The API endpoint + * @returns Array of successful request history entries + * + * @example + * const history = useRequestHistory('/api/forums'); + * console.log(`Made ${history.length} successful requests`); + */ + function useRequestHistory(api: string) { + return useSelector((state: RootState) => { + const cdeebee = selectCdeebee(state); + return cdeebee.request.done[api] ?? []; + }); + } + + /** + * Get the error history for a specific API endpoint. + * + * @param api - The API endpoint + * @returns Array of error history entries + * + * @example + * const errors = useRequestErrors('/api/forums'); + * if (errors.length > 0) { + * console.error('Last error:', errors[errors.length - 1]); + * } + */ + function useRequestErrors(api: string) { + return useSelector((state: RootState) => { + const cdeebee = selectCdeebee(state); + return cdeebee.request.errors[api] ?? []; + }); + } + + /** + * Get a specific list from storage with full type safety. + * + * @param listName - The name of the list in storage + * @returns The list data + * + * @example + * const forums = useStorageList('forumList'); + * const forumArray = Object.values(forums); + */ + function useStorageList(listName: K): Storage[K] { + return useSelector((state: RootState) => { + const cdeebee = selectCdeebee(state); + return cdeebee.storage[listName]; + }); + } + + /** + * Get the entire cdeebee storage. + * + * @returns The complete storage object + * + * @example + * const storage = useStorage(); + * console.log(Object.keys(storage)); // ['forumList', 'threadList', ...] + */ + function useStorage(): Storage { + return useSelector((state: RootState) => { + const cdeebee = selectCdeebee(state); + return cdeebee.storage; + }); + } + + /** + * Check if any request is currently loading (across all APIs). + * + * @returns true if any request is active + * + * @example + * const isAnythingLoading = useIsLoading(); + * if (isAnythingLoading) return ; + */ + function useIsLoading(): boolean { + return useSelector((state: RootState) => { + const cdeebee = selectCdeebee(state); + return cdeebee.request.active.length > 0; + }); + } + + return { + useLoading, + useRequestHistory, + useRequestErrors, + useStorageList, + useStorage, + useIsLoading, + }; +} + +/** + * Standalone hook that can be used without createCdeebeeHooks. + * Assumes the cdeebee slice is at state.cdeebee. + * + * @param apiList - Array of API endpoints to check + * @returns true if any of the APIs are currently active/loading + * + * @example + * const isLoading = useLoading(['/api/forums', '/api/threads']); + */ +export function useLoading(apiList: string[]): boolean { + return useSelector((state: { cdeebee: CdeebeeState }) => { + return state.cdeebee.request.active.some(q => apiList.includes(q.api)); + }); +} + +/** + * Standalone hook that can be used without createCdeebeeHooks. + * Assumes the cdeebee slice is at state.cdeebee. + * + * @param api - The API endpoint + * @returns Array of successful request history entries + */ +export function useRequestHistory(api: string) { + return useSelector((state: { cdeebee: CdeebeeState }) => { + return state.cdeebee.request.done[api] ?? []; + }); +} + +/** + * Standalone hook that can be used without createCdeebeeHooks. + * Assumes the cdeebee slice is at state.cdeebee. + * + * @param api - The API endpoint + * @returns Array of error history entries + */ +export function useRequestErrors(api: string) { + return useSelector((state: { cdeebee: CdeebeeState }) => { + return state.cdeebee.request.errors[api] ?? []; + }); +} + +/** + * Standalone hook that can be used without createCdeebeeHooks. + * Assumes the cdeebee slice is at state.cdeebee. + * + * @param listName - The name of the list in storage + * @returns The list data + */ +export function useStorageList(listName: K): Storage[K] { + return useSelector((state: { cdeebee: CdeebeeState }) => { + return state.cdeebee.storage[listName]; + }); +} + +/** + * Standalone hook that can be used without createCdeebeeHooks. + * Assumes the cdeebee slice is at state.cdeebee. + * + * @returns The complete storage object + */ +export function useStorage(): Storage { + return useSelector((state: { cdeebee: CdeebeeState }) => { + return state.cdeebee.storage; + }); +} + +/** + * Standalone hook that can be used without createCdeebeeHooks. + * Assumes the cdeebee slice is at state.cdeebee. + * + * @returns true if any request is active + */ +export function useIsLoading(): boolean { + return useSelector((state: { cdeebee: CdeebeeState }) => { + return state.cdeebee.request.active.length > 0; + }); +} diff --git a/lib/index.ts b/lib/index.ts index c099310..dae3918 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,4 +1,5 @@ -export { type CdeebeeListStrategy, type CdeebeeState, type CdeebeeValueList, type CdeebeeRequestOptions, type CdeebeeModule } from './reducer/types'; +export { type CdeebeeListStrategy, type CdeebeeState, type CdeebeeValueList, type CdeebeeRequestOptions, type CdeebeeModule, type CdeebeeActiveRequest, type CdeebeeHistoryState } from './reducer/types'; export { batchingUpdate } from './reducer/helpers'; export { request } from './reducer/request'; export { factory } from './reducer/index'; +export { createCdeebeeHooks, useLoading, useRequestHistory, useRequestErrors, useStorageList, useStorage, useIsLoading, } from './hooks'; diff --git a/lib/reducer/types.ts b/lib/reducer/types.ts index 1af699e..16e7d9d 100644 --- a/lib/reducer/types.ts +++ b/lib/reducer/types.ts @@ -13,9 +13,9 @@ export interface CdeebeeSettings { normalize?: (storage: CdeebeeState, result: T, strategyList: CdeebeeListStrategy) => T; } -interface CdeebeeHistoryState { - requestId: string, - api: string, +export interface CdeebeeHistoryState { + requestId: string, + api: string, request: unknown, } @@ -36,7 +36,7 @@ export interface CdeebeeState { request: CdeebeeRequestState; } -export interface CdeebeeRequestOptions extends Partial, 'fileKey' | 'bodyKey' | 'normalize' | 'listStrategy'>> { +export interface CdeebeeRequestOptions extends Partial, 'fileKey' | 'bodyKey' | 'normalize'>> { api: string; files?: File[]; method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; @@ -45,6 +45,7 @@ export interface CdeebeeRequestOptions extends Partial void; ignore?: boolean; responseType?: 'json' | 'text' | 'blob'; + listStrategy?: Partial>; } type KeyOf = Extract; diff --git a/package.json b/package.json index 7494887..1d9e1d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@recats/cdeebee", - "version": "3.0.0-beta.9", + "version": "3.0.0-beta.10", "description": "React Redux data-logic library", "repository": "git@github.com:recats/cdeebee.git", "author": "recats", @@ -48,9 +48,12 @@ "@reduxjs/toolkit": "^2.11.2", "@types/lodash": "^4.17.21", "@types/node": "^22.19.3", + "@types/react": "^18.3.18", "@vitest/coverage-v8": "^2.1.9", "eslint": "^9.39.2", "jsdom": "^27.3.0", + "react": "^18.3.1", + "react-redux": "^9.2.0", "typescript": "^5.9.3", "typescript-eslint": "^8.50.1", "vite": "^6.4.1", @@ -58,7 +61,9 @@ "vitest": "^2.1.9" }, "peerDependencies": { - "@reduxjs/toolkit": ">=2" + "@reduxjs/toolkit": ">=2", + "react": ">=18", + "react-redux": ">=8" }, "packageManager": "pnpm@9.15.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ced791e..dfd0a96 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,13 +10,16 @@ importers: devDependencies: '@reduxjs/toolkit': specifier: ^2.11.2 - version: 2.11.2 + version: 2.11.2(react-redux@9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1))(react@18.3.1) '@types/lodash': specifier: ^4.17.21 version: 4.17.21 '@types/node': specifier: ^22.19.3 version: 22.19.3 + '@types/react': + specifier: ^18.3.18 + version: 18.3.27 '@vitest/coverage-v8': specifier: ^2.1.9 version: 2.1.9(vitest@2.1.9(@types/node@22.19.3)(jsdom@27.3.0)) @@ -26,6 +29,12 @@ importers: jsdom: specifier: ^27.3.0 version: 27.3.0 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-redux: + specifier: ^9.2.0 + version: 9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -687,6 +696,15 @@ packages: '@types/node@22.19.3': resolution: {integrity: sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==} + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react@18.3.27': + resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==} + + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + '@typescript-eslint/eslint-plugin@8.50.1': resolution: {integrity: sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -944,6 +962,9 @@ packages: resolution: {integrity: sha512-GlsEptulso7Jg0VaOZ8BXQi3AkYM5BOJKEO/rjMidSCq70FkIC5y0eawrCXeYzxgt3OCf4Ls+eoxN+/05vN0Ag==} engines: {node: '>=20'} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + data-urls@6.0.0: resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==} engines: {node: '>=20'} @@ -1225,6 +1246,9 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@4.1.1: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true @@ -1277,6 +1301,10 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + loupe@3.2.1: resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} @@ -1414,6 +1442,22 @@ packages: quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + react-redux@9.2.0: + resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==} + peerDependencies: + '@types/react': ^18.2.25 || ^19 + react: ^18.0 || ^19 + redux: ^5.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + redux: + optional: true + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + redux-thunk@3.1.0: resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==} peerDependencies: @@ -1612,6 +1656,11 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + vite-node@2.1.9: resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -2131,7 +2180,7 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@reduxjs/toolkit@2.11.2': + '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1))(react@18.3.1)': dependencies: '@standard-schema/spec': 1.1.0 '@standard-schema/utils': 0.3.0 @@ -2139,6 +2188,9 @@ snapshots: redux: 5.0.1 redux-thunk: 3.1.0(redux@5.0.1) reselect: 5.1.1 + optionalDependencies: + react: 18.3.1 + react-redux: 9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1) '@rollup/pluginutils@5.3.0(rollup@4.54.0)': dependencies: @@ -2269,6 +2321,15 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/prop-types@15.7.15': {} + + '@types/react@18.3.27': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.2.3 + + '@types/use-sync-external-store@0.0.6': {} + '@typescript-eslint/eslint-plugin@8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -2585,6 +2646,8 @@ snapshots: '@csstools/css-syntax-patches-for-csstree': 1.0.22 css-tree: 3.1.0 + csstype@3.2.3: {} + data-urls@6.0.0: dependencies: whatwg-mimetype: 4.0.0 @@ -2900,6 +2963,8 @@ snapshots: jju@1.4.0: {} + js-tokens@4.0.0: {} + js-yaml@4.1.1: dependencies: argparse: 2.0.1 @@ -2970,6 +3035,10 @@ snapshots: lodash@4.17.21: {} + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + loupe@3.2.1: {} lru-cache@10.4.3: {} @@ -3099,6 +3168,19 @@ snapshots: quansync@0.2.11: {} + react-redux@9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1): + dependencies: + '@types/use-sync-external-store': 0.0.6 + react: 18.3.1 + use-sync-external-store: 1.6.0(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + redux: 5.0.1 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + redux-thunk@3.1.0(redux@5.0.1): dependencies: redux: 5.0.1 @@ -3281,6 +3363,10 @@ snapshots: dependencies: punycode: 2.3.1 + use-sync-external-store@1.6.0(react@18.3.1): + dependencies: + react: 18.3.1 + vite-node@2.1.9(@types/node@22.19.3): dependencies: cac: 6.7.14 diff --git a/tests/lib/hooks.test.ts b/tests/lib/hooks.test.ts new file mode 100644 index 0000000..2384c7e --- /dev/null +++ b/tests/lib/hooks.test.ts @@ -0,0 +1,264 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { configureStore } from '@reduxjs/toolkit'; +import { factory } from '../../lib/reducer/index'; +import { createCdeebeeHooks } from '../../lib/hooks'; +import { type CdeebeeState } from '../../lib/reducer/types'; + +interface TestStorage { + userList: Record; + postList: Record; +} + +interface RootState { + cdeebee: CdeebeeState; +} + +describe('cdeebee hooks selector logic', () => { + let store: ReturnType; + let hooks: ReturnType>; + + beforeEach(() => { + const slice = factory( + { + modules: ['storage', 'listener', 'history'], + fileKey: 'file', + bodyKey: 'value', + }, + { + userList: {}, + postList: {}, + } + ); + + store = configureStore({ + reducer: { + cdeebee: slice.reducer, + }, + }); + + hooks = createCdeebeeHooks(state => state.cdeebee); + }); + + describe('useLoading selector logic', () => { + it('should return false when no APIs are loading', () => { + const state = store.getState(); + const isLoading = state.cdeebee.request.active.some(q => + ['/api/users'].includes(q.api) + ); + expect(isLoading).toBe(false); + }); + + it('should return true when an API in the list is loading', () => { + store.dispatch({ + type: 'cdeebee/request/pending', + meta: { arg: { api: '/api/users' }, requestId: 'req-1' }, + }); + + const state = store.getState(); + const isLoading = state.cdeebee.request.active.some(q => + ['/api/users', '/api/posts'].includes(q.api) + ); + expect(isLoading).toBe(true); + }); + + it('should return false when a different API is loading', () => { + store.dispatch({ + type: 'cdeebee/request/pending', + meta: { arg: { api: '/api/comments' }, requestId: 'req-1' }, + }); + + const state = store.getState(); + const isLoading = state.cdeebee.request.active.some(q => + ['/api/users', '/api/posts'].includes(q.api) + ); + expect(isLoading).toBe(false); + }); + }); + + describe('useRequestHistory selector logic', () => { + it('should return empty array when no history exists', () => { + const state = store.getState(); + const history = state.cdeebee.request.done['/api/users'] ?? []; + expect(history).toEqual([]); + }); + + it('should return request history for specific API', () => { + const mockResult = { data: 'test' }; + store.dispatch({ + type: 'cdeebee/request/fulfilled', + payload: { result: mockResult }, + meta: { arg: { api: '/api/users' }, requestId: 'req-1' }, + }); + + const state = store.getState(); + const history = state.cdeebee.request.done['/api/users'] ?? []; + expect(history).toHaveLength(1); + expect(history[0]).toEqual({ + api: '/api/users', + request: { result: mockResult }, + requestId: 'req-1', + }); + }); + }); + + describe('useRequestErrors selector logic', () => { + it('should return empty array when no errors exist', () => { + const state = store.getState(); + const errors = state.cdeebee.request.errors['/api/users'] ?? []; + expect(errors).toEqual([]); + }); + + it('should return error history for specific API', () => { + const mockError = { message: 'Network error' }; + store.dispatch({ + type: 'cdeebee/request/rejected', + error: mockError, + meta: { arg: { api: '/api/users' }, requestId: 'req-1' }, + }); + + const state = store.getState(); + const errors = state.cdeebee.request.errors['/api/users'] ?? []; + expect(errors).toHaveLength(1); + expect(errors[0]).toEqual({ + api: '/api/users', + request: mockError, + requestId: 'req-1', + }); + }); + }); + + describe('useStorageList selector logic', () => { + it('should return empty object when list is not populated', () => { + const state = store.getState(); + expect(state.cdeebee.storage.userList).toEqual({}); + }); + + it('should return the list from storage', () => { + const users = { + '1': { id: '1', name: 'John' }, + '2': { id: '2', name: 'Jane' }, + }; + + store.dispatch({ + type: 'cdeebee/set', + payload: [{ key: ['userList'], value: users }], + }); + + const state = store.getState(); + expect(state.cdeebee.storage.userList).toEqual(users); + }); + }); + + describe('useStorage selector logic', () => { + it('should return the entire storage', () => { + const state = store.getState(); + expect(state.cdeebee.storage).toHaveProperty('userList'); + expect(state.cdeebee.storage).toHaveProperty('postList'); + }); + + it('should return updated storage after changes', () => { + const users = { '1': { id: '1', name: 'John' } }; + store.dispatch({ + type: 'cdeebee/set', + payload: [{ key: ['userList'], value: users }], + }); + + const state = store.getState(); + expect(state.cdeebee.storage.userList).toEqual(users); + }); + }); + + describe('useIsLoading selector logic', () => { + it('should return false when no requests are active', () => { + const state = store.getState(); + expect(state.cdeebee.request.active.length).toBe(0); + }); + + it('should return true when any request is active', () => { + store.dispatch({ + type: 'cdeebee/request/pending', + meta: { arg: { api: '/api/users' }, requestId: 'req-1' }, + }); + + const state = store.getState(); + expect(state.cdeebee.request.active.length).toBeGreaterThan(0); + }); + }); + + describe('createCdeebeeHooks with custom selector', () => { + it('should create hooks factory that has all expected properties', () => { + interface CustomRootState { + customPath: CdeebeeState; + } + + const customHooks = createCdeebeeHooks( + state => state.customPath + ); + + // Verify all hook functions are created + expect(customHooks).toHaveProperty('useLoading'); + expect(customHooks).toHaveProperty('useRequestHistory'); + expect(customHooks).toHaveProperty('useRequestErrors'); + expect(customHooks).toHaveProperty('useStorageList'); + expect(customHooks).toHaveProperty('useStorage'); + expect(customHooks).toHaveProperty('useIsLoading'); + + // Verify they're all functions + expect(typeof customHooks.useLoading).toBe('function'); + expect(typeof customHooks.useStorageList).toBe('function'); + }); + }); + + describe('request lifecycle with active tracking', () => { + it('should add request to active on pending', () => { + store.dispatch({ + type: 'cdeebee/request/pending', + meta: { arg: { api: '/api/users' }, requestId: 'req-1' }, + }); + + const state = store.getState(); + expect(state.cdeebee.request.active).toContainEqual({ + api: '/api/users', + requestId: 'req-1', + }); + }); + + it('should remove request from active on fulfilled', () => { + store.dispatch({ + type: 'cdeebee/request/pending', + meta: { arg: { api: '/api/users' }, requestId: 'req-1' }, + }); + + let state = store.getState(); + expect(state.cdeebee.request.active).toHaveLength(1); + + store.dispatch({ + type: 'cdeebee/request/fulfilled', + payload: { result: {} }, + meta: { arg: { api: '/api/users' }, requestId: 'req-1' }, + }); + + state = store.getState(); + expect(state.cdeebee.request.active).toHaveLength(0); + }); + + it('should remove request from active on rejected', () => { + store.dispatch({ + type: 'cdeebee/request/pending', + meta: { arg: { api: '/api/users' }, requestId: 'req-1' }, + }); + + let state = store.getState(); + expect(state.cdeebee.request.active).toHaveLength(1); + + store.dispatch({ + type: 'cdeebee/request/rejected', + error: { message: 'Error' }, + meta: { arg: { api: '/api/users' }, requestId: 'req-1' }, + }); + + state = store.getState(); + expect(state.cdeebee.request.active).toHaveLength(0); + }); + }); +}); diff --git a/tests/lib/index.test.ts b/tests/lib/index.test.ts index 4d33d61..093eb16 100644 --- a/tests/lib/index.test.ts +++ b/tests/lib/index.test.ts @@ -17,6 +17,7 @@ describe('lib/index exports', () => { fileKey: 'file', bodyKey: 'body', mergeWithData: {}, + mergeWithHeaders: {} }, storage: {}, request: { From 396f8932faf24f7182f74f98e391dffbed12a3ba Mon Sep 17 00:00:00 2001 From: senelway Date: Tue, 13 Jan 2026 14:18:00 +0000 Subject: [PATCH 2/5] fix vite cofnig --- lib/reducer/index.ts | 7 ++++--- package.json | 6 +++--- vite.config.mjs | 4 +++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/reducer/index.ts b/lib/reducer/index.ts index 2e43b28..d1b69d9 100644 --- a/lib/reducer/index.ts +++ b/lib/reducer/index.ts @@ -1,6 +1,6 @@ import { createSlice, current } from '@reduxjs/toolkit'; -import { type CdeebeeSettings, type CdeebeeState, type CdeebeeValueList } from './types'; +import { type CdeebeeSettings, type CdeebeeState, type CdeebeeValueList, type CdeebeeListStrategy } from './types'; import { checkModule, mergeDeepRight, batchingUpdate } from './helpers'; import { abortQuery } from './abortController'; import { request } from './request'; @@ -64,12 +64,13 @@ export const factory = (settings: CdeebeeSettings, storage?: T) => { return; } - const strategyList = action.meta.arg.listStrategy ?? state.settings.listStrategy ?? {}; + const strategyList = (action.meta.arg.listStrategy ?? state.settings.listStrategy ?? {}) as CdeebeeListStrategy; const normalize = action.meta.arg.normalize ?? state.settings.normalize ?? defaultNormalize; const currentState = current(state) as CdeebeeState; // Type assertion is safe here because we've already checked isRecord - const normalizedData = normalize(currentState, action.payload.result as Record>, strategyList); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const normalizedData = normalize(currentState, action.payload.result as any, strategyList); // Normalize already handles merge/replace/skip and preserves keys not in response // Simply apply the result diff --git a/package.json b/package.json index 1d9e1d3..8a2c2b1 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "@vitest/coverage-v8": "^2.1.9", "eslint": "^9.39.2", "jsdom": "^27.3.0", - "react": "^18.3.1", + "react": "^19.3.1", "react-redux": "^9.2.0", "typescript": "^5.9.3", "typescript-eslint": "^8.50.1", @@ -62,8 +62,8 @@ }, "peerDependencies": { "@reduxjs/toolkit": ">=2", - "react": ">=18", - "react-redux": ">=8" + "react": ">=19", + "react-redux": ">=9" }, "packageManager": "pnpm@9.15.1" } diff --git a/vite.config.mjs b/vite.config.mjs index b6b0a77..62e325b 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -24,11 +24,13 @@ export default defineConfig({ formats: ['es', 'cjs'], }, rollupOptions: { - external: ['@reduxjs/toolkit', 'redux'], + external: ['@reduxjs/toolkit', 'redux', 'react', 'react-redux'], output: { globals: { '@reduxjs/toolkit': 'ReduxToolkit', redux: 'Redux', + react: 'React', + 'react-redux': 'ReactRedux', }, }, }, From 260f49198db68921ae0842ea14c0d8cf596a2253 Mon Sep 17 00:00:00 2001 From: senelway Date: Tue, 13 Jan 2026 14:20:00 +0000 Subject: [PATCH 3/5] update md --- CLAUDE.md | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index b33ff25..b808528 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -74,6 +74,20 @@ pnpm test tests/lib/reducer/storage.test.ts **`lib/reducer/types.ts`**: TypeScript type definitions including complex path-based types for type-safe batch updates via `CdeebeeValueList`. +**`lib/hooks.ts`**: React hooks for accessing cdeebee state without writing selectors. Provides two approaches: +- **Standalone hooks**: Export individual hooks that assume the cdeebee slice is at `state.cdeebee` (default when using `combineSlices`) +- **`createCdeebeeHooks` factory**: For edge cases where the slice is at a custom path in the state tree + +Available hooks: +- `useLoading(apiList)`: Check if any APIs in the list are currently loading +- `useIsLoading()`: Check if any request is loading globally +- `useStorageList(listName)`: Get a specific list from storage with type safety +- `useStorage()`: Get the entire storage object +- `useRequestHistory(api)`: Get successful request history for a specific API +- `useRequestErrors(api)`: Get error history for a specific API + +All hooks use `react-redux`'s `useSelector` internally and are fully typed for TypeScript. + ### Data Flow 1. User dispatches `request()` thunk with API options @@ -94,7 +108,23 @@ The normalization system supports three strategies per list: - **`replace`**: Completely replaces the list with new data - **`skip`**: Doesn't update the list, preserving existing data unchanged (useful for immutable reference data) -Strategies can be set globally in settings or overridden per-request. +Strategies can be set globally in settings (requires all lists) or overridden per-request (accepts `Partial<>` - only specify lists you want to override): +```typescript +// Global setting - must provide strategy for all lists +factory({ + listStrategy: { + forumList: 'merge', + threadList: 'replace', + postList: 'skip', + } +}) + +// Per-request - can be partial +dispatch(request({ + api: '/api/data', + listStrategy: { forumList: 'replace' } // Only override forumList +})) +``` ### Testing @@ -104,6 +134,7 @@ Tests use Vitest with jsdom environment. Test files are in `tests/lib/` mirrorin - QueryQueue sequential processing - AbortController cancellation - Helper functions and type guards +- React hooks (`tests/lib/hooks.test.ts`): Tests the selector logic for all hooks by dispatching Redux actions and verifying state selections ## Important Implementation Notes @@ -128,3 +159,19 @@ When `files` array is provided, the request automatically switches to FormData. - Without `queryQueue`: Requests execute in parallel, may complete out of order - With `queryQueue`: Requests execute sequentially in dispatch order, guaranteed to complete and store in order - This is important when request order matters for data consistency (e.g., optimistic updates followed by server sync) + +### Build Configuration and External Dependencies + +**CRITICAL**: The `vite.config.mjs` must mark `react`, `react-redux`, `@reduxjs/toolkit`, and `redux` as external dependencies. This prevents them from being bundled with the library and avoids the "Invalid hook call" error. + +The external array in Vite config should include: +```js +external: ['@reduxjs/toolkit', 'redux', 'react', 'react-redux'] +``` + +These dependencies are: +- Listed in `peerDependencies` (the consuming app provides them) +- Listed in `devDependencies` (for development and testing) +- **NOT bundled** with the library distribution + +If hooks are being bundled, users will get "Cannot read properties of null (reading 'useContext')" errors because there will be multiple React instances. From 9fae343e0a7d599105d005fc91108f3beeff7cbf Mon Sep 17 00:00:00 2001 From: senelway Date: Tue, 13 Jan 2026 14:22:07 +0000 Subject: [PATCH 4/5] upd --- package.json | 12 +- pnpm-lock.yaml | 678 +++++++++++++++++++++++++------------------------ 2 files changed, 348 insertions(+), 342 deletions(-) diff --git a/package.json b/package.json index 8a2c2b1..f47573a 100644 --- a/package.json +++ b/package.json @@ -46,16 +46,16 @@ ], "devDependencies": { "@reduxjs/toolkit": "^2.11.2", - "@types/lodash": "^4.17.21", - "@types/node": "^22.19.3", - "@types/react": "^18.3.18", + "@types/lodash": "^4.17.23", + "@types/node": "^22.19.5", + "@types/react": "^18.3.27", "@vitest/coverage-v8": "^2.1.9", "eslint": "^9.39.2", - "jsdom": "^27.3.0", - "react": "^19.3.1", + "jsdom": "^27.4.0", + "react": "^19.2.3", "react-redux": "^9.2.0", "typescript": "^5.9.3", - "typescript-eslint": "^8.50.1", + "typescript-eslint": "^8.53.0", "vite": "^6.4.1", "vite-plugin-dts": "^4.5.4", "vitest": "^2.1.9" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dfd0a96..52d037e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,51 +10,51 @@ importers: devDependencies: '@reduxjs/toolkit': specifier: ^2.11.2 - version: 2.11.2(react-redux@9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1))(react@18.3.1) + version: 2.11.2(react-redux@9.2.0(@types/react@18.3.27)(react@19.2.3)(redux@5.0.1))(react@19.2.3) '@types/lodash': - specifier: ^4.17.21 - version: 4.17.21 + specifier: ^4.17.23 + version: 4.17.23 '@types/node': - specifier: ^22.19.3 - version: 22.19.3 + specifier: ^22.19.5 + version: 22.19.5 '@types/react': - specifier: ^18.3.18 + specifier: ^18.3.27 version: 18.3.27 '@vitest/coverage-v8': specifier: ^2.1.9 - version: 2.1.9(vitest@2.1.9(@types/node@22.19.3)(jsdom@27.3.0)) + version: 2.1.9(vitest@2.1.9(@types/node@22.19.5)(jsdom@27.4.0)) eslint: specifier: ^9.39.2 version: 9.39.2 jsdom: - specifier: ^27.3.0 - version: 27.3.0 + specifier: ^27.4.0 + version: 27.4.0 react: - specifier: ^18.3.1 - version: 18.3.1 + specifier: ^19.2.3 + version: 19.2.3 react-redux: specifier: ^9.2.0 - version: 9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1) + version: 9.2.0(@types/react@18.3.27)(react@19.2.3)(redux@5.0.1) typescript: specifier: ^5.9.3 version: 5.9.3 typescript-eslint: - specifier: ^8.50.1 - version: 8.50.1(eslint@9.39.2)(typescript@5.9.3) + specifier: ^8.53.0 + version: 8.53.0(eslint@9.39.2)(typescript@5.9.3) vite: specifier: ^6.4.1 - version: 6.4.1(@types/node@22.19.3) + version: 6.4.1(@types/node@22.19.5) vite-plugin-dts: specifier: ^4.5.4 - version: 4.5.4(@types/node@22.19.3)(rollup@4.54.0)(typescript@5.9.3)(vite@6.4.1(@types/node@22.19.3)) + version: 4.5.4(@types/node@22.19.5)(rollup@4.55.1)(typescript@5.9.3)(vite@6.4.1(@types/node@22.19.5)) vitest: specifier: ^2.1.9 - version: 2.1.9(@types/node@22.19.3)(jsdom@27.3.0) + version: 2.1.9(@types/node@22.19.5)(jsdom@27.4.0) packages: - '@acemir/cssom@0.9.30': - resolution: {integrity: sha512-9CnlMCI0LmCIq0olalQqdWrJHPzm0/tw3gzOA9zJSgvFX7Xau3D24mAGa4BtwxwY69nsuJW6kQqqCzf/mEcQgg==} + '@acemir/cssom@0.9.31': + resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} @@ -77,13 +77,13 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.5': - resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + '@babel/parser@7.28.6': + resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.28.5': - resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + '@babel/types@7.28.6': + resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -113,8 +113,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-syntax-patches-for-csstree@1.0.22': - resolution: {integrity: sha512-qBcx6zYlhleiFfdtzkRgwNC7VVoAwfK76Vmsw5t+PbvtdknO9StgRk7ROvq9so1iqbdW4uLIDAsXRsTfUrIoOw==} + '@csstools/css-syntax-patches-for-csstree@1.0.25': + resolution: {integrity: sha512-g0Kw9W3vjx5BEBAF8c5Fm2NcB/Fs8jJXh85aXqwEXiL+tqtOut07TWgyaGzAAfTM+gKckrrncyeGEZPcaRgm2Q==} engines: {node: '>=18'} '@csstools/css-tokenizer@3.0.4': @@ -415,8 +415,8 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.9.0': - resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -453,6 +453,15 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@exodus/bytes@1.8.0': + resolution: {integrity: sha512-8JPn18Bcp8Uo1T82gR8lh2guEOa5KKU/IEKvvdp0sgmi7coPBWf1Doi1EXsGZb2ehc8ym/StJCjffYV+ne7sXQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@exodus/crypto': ^1.0.0-rc.4 + peerDependenciesMeta: + '@exodus/crypto': + optional: true + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -535,113 +544,128 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.54.0': - resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==} + '@rollup/rollup-android-arm-eabi@4.55.1': + resolution: {integrity: sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.54.0': - resolution: {integrity: sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==} + '@rollup/rollup-android-arm64@4.55.1': + resolution: {integrity: sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.54.0': - resolution: {integrity: sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==} + '@rollup/rollup-darwin-arm64@4.55.1': + resolution: {integrity: sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.54.0': - resolution: {integrity: sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==} + '@rollup/rollup-darwin-x64@4.55.1': + resolution: {integrity: sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.54.0': - resolution: {integrity: sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==} + '@rollup/rollup-freebsd-arm64@4.55.1': + resolution: {integrity: sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.54.0': - resolution: {integrity: sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==} + '@rollup/rollup-freebsd-x64@4.55.1': + resolution: {integrity: sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.54.0': - resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==} + '@rollup/rollup-linux-arm-gnueabihf@4.55.1': + resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.54.0': - resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==} + '@rollup/rollup-linux-arm-musleabihf@4.55.1': + resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.54.0': - resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==} + '@rollup/rollup-linux-arm64-gnu@4.55.1': + resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.54.0': - resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==} + '@rollup/rollup-linux-arm64-musl@4.55.1': + resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loong64-gnu@4.54.0': - resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==} + '@rollup/rollup-linux-loong64-gnu@4.55.1': + resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.54.0': - resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==} + '@rollup/rollup-linux-loong64-musl@4.55.1': + resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.55.1': + resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.55.1': + resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.54.0': - resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==} + '@rollup/rollup-linux-riscv64-gnu@4.55.1': + resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.54.0': - resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==} + '@rollup/rollup-linux-riscv64-musl@4.55.1': + resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.54.0': - resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==} + '@rollup/rollup-linux-s390x-gnu@4.55.1': + resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.54.0': - resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==} + '@rollup/rollup-linux-x64-gnu@4.55.1': + resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.54.0': - resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==} + '@rollup/rollup-linux-x64-musl@4.55.1': + resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==} cpu: [x64] os: [linux] - '@rollup/rollup-openharmony-arm64@4.54.0': - resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==} + '@rollup/rollup-openbsd-x64@4.55.1': + resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.55.1': + resolution: {integrity: sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.54.0': - resolution: {integrity: sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==} + '@rollup/rollup-win32-arm64-msvc@4.55.1': + resolution: {integrity: sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.54.0': - resolution: {integrity: sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==} + '@rollup/rollup-win32-ia32-msvc@4.55.1': + resolution: {integrity: sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.54.0': - resolution: {integrity: sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==} + '@rollup/rollup-win32-x64-gnu@4.55.1': + resolution: {integrity: sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.54.0': - resolution: {integrity: sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==} + '@rollup/rollup-win32-x64-msvc@4.55.1': + resolution: {integrity: sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==} cpu: [x64] os: [win32] @@ -690,11 +714,11 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/lodash@4.17.21': - resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} + '@types/lodash@4.17.23': + resolution: {integrity: sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==} - '@types/node@22.19.3': - resolution: {integrity: sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==} + '@types/node@22.19.5': + resolution: {integrity: sha512-HfF8+mYcHPcPypui3w3mvzuIErlNOh2OAG+BCeBZCEwyiD5ls2SiCwEyT47OELtf7M3nHxBdu0FsmzdKxkN52Q==} '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} @@ -705,63 +729,63 @@ packages: '@types/use-sync-external-store@0.0.6': resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} - '@typescript-eslint/eslint-plugin@8.50.1': - resolution: {integrity: sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==} + '@typescript-eslint/eslint-plugin@8.53.0': + resolution: {integrity: sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.50.1 + '@typescript-eslint/parser': ^8.53.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.50.1': - resolution: {integrity: sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg==} + '@typescript-eslint/parser@8.53.0': + resolution: {integrity: sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.50.1': - resolution: {integrity: sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==} + '@typescript-eslint/project-service@8.53.0': + resolution: {integrity: sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.50.1': - resolution: {integrity: sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw==} + '@typescript-eslint/scope-manager@8.53.0': + resolution: {integrity: sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.50.1': - resolution: {integrity: sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==} + '@typescript-eslint/tsconfig-utils@8.53.0': + resolution: {integrity: sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.50.1': - resolution: {integrity: sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg==} + '@typescript-eslint/type-utils@8.53.0': + resolution: {integrity: sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.50.1': - resolution: {integrity: sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==} + '@typescript-eslint/types@8.53.0': + resolution: {integrity: sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.50.1': - resolution: {integrity: sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==} + '@typescript-eslint/typescript-estree@8.53.0': + resolution: {integrity: sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.50.1': - resolution: {integrity: sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ==} + '@typescript-eslint/utils@8.53.0': + resolution: {integrity: sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.50.1': - resolution: {integrity: sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==} + '@typescript-eslint/visitor-keys@8.53.0': + resolution: {integrity: sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@vitest/coverage-v8@2.1.9': @@ -927,8 +951,8 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - check-error@2.1.1: - resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} color-convert@2.0.1: @@ -958,8 +982,8 @@ packages: resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - cssstyle@5.3.5: - resolution: {integrity: sha512-GlsEptulso7Jg0VaOZ8BXQi3AkYM5BOJKEO/rjMidSCq70FkIC5y0eawrCXeYzxgt3OCf4Ls+eoxN+/05vN0Ag==} + cssstyle@5.3.7: + resolution: {integrity: sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==} engines: {node: '>=20'} csstype@3.2.3: @@ -991,8 +1015,8 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - diff@8.0.2: - resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} + diff@8.0.3: + resolution: {integrity: sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==} engines: {node: '>=0.3.1'} eastasianwidth@0.2.0: @@ -1055,8 +1079,8 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -1160,9 +1184,9 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true - html-encoding-sniffer@4.0.0: - resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} - engines: {node: '>=18'} + html-encoding-sniffer@6.0.0: + resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -1175,10 +1199,6 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1187,8 +1207,8 @@ packages: resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} - immer@11.1.0: - resolution: {integrity: sha512-dlzb07f5LDY+tzs+iLCSXV2yuhaYfezqyZQc+n6baLECWkOMEWxkECAOnXL0ba7lsA25fM9b2jtzpu/uxo1a7g==} + immer@11.1.3: + resolution: {integrity: sha512-6jQTc5z0KJFtr1UgFpIL3N9XSC3saRaI9PwWtzM2pSqkNGtiNkYY2OSwkOGDK2XcTRcLb1pi/aNkKZz0nxVH4Q==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -1246,15 +1266,12 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.1.1: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsdom@27.3.0: - resolution: {integrity: sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==} + jsdom@27.4.0: + resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: canvas: ^3.0.0 @@ -1301,10 +1318,6 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - loupe@3.2.1: resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} @@ -1454,8 +1467,8 @@ packages: redux: optional: true - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + react@19.2.3: + resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} engines: {node: '>=0.10.0'} redux-thunk@3.1.0: @@ -1482,14 +1495,11 @@ packages: engines: {node: '>= 0.4'} hasBin: true - rollup@4.54.0: - resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==} + rollup@4.55.1: + resolution: {integrity: sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} @@ -1616,8 +1626,8 @@ packages: resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} engines: {node: '>=20'} - ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' @@ -1626,8 +1636,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.50.1: - resolution: {integrity: sha512-ytTHO+SoYSbhAH9CrYnMhiLx8To6PSSvqnvXyPUgPETCvB6eBKmTI9w6XMPS3HsBRGkwTVBX+urA8dYQx6bHfQ==} + typescript-eslint@8.53.0: + resolution: {integrity: sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -1643,8 +1653,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - ufo@1.6.1: - resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + ufo@1.6.2: + resolution: {integrity: sha512-heMioaxBcG9+Znsda5Q8sQbWnLJSl98AFDXTO80wELWEzX3hordXsTdxrIfMQoO9IY1MEnoGoPjpoKpMj+Yx0Q==} undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -1778,14 +1788,10 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - webidl-conversions@8.0.0: - resolution: {integrity: sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==} + webidl-conversions@8.0.1: + resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} engines: {node: '>=20'} - whatwg-encoding@3.1.1: - resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} - engines: {node: '>=18'} - whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} @@ -1816,8 +1822,8 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -1844,7 +1850,7 @@ packages: snapshots: - '@acemir/cssom@0.9.30': {} + '@acemir/cssom@0.9.31': {} '@ampproject/remapping@2.3.0': dependencies: @@ -1873,11 +1879,11 @@ snapshots: '@babel/helper-validator-identifier@7.28.5': {} - '@babel/parser@7.28.5': + '@babel/parser@7.28.6': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.28.6 - '@babel/types@7.28.5': + '@babel/types@7.28.6': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 @@ -1902,7 +1908,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-syntax-patches-for-csstree@1.0.22': {} + '@csstools/css-syntax-patches-for-csstree@1.0.25': {} '@csstools/css-tokenizer@3.0.4': {} @@ -2053,7 +2059,7 @@ snapshots: '@esbuild/win32-x64@0.25.12': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)': + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2)': dependencies: eslint: 9.39.2 eslint-visitor-keys: 3.4.3 @@ -2099,6 +2105,8 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@exodus/bytes@1.8.0': {} + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -2141,24 +2149,24 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@microsoft/api-extractor-model@7.32.2(@types/node@22.19.3)': + '@microsoft/api-extractor-model@7.32.2(@types/node@22.19.5)': dependencies: '@microsoft/tsdoc': 0.16.0 '@microsoft/tsdoc-config': 0.18.0 - '@rushstack/node-core-library': 5.19.1(@types/node@22.19.3) + '@rushstack/node-core-library': 5.19.1(@types/node@22.19.5) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.55.2(@types/node@22.19.3)': + '@microsoft/api-extractor@7.55.2(@types/node@22.19.5)': dependencies: - '@microsoft/api-extractor-model': 7.32.2(@types/node@22.19.3) + '@microsoft/api-extractor-model': 7.32.2(@types/node@22.19.5) '@microsoft/tsdoc': 0.16.0 '@microsoft/tsdoc-config': 0.18.0 - '@rushstack/node-core-library': 5.19.1(@types/node@22.19.3) + '@rushstack/node-core-library': 5.19.1(@types/node@22.19.5) '@rushstack/rig-package': 0.6.0 - '@rushstack/terminal': 0.19.5(@types/node@22.19.3) - '@rushstack/ts-command-line': 5.1.5(@types/node@22.19.3) - diff: 8.0.2 + '@rushstack/terminal': 0.19.5(@types/node@22.19.5) + '@rushstack/ts-command-line': 5.1.5(@types/node@22.19.5) + diff: 8.0.3 lodash: 4.17.21 minimatch: 10.0.3 resolve: 1.22.11 @@ -2180,93 +2188,102 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1))(react@18.3.1)': + '@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@18.3.27)(react@19.2.3)(redux@5.0.1))(react@19.2.3)': dependencies: '@standard-schema/spec': 1.1.0 '@standard-schema/utils': 0.3.0 - immer: 11.1.0 + immer: 11.1.3 redux: 5.0.1 redux-thunk: 3.1.0(redux@5.0.1) reselect: 5.1.1 optionalDependencies: - react: 18.3.1 - react-redux: 9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1) + react: 19.2.3 + react-redux: 9.2.0(@types/react@18.3.27)(react@19.2.3)(redux@5.0.1) - '@rollup/pluginutils@5.3.0(rollup@4.54.0)': + '@rollup/pluginutils@5.3.0(rollup@4.55.1)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 picomatch: 4.0.3 optionalDependencies: - rollup: 4.54.0 + rollup: 4.55.1 + + '@rollup/rollup-android-arm-eabi@4.55.1': + optional: true - '@rollup/rollup-android-arm-eabi@4.54.0': + '@rollup/rollup-android-arm64@4.55.1': optional: true - '@rollup/rollup-android-arm64@4.54.0': + '@rollup/rollup-darwin-arm64@4.55.1': optional: true - '@rollup/rollup-darwin-arm64@4.54.0': + '@rollup/rollup-darwin-x64@4.55.1': optional: true - '@rollup/rollup-darwin-x64@4.54.0': + '@rollup/rollup-freebsd-arm64@4.55.1': optional: true - '@rollup/rollup-freebsd-arm64@4.54.0': + '@rollup/rollup-freebsd-x64@4.55.1': optional: true - '@rollup/rollup-freebsd-x64@4.54.0': + '@rollup/rollup-linux-arm-gnueabihf@4.55.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.54.0': + '@rollup/rollup-linux-arm-musleabihf@4.55.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.54.0': + '@rollup/rollup-linux-arm64-gnu@4.55.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.54.0': + '@rollup/rollup-linux-arm64-musl@4.55.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.54.0': + '@rollup/rollup-linux-loong64-gnu@4.55.1': optional: true - '@rollup/rollup-linux-loong64-gnu@4.54.0': + '@rollup/rollup-linux-loong64-musl@4.55.1': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.54.0': + '@rollup/rollup-linux-ppc64-gnu@4.55.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.54.0': + '@rollup/rollup-linux-ppc64-musl@4.55.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.54.0': + '@rollup/rollup-linux-riscv64-gnu@4.55.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.54.0': + '@rollup/rollup-linux-riscv64-musl@4.55.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.54.0': + '@rollup/rollup-linux-s390x-gnu@4.55.1': optional: true - '@rollup/rollup-linux-x64-musl@4.54.0': + '@rollup/rollup-linux-x64-gnu@4.55.1': optional: true - '@rollup/rollup-openharmony-arm64@4.54.0': + '@rollup/rollup-linux-x64-musl@4.55.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.54.0': + '@rollup/rollup-openbsd-x64@4.55.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.54.0': + '@rollup/rollup-openharmony-arm64@4.55.1': optional: true - '@rollup/rollup-win32-x64-gnu@4.54.0': + '@rollup/rollup-win32-arm64-msvc@4.55.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.54.0': + '@rollup/rollup-win32-ia32-msvc@4.55.1': optional: true - '@rushstack/node-core-library@5.19.1(@types/node@22.19.3)': + '@rollup/rollup-win32-x64-gnu@4.55.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.55.1': + optional: true + + '@rushstack/node-core-library@5.19.1(@types/node@22.19.5)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -2277,28 +2294,28 @@ snapshots: resolve: 1.22.11 semver: 7.5.4 optionalDependencies: - '@types/node': 22.19.3 + '@types/node': 22.19.5 - '@rushstack/problem-matcher@0.1.1(@types/node@22.19.3)': + '@rushstack/problem-matcher@0.1.1(@types/node@22.19.5)': optionalDependencies: - '@types/node': 22.19.3 + '@types/node': 22.19.5 '@rushstack/rig-package@0.6.0': dependencies: resolve: 1.22.11 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.19.5(@types/node@22.19.3)': + '@rushstack/terminal@0.19.5(@types/node@22.19.5)': dependencies: - '@rushstack/node-core-library': 5.19.1(@types/node@22.19.3) - '@rushstack/problem-matcher': 0.1.1(@types/node@22.19.3) + '@rushstack/node-core-library': 5.19.1(@types/node@22.19.5) + '@rushstack/problem-matcher': 0.1.1(@types/node@22.19.5) supports-color: 8.1.1 optionalDependencies: - '@types/node': 22.19.3 + '@types/node': 22.19.5 - '@rushstack/ts-command-line@5.1.5(@types/node@22.19.3)': + '@rushstack/ts-command-line@5.1.5(@types/node@22.19.5)': dependencies: - '@rushstack/terminal': 0.19.5(@types/node@22.19.3) + '@rushstack/terminal': 0.19.5(@types/node@22.19.5) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -2315,9 +2332,9 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/lodash@4.17.21': {} + '@types/lodash@4.17.23': {} - '@types/node@22.19.3': + '@types/node@22.19.5': dependencies: undici-types: 6.21.0 @@ -2330,98 +2347,98 @@ snapshots: '@types/use-sync-external-store@0.0.6': {} - '@typescript-eslint/eslint-plugin@8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.50.1 - '@typescript-eslint/type-utils': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.1 + '@typescript-eslint/parser': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.53.0 + '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.53.0 eslint: 9.39.2 ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.50.1(eslint@9.39.2)(typescript@5.9.3)': + '@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.50.1 - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.1 + '@typescript-eslint/scope-manager': 8.53.0 + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.53.0 debug: 4.4.3 eslint: 9.39.2 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.50.1(typescript@5.9.3)': + '@typescript-eslint/project-service@8.53.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) - '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) + '@typescript-eslint/types': 8.53.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.50.1': + '@typescript-eslint/scope-manager@8.53.0': dependencies: - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/visitor-keys': 8.50.1 + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/visitor-keys': 8.53.0 - '@typescript-eslint/tsconfig-utils@8.50.1(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.53.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.50.1(eslint@9.39.2)(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.53.0(eslint@9.39.2)(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.1(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2 - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.50.1': {} + '@typescript-eslint/types@8.53.0': {} - '@typescript-eslint/typescript-estree@8.50.1(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.53.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.50.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/visitor-keys': 8.50.1 + '@typescript-eslint/project-service': 8.53.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/visitor-keys': 8.53.0 debug: 4.4.3 minimatch: 9.0.5 semver: 7.7.3 tinyglobby: 0.2.15 - ts-api-utils: 2.1.0(typescript@5.9.3) + ts-api-utils: 2.4.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.50.1(eslint@9.39.2)(typescript@5.9.3)': + '@typescript-eslint/utils@8.53.0(eslint@9.39.2)(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2) - '@typescript-eslint/scope-manager': 8.50.1 - '@typescript-eslint/types': 8.50.1 - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2) + '@typescript-eslint/scope-manager': 8.53.0 + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) eslint: 9.39.2 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.50.1': + '@typescript-eslint/visitor-keys@8.53.0': dependencies: - '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/types': 8.53.0 eslint-visitor-keys: 4.2.1 - '@vitest/coverage-v8@2.1.9(vitest@2.1.9(@types/node@22.19.3)(jsdom@27.3.0))': + '@vitest/coverage-v8@2.1.9(vitest@2.1.9(@types/node@22.19.5)(jsdom@27.4.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -2435,7 +2452,7 @@ snapshots: std-env: 3.10.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.1.9(@types/node@22.19.3)(jsdom@27.3.0) + vitest: 2.1.9(@types/node@22.19.5)(jsdom@27.4.0) transitivePeerDependencies: - supports-color @@ -2446,13 +2463,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@22.19.3))': + '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@22.19.5))': dependencies: '@vitest/spy': 2.1.9 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 5.4.21(@types/node@22.19.3) + vite: 5.4.21(@types/node@22.19.5) '@vitest/pretty-format@2.1.9': dependencies: @@ -2493,7 +2510,7 @@ snapshots: '@vue/compiler-core@3.5.26': dependencies: - '@babel/parser': 7.28.5 + '@babel/parser': 7.28.6 '@vue/shared': 3.5.26 entities: 7.0.0 estree-walker: 2.0.2 @@ -2603,7 +2620,7 @@ snapshots: chai@5.3.3: dependencies: assertion-error: 2.0.1 - check-error: 2.1.1 + check-error: 2.1.3 deep-eql: 5.0.2 loupe: 3.2.1 pathval: 2.0.1 @@ -2613,7 +2630,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - check-error@2.1.1: {} + check-error@2.1.3: {} color-convert@2.0.1: dependencies: @@ -2640,11 +2657,12 @@ snapshots: mdn-data: 2.12.2 source-map-js: 1.2.1 - cssstyle@5.3.5: + cssstyle@5.3.7: dependencies: '@asamuzakjp/css-color': 4.1.1 - '@csstools/css-syntax-patches-for-csstree': 1.0.22 + '@csstools/css-syntax-patches-for-csstree': 1.0.25 css-tree: 3.1.0 + lru-cache: 11.2.4 csstype@3.2.3: {} @@ -2665,7 +2683,7 @@ snapshots: deep-is@0.1.4: {} - diff@8.0.2: {} + diff@8.0.3: {} eastasianwidth@0.2.0: {} @@ -2747,7 +2765,7 @@ snapshots: eslint@9.39.2: dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2) + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.21.1 '@eslint/config-helpers': 0.4.2 @@ -2767,7 +2785,7 @@ snapshots: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 - esquery: 1.6.0 + esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 @@ -2790,7 +2808,7 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 4.2.1 - esquery@1.6.0: + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -2879,9 +2897,11 @@ snapshots: he@1.2.0: {} - html-encoding-sniffer@4.0.0: + html-encoding-sniffer@6.0.0: dependencies: - whatwg-encoding: 3.1.1 + '@exodus/bytes': 1.8.0 + transitivePeerDependencies: + - '@exodus/crypto' html-escaper@2.0.2: {} @@ -2899,15 +2919,11 @@ snapshots: transitivePeerDependencies: - supports-color - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - ignore@5.3.2: {} ignore@7.0.5: {} - immer@11.1.0: {} + immer@11.1.3: {} import-fresh@3.3.1: dependencies: @@ -2963,20 +2979,19 @@ snapshots: jju@1.4.0: {} - js-tokens@4.0.0: {} - js-yaml@4.1.1: dependencies: argparse: 2.0.1 - jsdom@27.3.0: + jsdom@27.4.0: dependencies: - '@acemir/cssom': 0.9.30 + '@acemir/cssom': 0.9.31 '@asamuzakjp/dom-selector': 6.7.6 - cssstyle: 5.3.5 + '@exodus/bytes': 1.8.0 + cssstyle: 5.3.7 data-urls: 6.0.0 decimal.js: 10.6.0 - html-encoding-sniffer: 4.0.0 + html-encoding-sniffer: 6.0.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 @@ -2985,13 +3000,13 @@ snapshots: symbol-tree: 3.2.4 tough-cookie: 6.0.0 w3c-xmlserializer: 5.0.0 - webidl-conversions: 8.0.0 - whatwg-encoding: 3.1.1 + webidl-conversions: 8.0.1 whatwg-mimetype: 4.0.0 whatwg-url: 15.1.0 - ws: 8.18.3 + ws: 8.19.0 xml-name-validator: 5.0.0 transitivePeerDependencies: + - '@exodus/crypto' - bufferutil - supports-color - utf-8-validate @@ -3035,10 +3050,6 @@ snapshots: lodash@4.17.21: {} - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - loupe@3.2.1: {} lru-cache@10.4.3: {} @@ -3055,8 +3066,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.28.5 - '@babel/types': 7.28.5 + '@babel/parser': 7.28.6 + '@babel/types': 7.28.6 source-map-js: 1.2.1 make-dir@4.0.0: @@ -3084,7 +3095,7 @@ snapshots: acorn: 8.15.0 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.6.1 + ufo: 1.6.2 ms@2.1.3: {} @@ -3168,18 +3179,16 @@ snapshots: quansync@0.2.11: {} - react-redux@9.2.0(@types/react@18.3.27)(react@18.3.1)(redux@5.0.1): + react-redux@9.2.0(@types/react@18.3.27)(react@19.2.3)(redux@5.0.1): dependencies: '@types/use-sync-external-store': 0.0.6 - react: 18.3.1 - use-sync-external-store: 1.6.0(react@18.3.1) + react: 19.2.3 + use-sync-external-store: 1.6.0(react@19.2.3) optionalDependencies: '@types/react': 18.3.27 redux: 5.0.1 - react@18.3.1: - dependencies: - loose-envify: 1.4.0 + react@19.2.3: {} redux-thunk@3.1.0(redux@5.0.1): dependencies: @@ -3199,36 +3208,37 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - rollup@4.54.0: + rollup@4.55.1: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.54.0 - '@rollup/rollup-android-arm64': 4.54.0 - '@rollup/rollup-darwin-arm64': 4.54.0 - '@rollup/rollup-darwin-x64': 4.54.0 - '@rollup/rollup-freebsd-arm64': 4.54.0 - '@rollup/rollup-freebsd-x64': 4.54.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.54.0 - '@rollup/rollup-linux-arm-musleabihf': 4.54.0 - '@rollup/rollup-linux-arm64-gnu': 4.54.0 - '@rollup/rollup-linux-arm64-musl': 4.54.0 - '@rollup/rollup-linux-loong64-gnu': 4.54.0 - '@rollup/rollup-linux-ppc64-gnu': 4.54.0 - '@rollup/rollup-linux-riscv64-gnu': 4.54.0 - '@rollup/rollup-linux-riscv64-musl': 4.54.0 - '@rollup/rollup-linux-s390x-gnu': 4.54.0 - '@rollup/rollup-linux-x64-gnu': 4.54.0 - '@rollup/rollup-linux-x64-musl': 4.54.0 - '@rollup/rollup-openharmony-arm64': 4.54.0 - '@rollup/rollup-win32-arm64-msvc': 4.54.0 - '@rollup/rollup-win32-ia32-msvc': 4.54.0 - '@rollup/rollup-win32-x64-gnu': 4.54.0 - '@rollup/rollup-win32-x64-msvc': 4.54.0 + '@rollup/rollup-android-arm-eabi': 4.55.1 + '@rollup/rollup-android-arm64': 4.55.1 + '@rollup/rollup-darwin-arm64': 4.55.1 + '@rollup/rollup-darwin-x64': 4.55.1 + '@rollup/rollup-freebsd-arm64': 4.55.1 + '@rollup/rollup-freebsd-x64': 4.55.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.55.1 + '@rollup/rollup-linux-arm-musleabihf': 4.55.1 + '@rollup/rollup-linux-arm64-gnu': 4.55.1 + '@rollup/rollup-linux-arm64-musl': 4.55.1 + '@rollup/rollup-linux-loong64-gnu': 4.55.1 + '@rollup/rollup-linux-loong64-musl': 4.55.1 + '@rollup/rollup-linux-ppc64-gnu': 4.55.1 + '@rollup/rollup-linux-ppc64-musl': 4.55.1 + '@rollup/rollup-linux-riscv64-gnu': 4.55.1 + '@rollup/rollup-linux-riscv64-musl': 4.55.1 + '@rollup/rollup-linux-s390x-gnu': 4.55.1 + '@rollup/rollup-linux-x64-gnu': 4.55.1 + '@rollup/rollup-linux-x64-musl': 4.55.1 + '@rollup/rollup-openbsd-x64': 4.55.1 + '@rollup/rollup-openharmony-arm64': 4.55.1 + '@rollup/rollup-win32-arm64-msvc': 4.55.1 + '@rollup/rollup-win32-ia32-msvc': 4.55.1 + '@rollup/rollup-win32-x64-gnu': 4.55.1 + '@rollup/rollup-win32-x64-msvc': 4.55.1 fsevents: 2.3.3 - safer-buffer@2.1.2: {} - saxes@6.0.0: dependencies: xmlchars: 2.2.0 @@ -3330,7 +3340,7 @@ snapshots: dependencies: punycode: 2.3.1 - ts-api-utils@2.1.0(typescript@5.9.3): + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 @@ -3338,12 +3348,12 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.50.1(eslint@9.39.2)(typescript@5.9.3): + typescript-eslint@8.53.0(eslint@9.39.2)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/parser': 8.50.1(eslint@9.39.2)(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.1(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/parser': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3) eslint: 9.39.2 typescript: 5.9.3 transitivePeerDependencies: @@ -3353,7 +3363,7 @@ snapshots: typescript@5.9.3: {} - ufo@1.6.1: {} + ufo@1.6.2: {} undici-types@6.21.0: {} @@ -3363,17 +3373,17 @@ snapshots: dependencies: punycode: 2.3.1 - use-sync-external-store@1.6.0(react@18.3.1): + use-sync-external-store@1.6.0(react@19.2.3): dependencies: - react: 18.3.1 + react: 19.2.3 - vite-node@2.1.9(@types/node@22.19.3): + vite-node@2.1.9(@types/node@22.19.5): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 1.1.2 - vite: 5.4.21(@types/node@22.19.3) + vite: 5.4.21(@types/node@22.19.5) transitivePeerDependencies: - '@types/node' - less @@ -3385,10 +3395,10 @@ snapshots: - supports-color - terser - vite-plugin-dts@4.5.4(@types/node@22.19.3)(rollup@4.54.0)(typescript@5.9.3)(vite@6.4.1(@types/node@22.19.3)): + vite-plugin-dts@4.5.4(@types/node@22.19.5)(rollup@4.55.1)(typescript@5.9.3)(vite@6.4.1(@types/node@22.19.5)): dependencies: - '@microsoft/api-extractor': 7.55.2(@types/node@22.19.3) - '@rollup/pluginutils': 5.3.0(rollup@4.54.0) + '@microsoft/api-extractor': 7.55.2(@types/node@22.19.5) + '@rollup/pluginutils': 5.3.0(rollup@4.55.1) '@volar/typescript': 2.4.27 '@vue/language-core': 2.2.0(typescript@5.9.3) compare-versions: 6.1.1 @@ -3398,37 +3408,37 @@ snapshots: magic-string: 0.30.21 typescript: 5.9.3 optionalDependencies: - vite: 6.4.1(@types/node@22.19.3) + vite: 6.4.1(@types/node@22.19.5) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite@5.4.21(@types/node@22.19.3): + vite@5.4.21(@types/node@22.19.5): dependencies: esbuild: 0.21.5 postcss: 8.5.6 - rollup: 4.54.0 + rollup: 4.55.1 optionalDependencies: - '@types/node': 22.19.3 + '@types/node': 22.19.5 fsevents: 2.3.3 - vite@6.4.1(@types/node@22.19.3): + vite@6.4.1(@types/node@22.19.5): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.54.0 + rollup: 4.55.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 22.19.3 + '@types/node': 22.19.5 fsevents: 2.3.3 - vitest@2.1.9(@types/node@22.19.3)(jsdom@27.3.0): + vitest@2.1.9(@types/node@22.19.5)(jsdom@27.4.0): dependencies: '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@22.19.3)) + '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@22.19.5)) '@vitest/pretty-format': 2.1.9 '@vitest/runner': 2.1.9 '@vitest/snapshot': 2.1.9 @@ -3444,12 +3454,12 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.1.1 tinyrainbow: 1.2.0 - vite: 5.4.21(@types/node@22.19.3) - vite-node: 2.1.9(@types/node@22.19.3) + vite: 5.4.21(@types/node@22.19.5) + vite-node: 2.1.9(@types/node@22.19.5) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.19.3 - jsdom: 27.3.0 + '@types/node': 22.19.5 + jsdom: 27.4.0 transitivePeerDependencies: - less - lightningcss @@ -3467,18 +3477,14 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - webidl-conversions@8.0.0: {} - - whatwg-encoding@3.1.1: - dependencies: - iconv-lite: 0.6.3 + webidl-conversions@8.0.1: {} whatwg-mimetype@4.0.0: {} whatwg-url@15.1.0: dependencies: tr46: 6.0.0 - webidl-conversions: 8.0.0 + webidl-conversions: 8.0.1 which@2.0.2: dependencies: @@ -3503,7 +3509,7 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.2 - ws@8.18.3: {} + ws@8.19.0: {} xml-name-validator@5.0.0: {} From ee3a1b7a50394b6c8951e4d860a8bb245aaa4b02 Mon Sep 17 00:00:00 2001 From: senelway Date: Tue, 13 Jan 2026 14:23:50 +0000 Subject: [PATCH 5/5] upd --- lib/reducer/helpers.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/reducer/helpers.ts b/lib/reducer/helpers.ts index ff62bab..a576c5a 100644 --- a/lib/reducer/helpers.ts +++ b/lib/reducer/helpers.ts @@ -1,6 +1,7 @@ +import { type WritableDraft } from '@reduxjs/toolkit'; import { type CdeebeeSettings, type CdeebeeModule, CdeebeeValueList } from './types'; -export function checkModule(settings: CdeebeeSettings, module: CdeebeeModule, result: () => void) { +export function checkModule(settings: CdeebeeSettings | WritableDraft>, module: CdeebeeModule, result: () => void) { if (settings.modules.includes(module)) { result(); }