diff --git a/.changeset/forty-cameras-check.md b/.changeset/forty-cameras-check.md new file mode 100644 index 0000000000..ab3fb6b944 --- /dev/null +++ b/.changeset/forty-cameras-check.md @@ -0,0 +1,5 @@ +--- +'@urql/solid': minor +--- + +Initial release diff --git a/exchanges/auth/package.json b/exchanges/auth/package.json index bb9ef542d0..e5588eb4e3 100644 --- a/exchanges/auth/package.json +++ b/exchanges/auth/package.json @@ -40,7 +40,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist extras", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -57,7 +57,8 @@ }, "devDependencies": { "@urql/core": "workspace:*", - "graphql": "^16.0.0" + "graphql": "^16.0.0", + "vitest": "^0.30.1" }, "publishConfig": { "access": "public", diff --git a/exchanges/auth/vitest.config.ts b/exchanges/auth/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/exchanges/auth/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/exchanges/context/package.json b/exchanges/context/package.json index 3b3ae0b659..b917caf54c 100644 --- a/exchanges/context/package.json +++ b/exchanges/context/package.json @@ -39,7 +39,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist extras", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -56,7 +56,8 @@ }, "devDependencies": { "@urql/core": "workspace:*", - "graphql": "^16.0.0" + "graphql": "^16.0.0", + "vitest": "^0.30.1" }, "publishConfig": { "access": "public", diff --git a/exchanges/context/vitest.config.ts b/exchanges/context/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/exchanges/context/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/exchanges/execute/package.json b/exchanges/execute/package.json index 963276da6b..a363a5dfd6 100644 --- a/exchanges/execute/package.json +++ b/exchanges/execute/package.json @@ -40,7 +40,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist extras", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -58,7 +58,8 @@ }, "devDependencies": { "@urql/core": "workspace:*", - "graphql": "^16.0.0" + "graphql": "^16.0.0", + "vitest": "^0.30.1" }, "publishConfig": { "access": "public", diff --git a/exchanges/execute/vitest.config.ts b/exchanges/execute/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/exchanges/execute/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/exchanges/graphcache/package.json b/exchanges/graphcache/package.json index 76aef184c7..cd76d32d01 100644 --- a/exchanges/graphcache/package.json +++ b/exchanges/graphcache/package.json @@ -54,7 +54,7 @@ "default-storage/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist extras", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -79,7 +79,8 @@ "graphql": "^16.6.0", "react": "^17.0.1", "react-dom": "^17.0.1", - "urql": "workspace:*" + "urql": "workspace:*", + "vitest": "^0.30.1" }, "publishConfig": { "access": "public", diff --git a/exchanges/graphcache/vitest.config.ts b/exchanges/graphcache/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/exchanges/graphcache/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/exchanges/persisted/package.json b/exchanges/persisted/package.json index d40a652f84..002457d9e9 100644 --- a/exchanges/persisted/package.json +++ b/exchanges/persisted/package.json @@ -38,7 +38,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist extras", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -55,7 +55,8 @@ }, "devDependencies": { "@urql/core": "workspace:*", - "graphql": "^16.0.0" + "graphql": "^16.0.0", + "vitest": "^0.30.1" }, "publishConfig": { "access": "public", diff --git a/exchanges/persisted/vitest.config.ts b/exchanges/persisted/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/exchanges/persisted/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/exchanges/populate/package.json b/exchanges/populate/package.json index 3c60ab7dea..5f5cb519ef 100644 --- a/exchanges/populate/package.json +++ b/exchanges/populate/package.json @@ -38,7 +38,7 @@ "extras/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist extras", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -56,7 +56,8 @@ }, "devDependencies": { "@urql/core": "workspace:*", - "graphql": "^16.0.0" + "graphql": "^16.0.0", + "vitest": "^0.30.1" }, "publishConfig": { "access": "public", diff --git a/exchanges/populate/vitest.config.ts b/exchanges/populate/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/exchanges/populate/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/exchanges/refocus/package.json b/exchanges/refocus/package.json index 9a83208536..23b1531844 100644 --- a/exchanges/refocus/package.json +++ b/exchanges/refocus/package.json @@ -40,7 +40,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -49,9 +49,10 @@ "prepublishOnly": "run-s clean build" }, "devDependencies": { - "@urql/core": "workspace:*", "@types/react": "^17.0.4", - "graphql": "^16.0.0" + "@urql/core": "workspace:*", + "graphql": "^16.0.0", + "vitest": "^0.30.1" }, "peerDependencies": { "@urql/core": "^5.0.0" diff --git a/exchanges/refocus/vitest.config.ts b/exchanges/refocus/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/exchanges/refocus/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/exchanges/request-policy/package.json b/exchanges/request-policy/package.json index c2118e04be..cc2e520473 100644 --- a/exchanges/request-policy/package.json +++ b/exchanges/request-policy/package.json @@ -39,7 +39,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -49,7 +49,8 @@ }, "devDependencies": { "@urql/core": "workspace:*", - "graphql": "^16.0.0" + "graphql": "^16.0.0", + "vitest": "^0.30.1" }, "peerDependencies": { "@urql/core": "^5.0.0" diff --git a/exchanges/request-policy/vitest.config.ts b/exchanges/request-policy/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/exchanges/request-policy/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/exchanges/retry/package.json b/exchanges/retry/package.json index 59a1e00a7a..138c339eb0 100644 --- a/exchanges/retry/package.json +++ b/exchanges/retry/package.json @@ -39,7 +39,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -49,7 +49,8 @@ }, "devDependencies": { "@urql/core": "workspace:*", - "graphql": "^16.0.0" + "graphql": "^16.0.0", + "vitest": "^0.30.1" }, "peerDependencies": { "@urql/core": "^5.0.0" diff --git a/exchanges/retry/vitest.config.ts b/exchanges/retry/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/exchanges/retry/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/package.json b/package.json index 758fdab541..a4a429cb74 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "scripts": { - "test": "vitest", + "test": "test -z $CI && vitest || pnpm -r --parallel run test run", "check": "tsc", "lint": "eslint --ext=js,jsx,ts,tsx .", "build": "node ./scripts/actions/build-all.mjs", diff --git a/packages/core/package.json b/packages/core/package.json index 9ea40dcf3e..c2dfc77a97 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -45,7 +45,7 @@ "internal/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -61,5 +61,8 @@ "publishConfig": { "access": "public", "provenance": true + }, + "devDependencies": { + "vitest": "^0.30.1" } } diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/packages/core/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/packages/introspection/package.json b/packages/introspection/package.json index e992937b9f..06d7d21bbf 100644 --- a/packages/introspection/package.json +++ b/packages/introspection/package.json @@ -37,7 +37,6 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", "clean": "rimraf dist", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -51,7 +50,6 @@ "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" }, - "dependencies": {}, "publishConfig": { "access": "public", "provenance": true diff --git a/packages/next-urql/vitest.config.ts b/packages/next-urql/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/packages/next-urql/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/packages/preact-urql/package.json b/packages/preact-urql/package.json index dede80385d..8ba183e667 100644 --- a/packages/preact-urql/package.json +++ b/packages/preact-urql/package.json @@ -40,7 +40,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -49,10 +49,11 @@ "prepublishOnly": "run-s clean build" }, "devDependencies": { - "@urql/core": "workspace:*", "@testing-library/preact": "^2.0.0", + "@urql/core": "workspace:*", "graphql": "^16.0.0", - "preact": "^10.13.0" + "preact": "^10.13.0", + "vitest": "^0.30.1" }, "peerDependencies": { "@urql/core": "^5.0.0", diff --git a/packages/preact-urql/vitest.config.ts b/packages/preact-urql/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/packages/preact-urql/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/packages/react-urql/package.json b/packages/react-urql/package.json index 65133fd2ec..48944b13bd 100644 --- a/packages/react-urql/package.json +++ b/packages/react-urql/package.json @@ -32,7 +32,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -55,7 +55,8 @@ "react-is": "^17.0.1", "react-ssr-prepass": "^1.1.2", "react-test-renderer": "^17.0.1", - "vite": "^3.2.4" + "vite": "^3.2.4", + "vitest": "^0.30.1" }, "peerDependencies": { "@urql/core": "^5.0.0", diff --git a/packages/react-urql/vitest.config.ts b/packages/react-urql/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/packages/react-urql/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/packages/solid-urql/package.json b/packages/solid-urql/package.json new file mode 100644 index 0000000000..39e3e32495 --- /dev/null +++ b/packages/solid-urql/package.json @@ -0,0 +1,72 @@ +{ + "name": "@urql/solid", + "version": "0.0.0", + "description": "A highly customizable and versatile GraphQL client for Solid", + "sideEffects": false, + "homepage": "https://formidable.com/open-source/urql/docs/", + "bugs": "https://github.com/urql-graphql/urql/issues", + "license": "MIT", + "author": "urql GraphQL Contributors", + "repository": { + "type": "git", + "url": "https://github.com/urql-graphql/urql.git", + "directory": "packages/solid-urql" + }, + "keywords": [ + "graphql client", + "state management", + "cache", + "graphql", + "exchanges", + "solid" + ], + "main": "dist/urql-solid", + "module": "dist/urql-solid.mjs", + "types": "dist/urql-solid.d.ts", + "source": "src/index.ts", + "exports": { + ".": { + "types": "./dist/urql-solid.d.ts", + "import": "./dist/urql-solid.mjs", + "require": "./dist/urql-solid.js", + "source": "./src/index.ts" + }, + "./package.json": "./package.json" + }, + "files": [ + "LICENSE", + "CHANGELOG.md", + "README.md", + "dist/" + ], + "scripts": { + "test": "vitest", + "clean": "rimraf dist", + "check": "tsc --noEmit", + "lint": "eslint --ext=js,jsx,ts,tsx .", + "build": "rollup -c ../../scripts/rollup/config.mjs", + "prepare": "node ../../scripts/prepare/index.js", + "prepublishOnly": "run-s clean build" + }, + "devDependencies": { + "@solidjs/testing-library": "^0.8.2", + "@urql/core": "workspace:*", + "graphql": "^16.0.0", + "jsdom": "^22.1.0", + "vite-plugin-solid": "^2.7.0", + "vite-tsconfig-paths": "^4.2.0", + "vitest": "^0.30.1" + }, + "peerDependencies": { + "@urql/core": "^5.0.0", + "solid-js": "^1.7.7" + }, + "dependencies": { + "@urql/core": "^4.0.0", + "wonka": "^6.3.2" + }, + "publishConfig": { + "access": "public", + "provenance": true + } +} diff --git a/packages/solid-urql/src/context.ts b/packages/solid-urql/src/context.ts new file mode 100644 index 0000000000..ca1c73b100 --- /dev/null +++ b/packages/solid-urql/src/context.ts @@ -0,0 +1,20 @@ +import type { Client } from '@urql/core'; +import { createContext, useContext } from 'solid-js'; + +export const Context = createContext(); +export const Provider = Context.Provider; + +export type UseClient = () => Client; +export const useClient: UseClient = () => { + const client = useContext(Context); + + if (process.env.NODE_ENV !== 'production' && client === undefined) { + const error = + "No client has been specified using urql's Provider. please create a client and add a Provider."; + + console.error(error); + throw new Error(error); + } + + return client!; +}; diff --git a/packages/solid-urql/src/createMutation.test.ts b/packages/solid-urql/src/createMutation.test.ts new file mode 100644 index 0000000000..110e28b0be --- /dev/null +++ b/packages/solid-urql/src/createMutation.test.ts @@ -0,0 +1,113 @@ +// @vitest-environment jsdom + +import { testEffect } from '@solidjs/testing-library'; +import { expect, it, describe, vi } from 'vitest'; +import { CreateMutationState, createMutation } from './createMutation'; +import { + OperationResult, + OperationResultSource, + createClient, + gql, +} from '@urql/core'; +import { makeSubject } from 'wonka'; +import { createEffect } from 'solid-js'; + +const QUERY = gql` + mutation { + test + } +`; + +const client = createClient({ + url: '/graphql', + exchanges: [], + suspense: false, +}); + +vi.mock('./context', () => { + const useClient = () => { + return client!; + }; + + return { useClient }; +}); + +// Given that it is not possible to directly listen to all store changes it is necessary +// to access all relevant parts on which `createEffect` should listen on +const markStateDependencies = (state: CreateMutationState) => { + state.data; + state.error; + state.extensions; + state.fetching; + state.operation; + state.stale; +}; + +describe('createMutation', () => { + it('should have expected state before and after finish', () => { + const subject = makeSubject(); + const clientMutation = vi + .spyOn(client, 'executeMutation') + .mockImplementation( + () => subject.source as OperationResultSource + ); + + return testEffect(done => { + const [state, execute] = createMutation< + { test: boolean }, + { variable: number } + >(QUERY); + + createEffect((run: number = 0) => { + markStateDependencies(state); + + switch (run) { + case 0: { + expect(state).toMatchObject({ + data: undefined, + stale: false, + fetching: false, + error: undefined, + extensions: undefined, + operation: undefined, + }); + + execute({ variable: 1 }); + break; + } + + case 1: { + expect(state).toMatchObject({ + data: undefined, + stale: false, + fetching: true, + error: undefined, + extensions: undefined, + operation: undefined, + }); + + expect(clientMutation).toHaveBeenCalledTimes(1); + subject.next({ data: { test: true }, stale: false }); + + break; + } + + case 2: { + expect(state).toMatchObject({ + data: { test: true }, + stale: false, + fetching: false, + error: undefined, + extensions: undefined, + }); + + done(); + break; + } + } + + return run + 1; + }); + }); + }); +}); diff --git a/packages/solid-urql/src/createMutation.ts b/packages/solid-urql/src/createMutation.ts new file mode 100644 index 0000000000..ba818ed2dd --- /dev/null +++ b/packages/solid-urql/src/createMutation.ts @@ -0,0 +1,177 @@ +import { createStore } from 'solid-js/store'; +import { + type AnyVariables, + type DocumentInput, + type OperationContext, + type Operation, + type OperationResult, + type CombinedError, + createRequest, +} from '@urql/core'; +import { useClient } from './context'; +import { pipe, onPush, filter, take, toPromise } from 'wonka'; + +export type CreateMutationState< + Data = any, + Variables extends AnyVariables = AnyVariables, +> = { + /** Indicates whether `createMutation` is currently executing a mutation. */ + fetching: boolean; + + /** Indicates that the mutation result is not fresh. + * + * @remarks + * The `stale` flag is set to `true` when a new result for the mutation + * is expected. + * This is mostly unused for mutations and will rarely affect you, and + * is more relevant for queries. + * + * @see {@link OperationResult.stale} for the source of this value. + */ + stale: boolean; + /** The {@link OperationResult.data} for the executed mutation. */ + data?: Data; + /** The {@link OperationResult.error} for the executed mutation. */ + error?: CombinedError; + /** The {@link OperationResult.extensions} for the executed mutation. */ + extensions?: Record; + /** The {@link Operation} that the current state is for. + * + * @remarks + * This is the mutation {@link Operation} that has last been executed. + * When {@link CreateMutationState.fetching} is `true`, this is the + * last `Operation` that the current state was for. + */ + operation?: Operation; +}; + +/** Triggers {@link createMutation} to execute its GraphQL mutation operation. + * + * @param variables - variables using which the mutation will be executed. + * @param context - optionally, context options that will be merged with the hook's + * context options and the `Client`’s options. + * @returns the {@link OperationResult} of the mutation. + * + * @remarks + * When called, {@link createMutation} will start the GraphQL mutation + * it currently holds and use the `variables` passed to it. + * + * Once the mutation response comes back from the API, its + * returned promise will resolve to the mutation’s {@link OperationResult} + * and the {@link CreateMutationState} will be updated with the result. + * + * @example + * ```ts + * const [result, executeMutation] = createMutation(UpdateTodo); + * const start = async ({ id, title }) => { + * const result = await executeMutation({ id, title }); + * }; + */ +export type CreateMutationExecute< + Data = any, + Variables extends AnyVariables = AnyVariables, +> = ( + variables: Variables, + context?: Partial +) => Promise>; + +/** Result tuple returned by the {@link createMutation} hook. + * + * @remarks + * Similarly to a `createSignal` hook’s return value, + * the first element is the {@link createMutation}’s state, updated + * as mutations are executed with the second value, which is + * used to start mutations and is a {@link CreateMutationExecute} + * function. + */ +export type CreateMutationResult< + Data = any, + Variables extends AnyVariables = AnyVariables, +> = [ + CreateMutationState, + CreateMutationExecute, +]; + +/** Hook to create a GraphQL mutation, run by passing variables to the returned execute function. + * + * @param query - a GraphQL mutation document which `createMutation` will execute. + * @returns a {@link CreateMutationResult} tuple of a {@link CreateMutationState} result, + * and an execute function to start the mutation. + * + * @remarks + * `createMutation` allows GraphQL mutations to be defined and keeps its state + * after the mutation is started with the returned execute function. + * + * Given a GraphQL mutation document it returns state to keep track of the + * mutation state and a {@link CreateMutationExecute} function, which accepts + * variables for the mutation to be executed. + * Once called, the mutation executes and the state will be updated with + * the mutation’s result. + * + * @example + * ```ts + * import { gql, createMutation } from '@urql/solid'; + * + * const UpdateTodo = gql` + * mutation ($id: ID!, $title: String!) { + * updateTodo(id: $id, title: $title) { + * id, title + * } + * } + * `; + * + * const UpdateTodo = () => { + * const [result, executeMutation] = createMutation(UpdateTodo); + * const start = async ({ id, title }) => { + * const result = await executeMutation({ id, title }); + * }; + * // ... + * }; + * ``` + */ +export const createMutation = < + Data = any, + Variables extends AnyVariables = AnyVariables, +>( + query: DocumentInput +): CreateMutationResult => { + const client = useClient(); + const initialResult: CreateMutationState = { + operation: undefined, + fetching: false, + stale: false, + data: undefined, + error: undefined, + extensions: undefined, + }; + + const [state, setState] = + createStore>(initialResult); + + const execute = ( + variables: Variables, + context?: Partial + ) => { + setState({ ...initialResult, fetching: true }); + + const request = createRequest(query, variables); + return pipe( + client.executeMutation(request, context), + onPush(result => { + setState({ + fetching: false, + stale: result.stale, + data: result.data, + error: result.error, + extensions: result.extensions, + operation: result.operation, + }); + }), + filter(result => !result.hasNext), + take(1), + toPromise + ); + }; + + return [state, execute]; +}; diff --git a/packages/solid-urql/src/createQuery.test.tsx b/packages/solid-urql/src/createQuery.test.tsx new file mode 100644 index 0000000000..d0e7903ef2 --- /dev/null +++ b/packages/solid-urql/src/createQuery.test.tsx @@ -0,0 +1,262 @@ +// @vitest-environment jsdom + +import { expect, it, describe, vi } from 'vitest'; +import { CreateQueryState, createQuery } from './createQuery'; +import { renderHook, testEffect } from '@solidjs/testing-library'; +import { createClient } from '@urql/core'; +import { createEffect, createSignal } from 'solid-js'; +import { makeSubject } from 'wonka'; +import { OperationResult, OperationResultSource } from '@urql/core'; + +const client = createClient({ + url: '/graphql', + exchanges: [], + suspense: false, +}); + +vi.mock('./context', () => { + const useClient = () => { + return client!; + }; + + return { useClient }; +}); + +// Given that it is not possible to directly listen to all store changes it is necessary +// to access all relevant parts on which `createEffect` should listen on +const markStateDependencies = (state: CreateQueryState) => { + state.data; + state.error; + state.extensions; + state.fetching; + state.operation; + state.stale; +}; + +describe('createQuery', () => { + it('should fetch when query is resumed', () => { + const subject = + makeSubject, 'data'>>(); + const executeQuery = vi + .spyOn(client, 'executeQuery') + .mockImplementation( + () => subject.source as OperationResultSource + ); + + return testEffect(done => { + const [pause, setPause] = createSignal(true); + const [state] = createQuery<{ test: boolean }, { variable: number }>({ + query: '{ test }', + pause: pause, + }); + + createEffect((run: number = 0) => { + markStateDependencies(state); + + switch (run) { + case 0: { + expect(state.fetching).toEqual(false); + expect(executeQuery).not.toHaveBeenCalled(); + setPause(false); + break; + } + case 1: { + expect(state.fetching).toEqual(true); + expect(executeQuery).toHaveBeenCalledOnce(); + subject.next({ data: { test: true } }); + break; + } + case 2: { + expect(state.fetching).toEqual(false); + expect(state.data).toStrictEqual({ test: true }); + done(); + break; + } + } + + return run + 1; + }); + }); + }); + + it('should override pause when execute via refetch', () => { + const subject = + makeSubject, 'data'>>(); + const executeQuery = vi + .spyOn(client, 'executeQuery') + .mockImplementation( + () => subject.source as OperationResultSource + ); + + return testEffect(done => { + const [state, refetch] = createQuery< + { test: boolean }, + { variable: number } + >({ + query: '{ test }', + pause: true, + }); + + createEffect((run: number = 0) => { + markStateDependencies(state); + + switch (run) { + case 0: { + expect(state.fetching).toEqual(false); + expect(executeQuery).not.toBeCalled(); + refetch(); + break; + } + case 1: { + expect(state.fetching).toEqual(true); + expect(executeQuery).toHaveBeenCalledOnce(); + subject.next({ data: { test: true } }); + break; + } + case 2: { + expect(state.fetching).toEqual(false); + expect(state.data).toStrictEqual({ test: true }); + done(); + break; + } + } + + return run + 1; + }); + }); + }); + + it('should trigger refetch on variables change', () => { + const subject = + makeSubject, 'data'>>(); + const executeQuery = vi + .spyOn(client, 'executeQuery') + .mockImplementation( + () => subject.source as OperationResultSource + ); + + return testEffect(done => { + const [variables, setVariables] = createSignal<{ variable: number }>({ + variable: 1, + }); + + const [state] = createQuery<{ test: boolean }, { variable: number }>({ + query: '{ test }', + variables: variables, + }); + + createEffect((run: number = 0) => { + markStateDependencies(state); + + switch (run) { + case 0: { + expect(state.fetching).toEqual(true); + + subject.next({ data: { test: true } }); + + break; + } + case 1: { + expect(state.fetching).toEqual(false); + expect(state.data).toEqual({ test: true }); + setVariables({ variable: 2 }); + break; + } + case 2: { + expect(state.fetching).toEqual(true); + expect(executeQuery).toHaveBeenCalledTimes(2); + + subject.next({ data: { test: false } }); + break; + } + case 3: { + expect(state.fetching).toEqual(false); + expect(state.data).toEqual({ test: false }); + done(); + break; + } + } + + return run + 1; + }); + }); + }); + + it('should receive data', () => { + const subject = + makeSubject, 'data'>>(); + const executeQuery = vi + .spyOn(client, 'executeQuery') + .mockImplementation( + () => subject.source as OperationResultSource + ); + + return testEffect(done => { + const [state] = createQuery<{ test: boolean }, { variable: number }>({ + query: '{ test }', + }); + + createEffect((run: number = 0) => { + markStateDependencies(state); + + switch (run) { + case 0: { + expect(state.fetching).toEqual(true); + expect(state.data).toBeUndefined(); + + subject.next({ data: { test: true } }); + break; + } + + case 1: { + expect(state.fetching).toEqual(false); + expect(state.data).toStrictEqual({ test: true }); + expect(executeQuery).toHaveBeenCalledTimes(1); + done(); + break; + } + } + + return run + 1; + }); + }); + }); + + it('should unsubscribe on teardown', () => { + const subject = + makeSubject, 'data'>>(); + vi.spyOn(client, 'executeQuery').mockImplementation( + () => subject.source as OperationResultSource + ); + + const { + result: [state], + cleanup, + } = renderHook(() => + createQuery<{ test: number }, { variable: number }>({ + query: '{ test }', + }) + ); + + return testEffect(done => { + markStateDependencies(state); + + createEffect((run: number = 0) => { + switch (run) { + case 0: { + expect(state.fetching).toEqual(true); + cleanup(); + break; + } + case 1: { + expect(state.fetching).toEqual(false); + done(); + break; + } + } + + return run + 1; + }); + }); + }); +}); diff --git a/packages/solid-urql/src/createQuery.ts b/packages/solid-urql/src/createQuery.ts new file mode 100644 index 0000000000..2353462d46 --- /dev/null +++ b/packages/solid-urql/src/createQuery.ts @@ -0,0 +1,337 @@ +import { + type AnyVariables, + type OperationContext, + type DocumentInput, + type OperationResult, + type RequestPolicy, + createRequest, +} from '@urql/core'; +import { + createComputed, + createMemo, + createResource, + createSignal, + onCleanup, +} from 'solid-js'; +import { createStore, produce } from 'solid-js/store'; +import { useClient } from './context'; +import { type MaybeAccessor, asAccessor } from './utils'; +import type { Source, Subscription } from 'wonka'; +import { onEnd, pipe, subscribe } from 'wonka'; + +/** Triggers {@link createQuery} to execute a new GraphQL query operation. + * + * @remarks + * When called, {@link createQuery} will re-execute the GraphQL query operation + * it currently holds, even if {@link CreateQueryArgs.pause} is set to `true`. + * + * This is useful for executing a paused query or re-executing a query + * and get a new network result, by passing a new request policy. + * + * ```ts + * const [result, reExecuteQuery] = createQuery({ query }); + * + * const refresh = () => { + * // Re-execute the query with a network-only policy, skipping the cache + * reExecuteQuery({ requestPolicy: 'network-only' }); + * }; + * ``` + * + */ +export type CreateQueryExecute = (opts?: Partial) => void; + +/** State of the current query, your {@link createQuery} hook is executing. + * + * @remarks + * `CreateQueryState` is returned (in a tuple) by {@link createQuery} and + * gives you the updating {@link OperationResult} of GraphQL queries. + * + * Even when the query and variables passed to {@link createQuery} change, + * this state preserves the prior state and sets the `fetching` flag to + * `true`. + * This allows you to display the previous state, while implementing + * a separate loading indicator separately. + */ +export type CreateQueryState< + Data = any, + Variables extends AnyVariables = AnyVariables, +> = OperationResult & { + /** Indicates whether `createQuery` is waiting for a new result. + * + * @remarks + * When `createQuery` is passed a new query and/or variables, it will + * start executing the new query operation and `fetching` is set to + * `true` until a result arrives. + * + * Hint: This is subtly different than whether the query is actually + * fetching, and doesn’t indicate whether a query is being re-executed + * in the background. For this, see {@link CreateQueryState.stale}. + */ + fetching: boolean; +}; + +/** + * Input arguments for the {@link createQuery} hook. + */ +export type CreateQueryArgs< + Data = any, + Variables extends AnyVariables = AnyVariables, +> = { + /** The GraphQL query that `createQuery` executes. */ + query: DocumentInput; + + /** The variables for the GraphQL {@link CreateQueryArgs.query} that `createQuery` executes. */ + variables?: MaybeAccessor; + + /** Updates the {@link RequestPolicy} for the executed GraphQL query operation. + * + * @remarks + * `requestPolicy` modifies the {@link RequestPolicy} of the GraphQL query operation + * that `createQuery` executes, and indicates a caching strategy for cache exchanges. + * + * For example, when set to `'cache-and-network'`, {@link createQuery} will + * receive a cached result with `stale: true` and an API request will be + * sent in the background. + * + * @see {@link OperationContext.requestPolicy} for where this value is set. + */ + requestPolicy?: MaybeAccessor; + + /** Updates the {@link OperationContext} for the executed GraphQL query operation. + * + * @remarks + * `context` may be passed to {@link createQuery}, to update the {@link OperationContext} + * of a query operation. This may be used to update the `context` that exchanges + * will receive for a single hook. + * + * In order to re-execute query on context change pass {@link Accessor} instead + * of raw value. + */ + context?: MaybeAccessor>; + + /** Prevents {@link createQuery} from automatically executing GraphQL query operations. + * + * @remarks + * `pause` may be set to `true` to stop {@link createQuery} from executing + * automatically. The hook will stop receiving updates from the {@link Client} + * and won’t execute the query operation, until either it’s set to `false` + * or the {@link CreateQueryExecute} function is called. + */ + pause?: MaybeAccessor; +}; + +/** Result tuple returned by the {@link createQuery} hook. + * + * @remarks + * the first element is the {@link createQuery}’s result and state, + * a {@link CreateQueryState} object, + * and the second is used to imperatively re-execute the query + * via a {@link CreateQueryExecute} function. + */ +export type CreateQueryResult< + Data = any, + Variables extends AnyVariables = AnyVariables, +> = [CreateQueryState, CreateQueryExecute]; + +/** Hook to run a GraphQL query and get updated GraphQL results. + * + * @param args - a {@link CreateQueryArgs} object, to pass a `query`, `variables`, and options. + * @returns a {@link CreateQueryResult} tuple of a {@link CreateQueryState} result, and re-execute function. + * + * @remarks + * `createQuery` allows GraphQL queries to be defined and executed. + * Given {@link CreateQueryArgs.query}, it executes the GraphQL query with the + * context’s {@link Client}. + * + * The returned result updates when the `Client` has new results + * for the query, and changes when your input `args` change. + * + * Additionally, if the `suspense` option is enabled on the `Client`, + * the `createQuery` hook will suspend instead of indicating that it’s + * waiting for a result via {@link CreateQueryState.fetching}. + * + * @example + * ```tsx + * import { gql, createQuery } from '@urql/solid'; + * + * const TodosQuery = gql` + * query { todos { id, title } } + * `; + * + * const Todos = () => { + * const [result, reExecuteQuery] = createQuery({ + * query: TodosQuery, + * }); + * // ... + * }; + * ``` + */ +export const createQuery = < + Data = any, + Variables extends AnyVariables = AnyVariables, +>( + args: CreateQueryArgs +): CreateQueryResult => { + const client = useClient(); + const getContext = asAccessor(args.context); + const getPause = asAccessor(args.pause); + const getRequestPolicy = asAccessor(args.requestPolicy); + const getVariables = asAccessor(args.variables); + + const [source, setSource] = createSignal< + Source> | undefined + >(undefined, { equals: false }); + + // Combine suspense param coming from context and client with context being priority + const isSuspense = createMemo(() => { + const ctx = getContext(); + if (ctx !== undefined && ctx.suspense !== undefined) { + return ctx.suspense; + } + + return client.suspense; + }); + + const request = createRequest(args.query, getVariables() as any); + const context: Partial = { + requestPolicy: getRequestPolicy(), + ...getContext(), + }; + const operation = client.createRequestOperation('query', request, context); + const initialResult: CreateQueryState = { + operation: operation, + fetching: false, + data: undefined, + error: undefined, + extensions: undefined, + hasNext: false, + stale: false, + }; + + const [result, setResult] = + createStore>(initialResult); + + createComputed(() => { + if (getPause() === true) { + setSource(undefined); + return; + } + + const request = createRequest(args.query, getVariables() as any); + const context: Partial = { + requestPolicy: getRequestPolicy(), + ...getContext(), + }; + + setSource(() => client.executeQuery(request, context)); + }); + + createComputed(() => { + const s = source(); + if (s === undefined) { + setResult( + produce(draft => { + draft.fetching = false; + draft.stale = false; + }) + ); + + return; + } + + setResult( + produce(draft => { + draft.fetching = true; + draft.stale = false; + }) + ); + + onCleanup( + pipe( + s, + onEnd(() => { + setResult( + produce(draft => { + draft.fetching = false; + draft.stale = false; + }) + ); + }), + subscribe(res => { + setResult( + produce(draft => { + draft.data = res.data; + draft.stale = !!res.stale; + draft.fetching = false; + draft.error = res.error; + draft.operation = res.operation; + draft.extensions = res.extensions; + }) + ); + }) + ).unsubscribe + ); + }); + + const [dataResource, { refetch }] = createResource< + CreateQueryState, + Source> | undefined + >(source, source => { + let sub: Subscription | void; + if (source === undefined) { + return Promise.resolve(result); + } + + return new Promise>(resolve => { + let hasResult = false; + sub = pipe( + source, + subscribe(() => { + if (!result.fetching && !result.stale) { + if (sub) sub.unsubscribe(); + hasResult = true; + resolve(result); + } + }) + ); + if (hasResult) { + sub.unsubscribe(); + } + }); + }); + + const executeQuery: CreateQueryExecute = opts => { + const request = createRequest(args.query, getVariables() as any); + const context: Partial = { + requestPolicy: getRequestPolicy(), + ...getContext(), + ...opts, + }; + + setSource(() => client.executeQuery(request, context)); + if (isSuspense()) { + refetch(); + } + }; + + const handler = { + get( + target: CreateQueryState, + prop: keyof CreateQueryState + ): any { + if (isSuspense() && prop === 'data') { + const resource = dataResource(); + if (resource !== undefined) { + return resource.data; + } + + return undefined; + } + + return Reflect.get(target, prop); + }, + }; + + const proxy = new Proxy(result, handler); + return [proxy, executeQuery]; +}; diff --git a/packages/solid-urql/src/createSubscription.test.ts b/packages/solid-urql/src/createSubscription.test.ts new file mode 100644 index 0000000000..d79ea91f76 --- /dev/null +++ b/packages/solid-urql/src/createSubscription.test.ts @@ -0,0 +1,341 @@ +// @vitest-environment jsdom + +import { renderHook, testEffect } from '@solidjs/testing-library'; +import { + OperationResult, + OperationResultSource, + createClient, + createRequest, + gql, +} from '@urql/core'; +import { expect, it, describe, vi } from 'vitest'; +import { makeSubject } from 'wonka'; +import { + CreateSubscriptionState, + createSubscription, +} from './createSubscription'; +import { createEffect, createSignal } from 'solid-js'; + +const QUERY = gql` + subscription { + value + } +`; + +const client = createClient({ + url: '/graphql', + exchanges: [], + suspense: false, +}); + +vi.mock('./context', () => { + const useClient = () => { + return client!; + }; + + return { useClient }; +}); + +// Given that it is not possible to directly listen to all store changes it is necessary +// to access all relevant parts on which `createEffect` should listen on +const markStateDependencies = (state: CreateSubscriptionState) => { + state.data; + state.error; + state.extensions; + state.fetching; + state.operation; + state.stale; +}; + +describe('createSubscription', () => { + it('should receive data', () => { + return testEffect(done => { + const subject = + makeSubject, 'data'>>(); + const executeQuery = vi + .spyOn(client, 'executeSubscription') + .mockImplementation( + () => subject.source as OperationResultSource + ); + + const request = createRequest(QUERY, undefined); + const operation = client.createRequestOperation('subscription', request); + + const [state] = createSubscription< + { value: number }, + { value: number }, + { variable: number } + >({ + query: QUERY, + }); + + createEffect((run: number = 0) => { + markStateDependencies(state); + + switch (run) { + case 0: { + expect(state).toMatchObject({ + data: undefined, + stale: false, + operation: operation, + error: undefined, + extensions: undefined, + fetching: true, + }); + expect(executeQuery).toEqual(expect.any(Function)); + expect(executeQuery).toHaveBeenCalledOnce(); + expect(client.executeSubscription).toBeCalledWith( + { + key: expect.any(Number), + query: expect.any(Object), + variables: {}, + }, + undefined + ); + subject.next({ data: { value: 0 } }); + break; + } + case 1: { + expect(state.data).toEqual({ value: 0 }); + subject.next({ data: { value: 1 } }); + break; + } + case 2: { + expect(state.data).toEqual({ value: 1 }); + // expect(state.fetching).toEqual(true); + subject.complete(); + break; + } + case 3: { + expect(state.fetching).toEqual(false); + expect(state.data).toEqual({ value: 1 }); + done(); + } + } + + return run + 1; + }); + }); + }); + + it('should call handler', () => { + const handler = vi.fn(); + const subject = + makeSubject, 'data'>>(); + vi.spyOn(client, 'executeSubscription').mockImplementation( + () => subject.source as OperationResultSource + ); + + return testEffect(done => { + const [state] = createSubscription< + { value: number }, + { value: number }, + { variable: number } + >( + { + query: QUERY, + }, + handler + ); + + createEffect((run: number = 0) => { + markStateDependencies(state); + switch (run) { + case 0: { + expect(state.fetching).toEqual(true); + subject.next({ data: { value: 0 } }); + + break; + } + case 1: { + expect(handler).toHaveBeenCalledOnce(); + expect(handler).toBeCalledWith(undefined, { value: 0 }); + done(); + break; + } + } + + return run + 1; + }); + }); + }); + + it('should unsubscribe on teardown', () => { + const subject = + makeSubject, 'data'>>(); + vi.spyOn(client, 'executeSubscription').mockImplementation( + () => subject.source as OperationResultSource + ); + + const { + result: [state], + cleanup, + } = renderHook(() => + createSubscription<{ value: number }, { variable: number }>({ + query: QUERY, + }) + ); + + return testEffect(done => + createEffect((run: number = 0) => { + if (run === 0) { + expect(state.fetching).toEqual(true); + cleanup(); + } + + if (run === 1) { + expect(state.fetching).toEqual(false); + done(); + } + + return run + 1; + }) + ); + }); + + it('should skip executing query when paused', () => { + const subject = + makeSubject, 'data'>>(); + vi.spyOn(client, 'executeSubscription').mockImplementation( + () => subject.source as OperationResultSource + ); + + return testEffect(done => { + const [pause, setPause] = createSignal(true); + + const [state] = createSubscription< + { value: number }, + { value: number }, + { variable: number } + >({ query: QUERY, pause: pause }); + + createEffect((run: number = 0) => { + switch (run) { + case 0: { + expect(state.fetching).toBe(false); + setPause(false); + break; + } + case 1: { + expect(state.fetching).toBe(true); + expect(state.data).toBeUndefined(); + subject.next({ data: { value: 1 } }); + + break; + } + case 2: { + expect(state.data).toStrictEqual({ value: 1 }); + done(); + break; + } + } + + return run + 1; + }); + }); + }); + + it('should override pause when execute executeSubscription', () => { + const subject = + makeSubject, 'data'>>(); + const executeQuery = vi + .spyOn(client, 'executeSubscription') + .mockImplementation( + () => subject.source as OperationResultSource + ); + + return testEffect(done => { + const [state, executeSubscription] = createSubscription< + { value: number }, + { value: number }, + { variable: number } + >({ + query: QUERY, + pause: true, + }); + + createEffect((run: number = 0) => { + markStateDependencies(state); + + switch (run) { + case 0: { + expect(state.fetching).toEqual(false); + expect(executeQuery).not.toBeCalled(); + + executeSubscription(); + + break; + } + case 1: { + expect(state.fetching).toEqual(true); + expect(executeQuery).toHaveBeenCalledOnce(); + subject.next({ data: { value: 1 } }); + break; + } + case 2: { + expect(state.data).toStrictEqual({ value: 1 }); + done(); + break; + } + } + + return run + 1; + }); + }); + }); + + it('should aggregate results', () => { + const subject = + makeSubject, 'data'>>(); + vi.spyOn(client, 'executeSubscription').mockImplementation( + () => subject.source as OperationResultSource + ); + + return testEffect(done => { + const [state] = createSubscription< + { value: number }, + { merged: number }, + { variable: number } + >( + { + query: QUERY, + }, + (prev, next) => { + if (prev === undefined) { + return { + merged: 0 + next.value, + }; + } + + return { merged: prev.merged + next.value }; + } + ); + + createEffect((run: number = 0) => { + markStateDependencies(state); + switch (run) { + case 0: { + expect(state.fetching).toEqual(true); + subject.next({ data: { value: 1 } }); + + break; + } + case 1: { + expect(state.data).toEqual({ merged: 1 }); + subject.next({ data: { value: 2 } }); + + break; + } + case 2: { + expect(state.data).toEqual({ merged: 3 }); + + done(); + break; + } + } + + return run + 1; + }); + }); + }); +}); diff --git a/packages/solid-urql/src/createSubscription.ts b/packages/solid-urql/src/createSubscription.ts new file mode 100644 index 0000000000..20c7322e24 --- /dev/null +++ b/packages/solid-urql/src/createSubscription.ts @@ -0,0 +1,300 @@ +import { type MaybeAccessor, asAccessor } from './utils'; +import { + type AnyVariables, + type DocumentInput, + type Operation, + type OperationContext, + type OperationResult, + type CombinedError, + createRequest, +} from '@urql/core'; +import { useClient } from './context'; +import { createStore, produce } from 'solid-js/store'; +import { createComputed, createSignal, onCleanup } from 'solid-js'; +import { type Source, onEnd, pipe, subscribe } from 'wonka'; + +/** Triggers {@link createSubscription} to re-execute a GraphQL subscription operation. + * + * @param opts - optionally, context options that will be merged with the hook's + * {@link CreateSubscriptionArgs.context} options and the `Client`’s options. + * + * @remarks + * When called, {@link createSubscription} will restart the GraphQL subscription + * operation it currently holds. If {@link CreateSubscriptionArgs.pause} is set + * to `true`, it will start executing the subscription. + * + * ```ts + * const [result, executeSubscription] = createSubscription({ + * query, + * pause: true, + * }); + * + * const start = () => { + * executeSubscription(); + * }; + * ``` + */ +export type CreateSubscriptionExecute = ( + opts?: Partial +) => void; + +/** Input arguments for the {@link createSubscription} hook. */ +export type CreateSubscriptionArgs< + Data, + Variables extends AnyVariables = AnyVariables, +> = { + /** The GraphQL subscription document that `createSubscription` executes. */ + query: DocumentInput; + + /** The variables for the GraphQL subscription that `createSubscription` executes. */ + variables?: MaybeAccessor; + + /** Updates the {@link OperationContext} for the executed GraphQL subscription operation. + * + * @remarks + * `context` may be passed to {@link createSubscription}, to update the {@link OperationContext} + * of a subscription operation. This may be used to update the `context` that exchanges + * will receive for a single hook. + */ + context?: MaybeAccessor>; + + /** Prevents {@link createSubscription} from automatically starting GraphQL subscriptions. + * + * @remarks + * `pause` may be set to `true` to stop {@link createSubscription} from starting its subscription + * automatically. The hook will stop receiving updates from the {@link Client} + * and won’t start the subscription operation, until either it’s set to `false` + * or the {@link CreateSubscriptionExecute} function is called. + */ + pause?: MaybeAccessor; +}; + +export type CreateSubscriptionState< + Data = any, + Variables extends AnyVariables = AnyVariables, +> = { + /** Indicates whether `createSubscription`’s subscription is active. + * + * @remarks + * When `createSubscription` starts a subscription, the `fetching` flag + * is set to `true` and will remain `true` until the subscription + * completes on the API, or the {@link CreateSubscriptionArgs.pause} + * flag is set to `true`. + */ + fetching: boolean; + + /** Indicates that the subscription result is not fresh. + * + * @remarks + * This is mostly unused for subscriptions and will rarely affect you, and + * is more relevant for queries. + * + * @see {@link OperationResult.stale} for the source of this value. + */ + stale: boolean; + + /** The {@link OperationResult.data} for the executed subscription, or data returned by a handler. + * + * @remarks + * `data` will be set to the last {@link OperationResult.data} value + * received for the subscription. + * + * It will instead be set to the values that {@link SubscriptionHandler} + * returned, if a handler has been passed to {@link CreateSubscription}. + */ + data?: Data; + + /** The {@link OperationResult.error} for the executed subscription. */ + error?: CombinedError; + + /** The {@link OperationResult.extensions} for the executed mutation. */ + extensions?: Record; + + /** The {@link Operation} that the current state is for. + * + * @remarks + * This is the subscription {@link Operation} that is currently active. + * When {@link CreateSubscriptionState.fetching} is `true`, this is the + * last `Operation` that the current state was for. + */ + operation?: Operation; +}; + +/** Combines previous data with an incoming subscription result’s data. + * + * @remarks + * A `SubscriptionHandler` may be passed to {@link createSubscription} to + * aggregate subscription results into a combined {@link CreateSubscriptionState.data} + * value. + * + * This is useful when a subscription event delivers a single item, while + * you’d like to display a list of events. + * + * @example + * ```ts + * const NotificationsSubscription = gql` + * subscription { newNotification { id, text } } + * `; + * + * const combineNotifications = (notifications = [], data) => { + * return [...notifications, data.newNotification]; + * }; + * + * const [result, executeSubscription] = createSubscription( + * { query: NotificationsSubscription }, + * combineNotifications, + * ); + * ``` + */ +export type SubscriptionHandler = (prev: R | undefined, data: T) => R; + +/** Result tuple returned by the {@link createSubscription} hook. + * + * @remarks + * Similarly to a `createSignal` hook’s return value, + * the first element is the {@link createSubscription}’s state, + * a {@link CreateSubscriptionState} object, + * and the second is used to imperatively re-execute or start the subscription + * via a {@link CreateMutationExecute} function. + */ +export type CreateSubscriptionResult< + Data, + Variables extends AnyVariables = AnyVariables, +> = [CreateSubscriptionState, CreateSubscriptionExecute]; + +/** Hook to run a GraphQL subscription and get updated GraphQL results. + * + * @param args - a {@link CreateSubscriptionArgs} object, to pass a `query`, `variables`, and options. + * @param handler - optionally, a {@link SubscriptionHandler} function to combine multiple subscription results. + * @returns a {@link CreateSubscriptionResponse} tuple of a {@link CreateSubscriptionState} result, + * and an execute function. + * + * @remarks + * `createSubscription` allows GraphQL subscriptions to be defined and executed. + * Given {@link CreateSubscriptionArgs.query}, it executes the GraphQL subscription with the + * context’s {@link Client}. + * + * The returned result updates when the `Client` has new results + * for the subscription, and `data` is updated with the result’s data + * or with the `data` that a `handler` returns. + * + * @example + * ```ts + * import { gql, createSubscription } from '@urql/solid'; + * + * const NotificationsSubscription = gql` + * subscription { newNotification { id, text } } + * `; + * + * const combineNotifications = (notifications = [], data) => { + * return [...notifications, data.newNotification]; + * }; + * + * const Notifications = () => { + * const [result, executeSubscription] = createSubscription( + * { query: NotificationsSubscription }, + * combineNotifications, + * ); + * // ... + * }; + * ``` + */ +export const createSubscription = < + Data, + Result = Data, + Variables extends AnyVariables = AnyVariables, +>( + args: CreateSubscriptionArgs, + handler?: SubscriptionHandler +): CreateSubscriptionResult => { + const getContext = asAccessor(args.context); + const getPause = asAccessor(args.pause); + const getVariables = asAccessor(args.variables); + + const client = useClient(); + + const request = createRequest(args.query, getVariables() as Variables); + const operation = client.createRequestOperation( + 'subscription', + request, + getContext() + ); + const initialState: CreateSubscriptionState = { + operation, + fetching: false, + data: undefined, + error: undefined, + extensions: undefined, + stale: false, + }; + + const [source, setSource] = createSignal< + Source> | undefined + >(undefined, { equals: false }); + + const [state, setState] = + createStore>(initialState); + + createComputed(() => { + if (getPause() === true) { + setSource(undefined); + return; + } + + const context = getContext(); + const request = createRequest(args.query, getVariables() as Variables); + setSource(() => client.executeSubscription(request, context)); + }); + + createComputed(() => { + const s = source(); + if (s === undefined) { + setState('fetching', false); + + return; + } + + setState('fetching', true); + onCleanup( + pipe( + s, + onEnd(() => { + setState( + produce(draft => { + draft.fetching = false; + }) + ); + }), + subscribe(res => { + setState( + produce(draft => { + draft.data = + res.data !== undefined + ? typeof handler === 'function' + ? handler(draft.data, res.data) + : res.data + : (draft.data as any); + draft.stale = !!res.stale; + draft.fetching = true; + draft.error = res.error; + draft.operation = res.operation; + draft.extensions = res.extensions; + }) + ); + }) + ).unsubscribe + ); + }); + + const executeSubscription = (opts?: Partial) => { + const context: Partial = { + ...getContext(), + ...opts, + }; + const request = createRequest(args.query, getVariables() as Variables); + + setSource(() => client.executeSubscription(request, context)); + }; + + return [state, executeSubscription]; +}; diff --git a/packages/solid-urql/src/index.ts b/packages/solid-urql/src/index.ts new file mode 100644 index 0000000000..1cdbc30386 --- /dev/null +++ b/packages/solid-urql/src/index.ts @@ -0,0 +1,29 @@ +export * from '@urql/core'; + +export { type UseClient } from './context'; +export { useClient } from './context'; + +export { + type CreateMutationState, + type CreateMutationExecute, + type CreateMutationResult, +} from './createMutation'; +export { createMutation } from './createMutation'; + +export { + type CreateQueryArgs, + type CreateQueryState, + type CreateQueryExecute, + type CreateQueryResult, +} from './createQuery'; +export { createQuery } from './createQuery'; + +export { + type CreateSubscriptionArgs, + type CreateSubscriptionState, + type CreateSubscriptionExecute, + type CreateSubscriptionResult, + type SubscriptionHandler, +} from './createSubscription'; + +export { createSubscription } from './createSubscription'; diff --git a/packages/solid-urql/src/suspense.test.tsx b/packages/solid-urql/src/suspense.test.tsx new file mode 100644 index 0000000000..f07d5a37de --- /dev/null +++ b/packages/solid-urql/src/suspense.test.tsx @@ -0,0 +1,135 @@ +/** @jsxImportSource solid-js */ +// @vitest-environment jsdom + +import { describe, it, vi } from 'vitest'; +import { + OperationResult, + OperationResultSource, + createClient, +} from '@urql/core'; +import { createQuery } from './createQuery'; +import { fireEvent, render, screen, waitFor } from '@solidjs/testing-library'; +import { Provider } from './context'; +import { Suspense } from 'solid-js'; +import { makeSubject } from 'wonka'; + +describe('createQuery suspense', () => { + it('should not suspend', async () => { + const client = createClient({ + url: '/graphql', + exchanges: [], + suspense: false, + }); + + const subject = + makeSubject, 'data'>>(); + vi.spyOn(client, 'executeQuery').mockImplementation( + () => subject.source as OperationResultSource + ); + + const Page = () => { + const [state, refetch] = createQuery< + { test: boolean }, + { variable: number } + >({ + query: '{ test }', + }); + + return ( +
+
+ ); + }; + + render(() => ( + + + + + + )); + + subject.next({ data: { test: true } }); + await waitFor(() => screen.getByText('data: true')); + + fireEvent.click(screen.getByTestId('refetch')); + + subject.next({ data: { test: false } }); + await waitFor(() => screen.getByText('data: false')); + }); + + it('should suspend', async () => { + const client = createClient({ + url: '/graphql', + exchanges: [], + suspense: true, + }); + + const subject = + makeSubject, 'data'>>(); + vi.spyOn(client, 'executeQuery').mockImplementation( + () => subject.source as OperationResultSource + ); + + const Page = () => { + const [state] = createQuery<{ test: boolean }, { variable: number }>({ + query: '{ test }', + }); + + return
data: {String(state.data?.test)}
; + }; + + render(() => ( + + + + + + )); + + await waitFor(() => screen.getByText('loading')); + + subject.next({ data: { test: true } }); + await waitFor(() => screen.getByText('data: true')); + }); + + it('context suspend should override client suspend', async () => { + const client = createClient({ + url: '/graphql', + exchanges: [], + suspense: false, + }); + + const subject = + makeSubject, 'data'>>(); + vi.spyOn(client, 'executeQuery').mockImplementation( + () => subject.source as OperationResultSource + ); + + const Page = () => { + const [state] = createQuery<{ test: boolean }, { variable: number }>({ + query: '{ test }', + context: { + suspense: true, + }, + }); + + return
data: {String(state.data?.test)}
; + }; + + render(() => ( + + + + + + )); + + await waitFor(() => screen.getByText('loading')); + + subject.next({ data: { test: true } }); + await waitFor(() => screen.getByText('data: true')); + }); +}); diff --git a/packages/solid-urql/src/utils.ts b/packages/solid-urql/src/utils.ts new file mode 100644 index 0000000000..8ffc58f590 --- /dev/null +++ b/packages/solid-urql/src/utils.ts @@ -0,0 +1,11 @@ +import type { Accessor } from 'solid-js'; + +export type MaybeAccessor = T | Accessor; + +export type MaybeAccessorValue> = + T extends () => any ? ReturnType : T; + +export const asAccessor = >( + v: A +): Accessor> => + typeof v === 'function' ? (v as any) : () => v; diff --git a/packages/solid-urql/tsconfig.json b/packages/solid-urql/tsconfig.json new file mode 100644 index 0000000000..8c25acf9b4 --- /dev/null +++ b/packages/solid-urql/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src"], + "compilerOptions": { + "jsx": "preserve", + "jsxImportSource": "solid-js" + } +} diff --git a/packages/solid-urql/vitest.config.ts b/packages/solid-urql/vitest.config.ts new file mode 100644 index 0000000000..55b1b9e774 --- /dev/null +++ b/packages/solid-urql/vitest.config.ts @@ -0,0 +1,7 @@ +import { mergeConfig } from 'vitest/config'; +import solidPlugin from 'vite-plugin-solid'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, { + plugins: [solidPlugin({ hot: false })], +}); diff --git a/packages/storage-rn/package.json b/packages/storage-rn/package.json index 693d790c26..1b2c506361 100644 --- a/packages/storage-rn/package.json +++ b/packages/storage-rn/package.json @@ -49,15 +49,16 @@ "prepublishOnly": "run-s clean build" }, "peerDependencies": { - "@urql/exchange-graphcache": ">=5.0.0", "@react-native-async-storage/async-storage": "^1.15.5", - "@react-native-community/netinfo": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^11.0.0" + "@react-native-community/netinfo": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^11.0.0", + "@urql/exchange-graphcache": ">=5.0.0" }, "devDependencies": { + "@react-native-async-storage/async-storage": "^1.21.0", + "@react-native-community/netinfo": "^11.2.1", "@urql/core": "workspace:*", "@urql/exchange-graphcache": "workspace:*", - "@react-native-async-storage/async-storage": "^1.21.0", - "@react-native-community/netinfo": "^11.2.1" + "vitest": "^0.30.1" }, "publishConfig": { "access": "public", diff --git a/packages/storage-rn/vitest.config.ts b/packages/storage-rn/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/packages/storage-rn/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/packages/svelte-urql/package.json b/packages/svelte-urql/package.json index bdb5b4e840..d861f9658d 100644 --- a/packages/svelte-urql/package.json +++ b/packages/svelte-urql/package.json @@ -40,7 +40,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -59,7 +59,8 @@ "devDependencies": { "@urql/core": "workspace:*", "graphql": "^16.0.0", - "svelte": "^3.20.0" + "svelte": "^3.20.0", + "vitest": "^0.30.1" }, "publishConfig": { "access": "public", diff --git a/packages/svelte-urql/vitest.config.ts b/packages/svelte-urql/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/packages/svelte-urql/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/packages/vue-urql/package.json b/packages/vue-urql/package.json index becee05825..2e01f841b5 100644 --- a/packages/vue-urql/package.json +++ b/packages/vue-urql/package.json @@ -40,7 +40,7 @@ "dist/" ], "scripts": { - "test": "vitest --config ../../vitest.config.ts", + "test": "vitest", "clean": "rimraf dist", "check": "tsc --noEmit", "lint": "eslint --ext=js,jsx,ts,tsx .", @@ -52,6 +52,7 @@ "@urql/core": "workspace:*", "@vue/test-utils": "^2.3.0", "graphql": "^16.0.0", + "vitest": "^0.30.1", "vue": "^3.2.47" }, "peerDependencies": { diff --git a/packages/vue-urql/vitest.config.ts b/packages/vue-urql/vitest.config.ts new file mode 100644 index 0000000000..6561524839 --- /dev/null +++ b/packages/vue-urql/vitest.config.ts @@ -0,0 +1,4 @@ +import { mergeConfig } from 'vitest/config'; +import baseConfig from '../../vitest.config'; + +export default mergeConfig(baseConfig, {}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ebb1cbe7ae..6f286c779f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -194,6 +194,9 @@ importers: graphql: specifier: ^16.6.0 version: 16.6.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) exchanges/context: dependencies: @@ -207,6 +210,9 @@ importers: graphql: specifier: ^16.6.0 version: 16.6.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) exchanges/execute: dependencies: @@ -220,6 +226,9 @@ importers: graphql: specifier: ^16.6.0 version: 16.6.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) exchanges/graphcache: dependencies: @@ -257,6 +266,9 @@ importers: urql: specifier: workspace:* version: link:../../packages/react-urql + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) exchanges/persisted: dependencies: @@ -270,6 +282,9 @@ importers: graphql: specifier: ^16.6.0 version: 16.6.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) exchanges/populate: dependencies: @@ -283,6 +298,9 @@ importers: graphql: specifier: ^16.6.0 version: 16.6.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) exchanges/refocus: dependencies: @@ -299,6 +317,9 @@ importers: graphql: specifier: ^16.6.0 version: 16.6.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) exchanges/request-policy: dependencies: @@ -312,6 +333,9 @@ importers: graphql: specifier: ^16.6.0 version: 16.6.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) exchanges/retry: dependencies: @@ -325,6 +349,9 @@ importers: graphql: specifier: ^16.6.0 version: 16.6.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) packages/core: dependencies: @@ -334,6 +361,10 @@ importers: wonka: specifier: ^6.3.2 version: 6.3.2 + devDependencies: + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) packages/introspection: devDependencies: @@ -386,6 +417,9 @@ importers: preact: specifier: ^10.13.0 version: 10.13.1 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) packages/react-urql: dependencies: @@ -438,6 +472,9 @@ importers: vite: specifier: ^3.2.4 version: 3.2.5(@types/node@18.16.3)(terser@5.17.1) + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) packages/site: dependencies: @@ -542,6 +579,37 @@ importers: specifier: '>=4.4.6' version: 4.46.0 + packages/solid-urql: + dependencies: + '@urql/core': + specifier: ^4.0.0 + version: 4.3.0(graphql@16.6.0) + solid-js: + specifier: ^1.7.7 + version: 1.8.17 + wonka: + specifier: ^6.3.2 + version: 6.3.2 + devDependencies: + '@solidjs/testing-library': + specifier: ^0.8.2 + version: 0.8.8(solid-js@1.8.17) + graphql: + specifier: ^16.6.0 + version: 16.6.0 + jsdom: + specifier: ^22.1.0 + version: 22.1.0 + vite-plugin-solid: + specifier: ^2.7.0 + version: 2.10.2(solid-js@1.8.17)(vite@3.2.5) + vite-tsconfig-paths: + specifier: ^4.2.0 + version: 4.2.0(typescript@5.1.6)(vite@3.2.5) + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@22.1.0)(terser@5.17.1) + packages/storage-rn: devDependencies: '@react-native-async-storage/async-storage': @@ -556,6 +624,9 @@ importers: '@urql/exchange-graphcache': specifier: workspace:* version: link:../../exchanges/graphcache + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) packages/svelte-urql: dependencies: @@ -572,6 +643,9 @@ importers: svelte: specifier: ^3.20.0 version: 3.37.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) packages/vue-urql: dependencies: @@ -588,6 +662,9 @@ importers: graphql: specifier: ^16.6.0 version: 16.6.0 + vitest: + specifier: ^0.30.1 + version: 0.30.1(jsdom@21.1.1)(terser@5.17.1) vue: specifier: ^3.2.47 version: 3.2.47 @@ -597,7 +674,7 @@ packages: /@0no-co/graphql.web@1.0.5(graphql@16.6.0): resolution: {integrity: sha512-/ODdeNNFksS9hUvpjWFldMEpq0OqCFEIV3NVM0eU8HLUYU0Szf+2iKvr63kkbGchQwk2/1IxPF1PfoCabVkgLw==} peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + graphql: ^16.6.0 peerDependenciesMeta: graphql: optional: true @@ -681,10 +758,22 @@ packages: '@babel/highlight': 7.24.2 picocolors: 1.0.0 + /@babel/code-frame@7.24.7: + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.0 + /@babel/compat-data@7.21.5: resolution: {integrity: sha512-M+XAiQ7GzQ3FDPf0KOLkugzptnIypt0X0ma0wmlTKPR3IchgNFdx2JXxZdvd18JY5s7QkaFD/qyX0dsMpog/Ug==} engines: {node: '>=6.9.0'} + /@babel/compat-data@7.24.7: + resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/core@7.12.9: resolution: {integrity: sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==} engines: {node: '>=6.9.0'} @@ -730,6 +819,29 @@ packages: transitivePeerDependencies: - supports-color + /@babel/core@7.24.7: + resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helpers': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + convert-source-map: 2.0.0 + debug: 4.3.4(supports-color@5.5.0) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/generator@7.21.5: resolution: {integrity: sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==} engines: {node: '>=6.9.0'} @@ -739,6 +851,16 @@ packages: '@jridgewell/trace-mapping': 0.3.17 jsesc: 2.5.2 + /@babel/generator@7.24.7: + resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + dev: true + /@babel/helper-annotate-as-pure@7.18.6: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} engines: {node: '>=6.9.0'} @@ -764,6 +886,17 @@ packages: lru-cache: 5.1.1 semver: 6.3.1 + /@babel/helper-compilation-targets@7.24.7: + resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + browserslist: 4.23.0 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + /@babel/helper-create-class-features-plugin@7.21.5(@babel/core@7.21.5): resolution: {integrity: sha512-yNSEck9SuDvPTEUYm4BSXl6ZVC7yO5ZLEMAhG3v3zi7RDxyL/nQDemWWZmw4L0stPWwhpnznRRyJHPRcbXR2jw==} engines: {node: '>=6.9.0'} @@ -813,6 +946,13 @@ packages: resolution: {integrity: sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==} engines: {node: '>=6.9.0'} + /@babel/helper-environment-visitor@7.24.7: + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + /@babel/helper-explode-assignable-expression@7.13.0: resolution: {integrity: sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==} dependencies: @@ -825,24 +965,56 @@ packages: '@babel/template': 7.20.7 '@babel/types': 7.22.4 + /@babel/helper-function-name@7.24.7: + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + dev: true + /@babel/helper-hoist-variables@7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.4 + /@babel/helper-hoist-variables@7.24.7: + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + /@babel/helper-member-expression-to-functions@7.21.5: resolution: {integrity: sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.4 + /@babel/helper-module-imports@7.18.6: + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.0 + dev: true + /@babel/helper-module-imports@7.21.4: resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.4 + /@babel/helper-module-imports@7.24.7: + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-module-transforms@7.21.5: resolution: {integrity: sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==} engines: {node: '>=6.9.0'} @@ -858,6 +1030,22 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7): + resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-optimise-call-expression@7.18.6: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} @@ -899,6 +1087,16 @@ packages: dependencies: '@babel/types': 7.22.4 + /@babel/helper-simple-access@7.24.7: + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-skip-transparent-expression-wrappers@7.20.0: resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} engines: {node: '>=6.9.0'} @@ -911,6 +1109,13 @@ packages: dependencies: '@babel/types': 7.22.4 + /@babel/helper-split-export-declaration@7.24.7: + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.7 + dev: true + /@babel/helper-string-parser@7.21.5: resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} engines: {node: '>=6.9.0'} @@ -920,7 +1125,11 @@ packages: engines: {node: '>=6.9.0'} requiresBuild: true dev: true - optional: true + + /@babel/helper-string-parser@7.24.7: + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + engines: {node: '>=6.9.0'} + dev: true /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} @@ -930,10 +1139,19 @@ packages: resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-identifier@7.24.7: + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + /@babel/helper-validator-option@7.21.0: resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-option@7.24.7: + resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-wrap-function@7.13.0: resolution: {integrity: sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==} dependencies: @@ -954,6 +1172,14 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helpers@7.24.7: + resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + dev: true + /@babel/highlight@7.22.5: resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} engines: {node: '>=6.9.0'} @@ -971,6 +1197,15 @@ packages: js-tokens: 4.0.0 picocolors: 1.0.0 + /@babel/highlight@7.24.7: + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + /@babel/parser@7.22.4: resolution: {integrity: sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==} engines: {node: '>=6.0.0'} @@ -986,7 +1221,14 @@ packages: dependencies: '@babel/types': 7.24.0 dev: true - optional: true + + /@babel/parser@7.24.7: + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.7 + dev: true /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.13.12(@babel/core@7.21.5): resolution: {integrity: sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==} @@ -1211,6 +1453,16 @@ packages: '@babel/core': 7.21.5 '@babel/helper-plugin-utils': 7.21.5 + /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.24.7): + resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.21.5): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: @@ -1802,6 +2054,15 @@ packages: '@babel/parser': 7.22.4 '@babel/types': 7.22.4 + /@babel/template@7.24.7: + resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + dev: true + /@babel/traverse@7.21.5(supports-color@5.5.0): resolution: {integrity: sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==} engines: {node: '>=6.9.0'} @@ -1819,6 +2080,24 @@ packages: transitivePeerDependencies: - supports-color + /@babel/traverse@7.24.7: + resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + debug: 4.3.4(supports-color@5.5.0) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/types@7.22.4: resolution: {integrity: sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==} engines: {node: '>=6.9.0'} @@ -1836,7 +2115,15 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 dev: true - optional: true + + /@babel/types@7.24.7: + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + dev: true /@changesets/apply-release-plan@6.1.4: resolution: {integrity: sha512-FMpKF1fRlJyCZVYHr3CbinpZZ+6MwvOtWUuO8uo+svcATEoc1zRDcj23pAurJ2TZ/uVz1wFHH6K3NlACy0PLew==} @@ -2041,10 +2328,10 @@ packages: /@cypress/react@7.0.2(@types/react@17.0.52)(cypress@12.8.1)(react-dom@17.0.2)(react@17.0.2): resolution: {integrity: sha512-TTV7XNMDOO9mZUFWiGbd44Od/jqMVX/QbHYKQmK1XT3nIVFs0EvKJuHJmwN7wxLOR/+6twtyX6vTD8z8XBTliQ==} peerDependencies: - '@types/react': ^16.9.16 || ^17.0.0 + '@types/react': ^17.0.39 cypress: '*' - react: ^=16.x || ^=17.x || 17 - react-dom: ^=16.x || ^=17.x || 17 + react: ^17.0.2 || 17 + react-dom: ^17.0.2 || 17 peerDependenciesMeta: '@types/react': optional: true @@ -2221,6 +2508,15 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.17 + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + dev: true + /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} @@ -2229,6 +2525,11 @@ packages: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + dev: true + /@jridgewell/source-map@0.3.2: resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} dependencies: @@ -2248,6 +2549,13 @@ packages: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + /@manypkg/find-root@1.1.0: resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} dependencies: @@ -2296,7 +2604,7 @@ packages: /@mdx-js/react@1.6.22(react@17.0.2): resolution: {integrity: sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==} peerDependencies: - react: ^16.13.1 || ^17.0.0 || 17 + react: ^17.0.2 || 17 dependencies: react: 17.0.2 dev: false @@ -2733,8 +3041,8 @@ packages: /@reach/router@1.3.4(react-dom@17.0.2)(react@17.0.2): resolution: {integrity: sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA==} peerDependencies: - react: 15.x || 16.x || 16.4.0-alpha.0911da3 || 17 - react-dom: 15.x || 16.x || 16.4.0-alpha.0911da3 || 17 + react: ^17.0.2 || 17 + react-dom: ^17.0.2 || 17 dependencies: create-react-context: 0.3.0(prop-types@15.8.1)(react@17.0.2) invariant: 2.2.4 @@ -2871,12 +3179,40 @@ packages: resolution: {integrity: sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==} engines: {node: '>=4'} + /@solidjs/testing-library@0.8.8(solid-js@1.8.17): + resolution: {integrity: sha512-47J9Aw+iG45Fs5Kxu/IJmkaaucpF7qhDazW+iXeNssAYI0FH+4MeM/SfYRhPbIMH/hBpMh/XjbK1Wpyu9PcSwg==} + engines: {node: '>= 14'} + peerDependencies: + '@solidjs/router': '>=0.9.0' + solid-js: '>=1.0.0' + peerDependenciesMeta: + '@solidjs/router': + optional: true + dependencies: + '@testing-library/dom': 10.1.0 + solid-js: 1.8.17 + dev: true + /@swc/helpers@0.4.11: resolution: {integrity: sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==} dependencies: tslib: 2.6.1 dev: true + /@testing-library/dom@10.1.0: + resolution: {integrity: sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==} + engines: {node: '>=18'} + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/runtime': 7.22.5 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + dev: true + /@testing-library/dom@7.30.4: resolution: {integrity: sha512-GObDVMaI4ARrZEXaRy4moolNAxWPKvEYNV/fa6Uc2eAzR/t4otS6A7EhrntPBIQLeehL9DbVhscvvv7gd6hWqA==} engines: {node: '>=10'} @@ -2904,8 +3240,8 @@ packages: /@testing-library/react-hooks@5.1.2(react-dom@17.0.2)(react-test-renderer@17.0.2)(react@17.0.2): resolution: {integrity: sha512-jwhtDYZ5gQUIX8cmVCVdtwNvuF5EiCOWjokRlTV+o/V0GdtRZDykUllL1OXq5PS4+J33wGLNQeeWzEHcWrH7tg==} peerDependencies: - react: '>=16.9.0 || 17' - react-dom: '>=16.9.0 || 17' + react: ^17.0.2 || 17 + react-dom: ^17.0.2 || 17 react-test-renderer: '>=16.9.0' peerDependenciesMeta: react-dom: @@ -2928,8 +3264,8 @@ packages: resolution: {integrity: sha512-TXMCg0jT8xmuU8BkKMtp8l7Z50Ykew5WNX8UoIKTaLFwKkP2+1YDhOLA2Ga3wY4x29jyntk7EWfum0kjlYiSjQ==} engines: {node: '>=10'} peerDependencies: - react: '*' - react-dom: '*' + react: ^17.0.2 || 17 + react-dom: ^17.0.2 || 17 dependencies: '@babel/runtime': 7.22.5 '@testing-library/dom': 7.30.4 @@ -2953,10 +3289,47 @@ packages: resolution: {integrity: sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==} dev: true + /@types/aria-query@5.0.4: + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + dev: true + + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + dependencies: + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + dev: true + + /@types/babel__generator@7.6.8: + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + dependencies: + '@babel/types': 7.24.0 + dev: true + + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + dependencies: + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + dev: true + + /@types/babel__traverse@7.20.6: + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + dependencies: + '@babel/types': 7.24.0 + dev: true + /@types/chai-subset@1.3.3: resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} dependencies: - '@types/chai': 4.3.4 + '@types/chai': 4.3.16 + dev: true + + /@types/chai@4.3.16: + resolution: {integrity: sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==} dev: true /@types/chai@4.3.4: @@ -3246,6 +3619,15 @@ packages: eslint-visitor-keys: 3.4.2 dev: true + /@urql/core@4.3.0(graphql@16.6.0): + resolution: {integrity: sha512-wT+FeL8DG4x5o6RfHEnONNFVDM3616ouzATMYUClB6CB+iIu2mwfBKd7xSUxYOZmwtxna5/hDRQdMl3nbQZlnw==} + dependencies: + '@0no-co/graphql.web': 1.0.5(graphql@16.6.0) + wonka: 6.3.2 + transitivePeerDependencies: + - graphql + dev: false + /@vitest/expect@0.30.1: resolution: {integrity: sha512-c3kbEtN8XXJSeN81iDGq29bUzSjQhjES2WR3aColsS4lPGbivwLtas4DNUe0jD9gg/FYGIteqOenfU95EFituw==} dependencies: @@ -3274,7 +3656,7 @@ packages: /@vitest/spy@0.30.1: resolution: {integrity: sha512-YfJeIf37GvTZe04ZKxzJfnNNuNSmTEGnla2OdL60C8od16f3zOfv9q9K0nNii0NfjDJRt/CVN/POuY5/zTS+BA==} dependencies: - tinyspy: 2.1.0 + tinyspy: 2.2.1 dev: true /@vitest/utils@0.30.1: @@ -3546,6 +3928,7 @@ packages: /abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead dev: true /abbrev@1.1.1: @@ -3610,6 +3993,12 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + /after@0.8.2: resolution: {integrity: sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==} @@ -3815,6 +4204,12 @@ packages: '@babel/runtime-corejs3': 7.13.17 dev: true + /aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + dependencies: + dequal: 2.0.3 + dev: true + /arr-diff@4.0.0: resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} engines: {node: '>=0.10.0'} @@ -4058,6 +4453,19 @@ packages: dependencies: '@babel/helper-plugin-utils': 7.10.4 + /babel-plugin-jsx-dom-expressions@0.37.21(@babel/core@7.24.7): + resolution: {integrity: sha512-WbQo1NQ241oki8bYasVzkMXOTSIri5GO/K47rYJb2ZBh8GaPUEWiWbMV3KwXz+96eU2i54N6ThzjQG/f5n8Azw==} + peerDependencies: + '@babel/core': ^7.20.12 + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-module-imports': 7.18.6 + '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.24.7) + '@babel/types': 7.24.0 + html-entities: 2.3.3 + validate-html-nesting: 1.2.2 + dev: true + /babel-plugin-macros@2.8.0: resolution: {integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==} dependencies: @@ -4101,7 +4509,7 @@ packages: /babel-plugin-styled-components@1.12.0(styled-components@5.2.3): resolution: {integrity: sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==} peerDependencies: - styled-components: '>= 2 || 5' + styled-components: ^5.2.3 || 5 dependencies: '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-module-imports': 7.21.4 @@ -4132,6 +4540,15 @@ packages: '@babel/helper-module-imports': 7.21.4 webpack: 4.46.0 + /babel-preset-solid@1.8.17(@babel/core@7.24.7): + resolution: {integrity: sha512-s/FfTZOeds0hYxYqce90Jb+0ycN2lrzC7VP1k1JIn3wBqcaexDKdYi6xjB+hMNkL+Q6HobKbwsriqPloasR9LA==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.7 + babel-plugin-jsx-dom-expressions: 0.37.21(@babel/core@7.24.7) + dev: true + /babel-runtime@6.26.0: resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} dependencies: @@ -4433,6 +4850,17 @@ packages: node-releases: 2.0.10 update-browserslist-db: 1.0.10(browserslist@4.21.5) + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001629 + electron-to-chromium: 1.4.795 + node-releases: 2.0.14 + update-browserslist-db: 1.0.16(browserslist@4.23.0) + dev: true + /buffer-alloc-unsafe@1.1.0: resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} @@ -4674,6 +5102,10 @@ packages: /caniuse-lite@1.0.30001466: resolution: {integrity: sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w==} + /caniuse-lite@1.0.30001629: + resolution: {integrity: sha512-c3dl911slnQhmxUIT4HhYzT7wnBK/XYpGnYLOj4nJBaRiw52Ibe7YxlDaAeRECvA786zCuExhxIUJ2K7nHMrBw==} + dev: true + /case-sensitive-paths-webpack-plugin@2.4.0: resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} engines: {node: '>=4'} @@ -5172,6 +5604,10 @@ packages: well-known-symbols: 2.0.0 dev: true + /confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + dev: true + /config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} dependencies: @@ -5209,6 +5645,10 @@ packages: /convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} @@ -5320,7 +5760,7 @@ packages: resolution: {integrity: sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==} peerDependencies: prop-types: ^15.0.0 - react: ^0.14.0 || ^15.0.0 || ^16.0.0 || 17 + react: ^17.0.2 || 17 dependencies: gud: 1.0.0 prop-types: 15.8.1 @@ -5544,6 +5984,9 @@ packages: resolution: {integrity: sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==} dev: true + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + /csv-generate@3.4.3: resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==} dev: true @@ -5952,6 +6395,11 @@ packages: resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} dev: false + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + /des.js@1.0.1: resolution: {integrity: sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==} dependencies: @@ -6016,6 +6464,10 @@ packages: esutils: 2.0.3 dev: true + /dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dev: true + /dom-accessibility-api@0.5.4: resolution: {integrity: sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==} dev: true @@ -6166,6 +6618,10 @@ packages: /electron-to-chromium@1.4.332: resolution: {integrity: sha512-c1Vbv5tuUlBFp0mb3mCIjw+REEsgthRgNE8BlbEDKmvzb8rxjcVki6OkQP83vLN34s0XCxpSkq7AZNep1a6xhw==} + /electron-to-chromium@1.4.795: + resolution: {integrity: sha512-hHo4lK/8wb4NUa+NJYSFyJ0xedNHiR6ylilDtb8NUW9d4dmBFmGiecYEKCEbti1wTNzbKXLfl4hPWEkAFbHYlw==} + dev: true + /elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} dependencies: @@ -6593,6 +7049,11 @@ packages: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + dev: true + /escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} @@ -7373,7 +7834,7 @@ packages: resolution: {integrity: sha512-jvHSQMXujUtncyT3ObkoQgwOzkxdnnAs7XYgJDGSqhGqPF+LZ0y4rS5b6XzaN2BR3hG2e7isVtCNOmb7gxNuYw==} engines: {node: '>= 0.12.0', npm: '>= 2.0.0'} peerDependencies: - styled-components: '>= 4.0.0 || 5' + styled-components: ^5.2.3 || 5 dependencies: styled-components: 5.2.3(react-dom@17.0.2)(react-is@17.0.2)(react@17.0.2) dev: false @@ -8042,6 +8503,10 @@ packages: /html-entities@1.4.0: resolution: {integrity: sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==} + /html-entities@2.3.3: + resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} + dev: true + /html-minifier@3.5.21: resolution: {integrity: sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==} engines: {node: '>=4'} @@ -8829,6 +9294,11 @@ packages: dependencies: call-bind: 1.0.2 + /is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + dev: true + /is-whitespace-character@1.0.4: resolution: {integrity: sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==} @@ -8965,6 +9435,44 @@ packages: - utf-8-validate dev: true + /jsdom@22.1.0: + resolution: {integrity: sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==} + engines: {node: '>=16'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + dependencies: + abab: 2.0.6 + cssstyle: 3.0.0 + data-urls: 4.0.0 + decimal.js: 10.4.3 + domexception: 4.0.0 + form-data: 4.0.0 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.10 + parse5: 7.1.2 + rrweb-cssom: 0.6.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 4.1.2 + w3c-xmlserializer: 4.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 12.0.1 + ws: 8.13.0 + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + /jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true @@ -9029,10 +9537,6 @@ packages: engines: {node: '>=6'} hasBin: true - /jsonc-parser@3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true - /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: @@ -9417,6 +9921,11 @@ packages: hasBin: true dev: true + /lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + dev: true + /magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} dependencies: @@ -9639,6 +10148,13 @@ packages: yargs-parser: 18.1.3 dev: true + /merge-anything@5.1.7: + resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} + engines: {node: '>=12.13'} + dependencies: + is-what: 4.1.16 + dev: true + /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} @@ -9760,7 +10276,7 @@ packages: deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. peerDependencies: prop-types: ^15.0.0 - react: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || 17 + react: ^17.0.2 || 17 dependencies: '@babel/runtime': 7.22.5 prop-types: 15.8.1 @@ -9940,13 +10456,13 @@ packages: hasBin: true dev: true - /mlly@1.2.0: - resolution: {integrity: sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==} + /mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} dependencies: - acorn: 8.10.0 - pathe: 1.1.0 - pkg-types: 1.0.2 - ufo: 1.1.1 + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.1.1 + ufo: 1.5.3 dev: true /moniker@0.1.2: @@ -10055,8 +10571,8 @@ packages: peerDependencies: fibers: '>= 3.1.0' node-sass: ^6.0.0 || ^7.0.0 - react: ^18.0.0-0 || 17 - react-dom: ^18.0.0-0 || 17 + react: ^17.0.2 || 17 + react-dom: ^17.0.2 || 17 sass: ^1.3.0 peerDependenciesMeta: fibers: @@ -10187,6 +10703,10 @@ packages: /node-releases@2.0.10: resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: true + /node-stream-zip@1.15.0: resolution: {integrity: sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==} engines: {node: '>=0.12.0'} @@ -10405,6 +10925,10 @@ packages: /num2fraction@1.2.2: resolution: {integrity: sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==} + /nwsapi@2.2.10: + resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==} + dev: true + /nwsapi@2.2.2: resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==} dev: true @@ -10826,7 +11350,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -10940,6 +11464,10 @@ packages: resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==} dev: true + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: true + /pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true @@ -10970,6 +11498,9 @@ packages: /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + /picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -11031,12 +11562,12 @@ packages: find-up: 5.0.0 dev: true - /pkg-types@1.0.2: - resolution: {integrity: sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ==} + /pkg-types@1.1.1: + resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} dependencies: - jsonc-parser: 3.2.0 - mlly: 1.2.0 - pathe: 1.1.0 + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 dev: true /please-upgrade-node@3.2.0: @@ -11359,7 +11890,7 @@ packages: engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.4 - picocolors: 1.0.0 + picocolors: 1.0.1 source-map-js: 1.0.2 dev: true @@ -11368,7 +11899,7 @@ packages: engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.4 - picocolors: 1.0.0 + picocolors: 1.0.1 source-map-js: 1.0.2 dev: true @@ -11455,7 +11986,7 @@ packages: /prism-react-renderer@1.2.0(react@17.0.2): resolution: {integrity: sha512-GHqzxLYImx1iKN1jJURcuRoA/0ygCcNhfGw1IT8nPIMzarmKQ3Nc+JcG0gi8JXQzuh0C5ShE4npMIoqNin40hg==} peerDependencies: - react: '>=0.14.9 || 17' + react: ^17.0.2 || 17 dependencies: react: 17.0.2 dev: false @@ -11705,7 +12236,7 @@ packages: /react-dom@17.0.2(react@17.0.2): resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} peerDependencies: - react: 17.0.2 || 17 + react: ^17.0.2 || 17 dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 @@ -11716,7 +12247,7 @@ packages: resolution: {integrity: sha512-W3xCd9zXnanqrTUeViceufD3mIW8Ut29BUD+S2f0eO2XCOU8b6UrJfY46RDGe5lxCJzfe4j0yvIfh0RbTZhKJw==} engines: {node: '>=10', npm: '>=6'} peerDependencies: - react: '>=16.13.1 || 17' + react: ^17.0.2 || 17 dependencies: '@babel/runtime': 7.22.5 react: 17.0.2 @@ -11728,7 +12259,7 @@ packages: /react-from-dom@0.3.1(react@17.0.2): resolution: {integrity: sha512-PeNBa8iuzoD7qHA9O7YpGnXFvC+XFFwStmFh2/r2zJAvEIaRg6EwOj+EPcDIFwyYBhqPIItxIx/dGdeWiFivjQ==} peerDependencies: - react: ^15.0.0 || ^16.0.0 || 17 + react: ^17.0.2 || 17 dependencies: react: 17.0.2 dev: false @@ -11737,7 +12268,7 @@ packages: resolution: {integrity: sha512-o8RScHj6Lb8cwy3GMrVH6NJvL+y0zpJvKtc0+wmH7Bt23rszJmnqEQxRbyrqUzk9DTJIHoP42bfO5rswC9SWBQ==} peerDependencies: prop-types: ^15.6.0 - react: ^15.6.2 || ^16.0 || ^17 || 17 + react: ^17.0.2 || 17 dependencies: prop-types: 15.7.2 react: 17.0.2 @@ -11750,7 +12281,7 @@ packages: /react-helmet@5.2.1(react@17.0.2): resolution: {integrity: sha512-CnwD822LU8NDBnjCpZ4ySh8L6HYyngViTZLfBBb3NjtrpN8m49clH8hidHouq20I51Y6TpCTISCBbqiY5GamwA==} peerDependencies: - react: '>=15.0.0 || 17' + react: ^17.0.2 || 17 dependencies: object-assign: 4.1.1 prop-types: 15.8.1 @@ -11762,9 +12293,9 @@ packages: resolution: {integrity: sha512-JrLlvUPqh6wIkrK2hZDfOyq/Uh/WeVEr8nc7hkn2/3Ul0sx1Kr5y4kOGNacNRoj7RhwLNcQ3Udf1KJXrqc0ZtA==} engines: {node: '>= 6'} peerDependencies: - '@types/react': '^15.0.0 || ^16.0.0 || ^17.0.0 ' - react: ^15.0.0 || ^16.0.0 || ^17.0.0 || 17 - react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || 17 + '@types/react': ^17.0.39 + react: ^17.0.2 || 17 + react-dom: ^17.0.2 || 17 peerDependenciesMeta: '@types/react': optional: true @@ -11783,7 +12314,7 @@ packages: /react-inlinesvg@1.2.0(react@17.0.2): resolution: {integrity: sha512-IsznU+UzpUwDGzBWbf0bfSRA5Jbqz87xeoqLM/nSIDPkoHksInF1wCGybTSn4sIui+30TqboRQP1wAelNTkdog==} peerDependencies: - react: ^16.3.0 || 17 + react: ^17.0.2 || 17 dependencies: exenv: 1.2.2 react: 17.0.2 @@ -11799,7 +12330,7 @@ packages: /react-router-dom@5.2.0(react@17.0.2): resolution: {integrity: sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==} peerDependencies: - react: '>=15 || 17' + react: ^17.0.2 || 17 dependencies: '@babel/runtime': 7.22.5 history: 4.10.1 @@ -11814,7 +12345,7 @@ packages: /react-router-ga@1.2.3(react-router-dom@5.2.0)(react@17.0.2): resolution: {integrity: sha512-0rNBGGI6Q1hkznbLB+bAmDTS+8w3duaJYYIbCrCwof/p7RbZuv+Lsv9enumRZXxb4oTZrY95vOvFxnsRQ4cFCg==} peerDependencies: - react: ^16.8.6 || 17 + react: ^17.0.2 || 17 react-router-dom: ^5.0.0 dependencies: react: 17.0.2 @@ -11824,7 +12355,7 @@ packages: /react-router@5.2.0(react@17.0.2): resolution: {integrity: sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==} peerDependencies: - react: '>=15 || 17' + react: ^17.0.2 || 17 dependencies: '@babel/runtime': 7.22.5 history: 4.10.1 @@ -11842,8 +12373,8 @@ packages: /react-scroll@1.8.2(react-dom@17.0.2)(react@17.0.2): resolution: {integrity: sha512-f2ZEG5fsPbPTySI9ekcFpETCcNlqbmwbQj9hhzYK8tkgv+PA8APatSt66o/q0KSkDZxyT98ONTtXp9x0lyowEw==} peerDependencies: - react: ^15.5.4 || ^16.0.0 || ^17.0.0 || 17 - react-dom: ^15.5.4 || ^16.0.0 || ^17.0.0 || 17 + react: ^17.0.2 || 17 + react-dom: ^17.0.2 || 17 dependencies: lodash.throttle: 4.1.1 prop-types: 15.8.1 @@ -11854,7 +12385,7 @@ packages: /react-shallow-renderer@16.14.1(react@17.0.2): resolution: {integrity: sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==} peerDependencies: - react: ^16.0.0 || ^17.0.0 || 17 + react: ^17.0.2 || 17 dependencies: object-assign: 4.1.1 react: 17.0.2 @@ -11864,7 +12395,7 @@ packages: /react-side-effect@1.2.0(react@17.0.2): resolution: {integrity: sha512-v1ht1aHg5k/thv56DRcjw+WtojuuDHFUgGfc+bFHOWsF4ZK6C2V57DO0Or0GPsg6+LSTE0M6Ry/gfzhzSwbc5w==} peerDependencies: - react: ^0.13.0 || ^0.14.0 || ^15.0.0 || ^16.0.0 || 17 + react: ^17.0.2 || 17 dependencies: react: 17.0.2 shallowequal: 1.1.0 @@ -11872,7 +12403,7 @@ packages: /react-ssr-prepass@1.4.0(react@17.0.2): resolution: {integrity: sha512-0SzdmiQUtHvhxCabHg9BI/pkJfijGkQ0jQL6fC4YFy7idaDOuaiQLsajIkkNxffFXtJFHIWFITlve2WB88e0Jw==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || 17 + react: ^17.0.2 || 17 dependencies: react: 17.0.2 dev: true @@ -11915,8 +12446,8 @@ packages: /react-static-plugin-styled-components@7.2.2(react@17.0.2)(styled-components@5.2.3): resolution: {integrity: sha512-yjZ2V5b4HLRs6ldbLmreXpXBiNU5y4IByPID/rYWe3J8NFenPMI7kbhiFlBDkUDEhJvGIpSFw3I8OCvAcm4yQg==} peerDependencies: - react: ^16.9.0 || 17 - styled-components: ^4.3.2 || 5 + react: ^17.0.2 || 17 + styled-components: ^5.2.3 || 5 dependencies: react: 17.0.2 styled-components: 5.2.3(react-dom@17.0.2)(react-is@17.0.2)(react@17.0.2) @@ -12013,7 +12544,7 @@ packages: /react-test-renderer@17.0.2(react@17.0.2): resolution: {integrity: sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==} peerDependencies: - react: 17.0.2 || 17 + react: ^17.0.2 || 17 dependencies: object-assign: 4.1.1 react: 17.0.2 @@ -12025,7 +12556,7 @@ packages: /react-universal-component@4.5.0(react@17.0.2): resolution: {integrity: sha512-dBUC6afvSAQhDcE4oh1eTmfU29W0O2eZhcGXnfGUTulXkU8ejuWqlJWXXrSMx5iV1H6LNgj2NJMj3BtBMfBNhA==} peerDependencies: - react: ^16.3.0 || ^17.0.0 || 17 + react: ^17.0.2 || 17 dependencies: hoist-non-react-statics: 3.3.2 prop-types: 15.8.1 @@ -12535,7 +13066,7 @@ packages: rollup: 3.21.1 typescript: 5.1.6 optionalDependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.24.7 dev: true /rollup-plugin-visualizer@5.9.0(rollup@3.21.1): @@ -12750,6 +13281,18 @@ packages: randombytes: 2.1.0 dev: true + /seroval-plugins@1.0.7(seroval@1.0.7): + resolution: {integrity: sha512-GO7TkWvodGp6buMEX9p7tNyIkbwlyuAWbI6G9Ec5bhcm7mQdu3JOK1IXbEUwb3FVzSc363GraG/wLW23NSavIw==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + dependencies: + seroval: 1.0.7 + + /seroval@1.0.7: + resolution: {integrity: sha512-n6ZMQX5q0Vn19Zq7CIKNIo7E75gPkGCFUEqDpa8jgwpYr/vScjqnQ6H09t1uIiZ0ZSK0ypEGvrYK2bhBGWsGdw==} + engines: {node: '>=10'} + /serve-handler@6.1.3: resolution: {integrity: sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==} dependencies: @@ -13088,6 +13631,26 @@ packages: smart-buffer: 4.2.0 dev: true + /solid-js@1.8.17: + resolution: {integrity: sha512-E0FkUgv9sG/gEBWkHr/2XkBluHb1fkrHywUgA6o6XolPDCJ4g1HaLmQufcBBhiF36ee40q+HpG/vCZu7fLpI3Q==} + dependencies: + csstype: 3.1.3 + seroval: 1.0.7 + seroval-plugins: 1.0.7(seroval@1.0.7) + + /solid-refresh@0.6.3(solid-js@1.8.17): + resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==} + peerDependencies: + solid-js: ^1.3 + dependencies: + '@babel/generator': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/types': 7.24.0 + solid-js: 1.8.17 + transitivePeerDependencies: + - supports-color + dev: true + /sort-keys-length@1.0.1: resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} engines: {node: '>=0.10.0'} @@ -13290,6 +13853,10 @@ packages: resolution: {integrity: sha512-uUZI65yrV2Qva5gqE0+A7uVAvO40iPo6jGhs7s8keRfHCmtg+uB2X6EiLGCI9IgL1J17xGhvoOqSz79lzICPTA==} dev: true + /std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + dev: true + /stream-browserify@2.0.2: resolution: {integrity: sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==} dependencies: @@ -13526,9 +14093,9 @@ packages: resolution: {integrity: sha512-BlR+KrLW3NL1yhvEB+9Nu9Dt51CuOnHoxd+Hj+rYPdtyR8X11uIW9rvhpy3Dk4dXXBsiW1u5U78f00Lf/afGoA==} engines: {node: '>=10'} peerDependencies: - react: '>= 16.8.0 || 17' - react-dom: '>= 16.8.0 || 17' - react-is: '>= 16.8.0 || 17' + react: ^17.0.2 || 17 + react-dom: ^17.0.2 || 17 + react-is: ^17.0.2 || 17 dependencies: '@babel/helper-module-imports': 7.21.4 '@babel/traverse': 7.21.5(supports-color@5.5.0) @@ -13550,7 +14117,7 @@ packages: peerDependencies: '@babel/core': '*' babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || 17' + react: ^17.0.2 || 17 peerDependenciesMeta: '@babel/core': optional: true @@ -13827,13 +14394,17 @@ packages: resolution: {integrity: sha512-iyziEiyFxX4kyxSp+MtY1oCH/lvjH3PxFN8PGCDeqcZWAJ/i+9y+nL85w99PxVzrIvew/GSkSbDYtiGVa85Afg==} dev: true + /tinybench@2.8.0: + resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} + dev: true + /tinypool@0.4.0: resolution: {integrity: sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==} engines: {node: '>=14.0.0'} dev: true - /tinyspy@2.1.0: - resolution: {integrity: sha512-7eORpyqImoOvkQJCSkL0d0mB4NHHIFAy4b1u8PHdDa7SjGS2njzl6/lyGoZLm+eyYEtlUmFGE0rFj66SWxZgQQ==} + /tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} engines: {node: '>=14.0.0'} dev: true @@ -14135,8 +14706,8 @@ packages: hasBin: true dev: true - /ufo@1.1.1: - resolution: {integrity: sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg==} + /ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} dev: true /uglify-js@3.4.10: @@ -14390,6 +14961,17 @@ packages: escalade: 3.1.1 picocolors: 1.0.0 + /update-browserslist-db@1.0.16(browserslist@4.23.0): + resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.0 + escalade: 3.1.2 + picocolors: 1.0.1 + dev: true + /update-check@1.5.2: resolution: {integrity: sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==} dependencies: @@ -14453,7 +15035,7 @@ packages: /use-sync-external-store@1.2.0(react@17.0.2): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || 17 + react: ^17.0.2 || 17 dependencies: react: 17.0.2 dev: true @@ -14512,6 +15094,10 @@ packages: hasBin: true dev: true + /validate-html-nesting@1.2.2: + resolution: {integrity: sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg==} + dev: true + /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -14574,9 +15160,9 @@ packages: dependencies: cac: 6.7.14 debug: 4.3.4(supports-color@5.5.0) - mlly: 1.2.0 - pathe: 1.1.0 - picocolors: 1.0.0 + mlly: 1.7.1 + pathe: 1.1.2 + picocolors: 1.0.1 vite: 3.2.5(@types/node@18.16.3)(terser@5.17.1) transitivePeerDependencies: - '@types/node' @@ -14588,10 +15174,32 @@ packages: - terser dev: true + /vite-plugin-solid@2.10.2(solid-js@1.8.17)(vite@3.2.5): + resolution: {integrity: sha512-AOEtwMe2baBSXMXdo+BUwECC8IFHcKS6WQV/1NEd+Q7vHPap5fmIhLcAzr+DUJ04/KHx/1UBU0l1/GWP+rMAPQ==} + peerDependencies: + '@testing-library/jest-dom': ^5.16.6 || ^5.17.0 || ^6.* + solid-js: ^1.7.2 + vite: ^3.2.4 + peerDependenciesMeta: + '@testing-library/jest-dom': + optional: true + dependencies: + '@babel/core': 7.24.7 + '@types/babel__core': 7.20.5 + babel-preset-solid: 1.8.17(@babel/core@7.24.7) + merge-anything: 5.1.7 + solid-js: 1.8.17 + solid-refresh: 0.6.3(solid-js@1.8.17) + vite: 3.2.5(@types/node@18.16.3)(terser@5.17.1) + vitefu: 0.2.5(vite@3.2.5) + transitivePeerDependencies: + - supports-color + dev: true + /vite-tsconfig-paths@4.2.0(typescript@5.1.6)(vite@3.2.5): resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==} peerDependencies: - vite: '*' + vite: ^3.2.4 peerDependenciesMeta: vite: optional: true @@ -14640,6 +15248,17 @@ packages: fsevents: 2.3.3 dev: true + /vitefu@0.2.5(vite@3.2.5): + resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} + peerDependencies: + vite: ^3.2.4 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 3.2.5(@types/node@18.16.3)(terser@5.17.1) + dev: true + /vitest@0.30.1(jsdom@21.1.1)(terser@5.17.1): resolution: {integrity: sha512-y35WTrSTlTxfMLttgQk4rHcaDkbHQwDP++SNwPb+7H8yb13Q3cu2EixrtHzF27iZ8v0XCciSsLg00RkPAzB/aA==} engines: {node: '>=v14.18.0'} @@ -14707,6 +15326,73 @@ packages: - terser dev: true + /vitest@0.30.1(jsdom@22.1.0)(terser@5.17.1): + resolution: {integrity: sha512-y35WTrSTlTxfMLttgQk4rHcaDkbHQwDP++SNwPb+7H8yb13Q3cu2EixrtHzF27iZ8v0XCciSsLg00RkPAzB/aA==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.16 + '@types/chai-subset': 1.3.3 + '@types/node': 18.16.3 + '@vitest/expect': 0.30.1 + '@vitest/runner': 0.30.1 + '@vitest/snapshot': 0.30.1 + '@vitest/spy': 0.30.1 + '@vitest/utils': 0.30.1 + acorn: 8.11.3 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + concordance: 5.0.4 + debug: 4.3.4(supports-color@5.5.0) + jsdom: 22.1.0 + local-pkg: 0.4.3 + magic-string: 0.30.0 + pathe: 1.1.2 + picocolors: 1.0.1 + source-map: 0.6.1 + std-env: 3.7.0 + strip-literal: 1.0.1 + tinybench: 2.8.0 + tinypool: 0.4.0 + vite: 3.2.5(@types/node@18.16.3)(terser@5.17.1) + vite-node: 0.30.1(@types/node@18.16.3)(terser@5.17.1) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vm-browserify@1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} @@ -14871,7 +15557,7 @@ packages: /webpack-flush-chunks@2.0.3(react@17.0.2): resolution: {integrity: sha512-CXGOyXG5YjjxyI+Qyt3VlI//JX92UmGRNP65zN3o9CIntEzfzc1J30YTKRRvF1JsE/iEzbnp5u99yCkL9obotQ==} peerDependencies: - react: '*' + react: ^17.0.2 || 17 dependencies: react: 17.0.2 diff --git a/vitest.config.ts b/vitest.config.ts index abb29bd401..2b108b4726 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -18,6 +18,7 @@ export default defineConfig({ setupFiles: [resolve(__dirname, 'scripts/vitest/setup.js')], clearMocks: true, exclude: [ + 'packages/solid-urql/**', '**/node_modules/**', '**/dist/**', '**/cypress/**',