diff --git a/.changeset/good-eagles-speak.md b/.changeset/good-eagles-speak.md new file mode 100644 index 00000000..f8b2292e --- /dev/null +++ b/.changeset/good-eagles-speak.md @@ -0,0 +1,16 @@ +--- +"@dojoengine/sdk": minor +"template-vite-ts": minor +"@dojoengine/core": minor +"@dojoengine/create-burner": minor +"@dojoengine/create-dojo": minor +"@dojoengine/predeployed-connector": minor +"@dojoengine/react": minor +"@dojoengine/state": minor +"@dojoengine/torii-client": minor +"@dojoengine/torii-wasm": minor +"@dojoengine/utils": minor +"@dojoengine/utils-wasm": minor +--- + +feat: add reusable sdk react hooks diff --git a/examples/example-nodejs-bot/tsconfig.json b/examples/example-nodejs-bot/tsconfig.json index fdca51ed..54045688 100644 --- a/examples/example-nodejs-bot/tsconfig.json +++ b/examples/example-nodejs-bot/tsconfig.json @@ -14,8 +14,7 @@ "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "allowJs": true, - "outDir": "dist", - "types": ["bun-types"] + "outDir": "dist" }, "include": [ "./src/**/*", diff --git a/examples/example-vite-react-sdk/dojoConfig.ts b/examples/example-vite-react-sdk/dojoConfig.ts index e45ee85a..484d368d 100644 --- a/examples/example-vite-react-sdk/dojoConfig.ts +++ b/examples/example-vite-react-sdk/dojoConfig.ts @@ -1,6 +1,6 @@ import { createDojoConfig } from "@dojoengine/core"; -import manifest from "../../worlds/dojo-starter/manifest_dev.json"; +import manifest from "../../../dojo-starter/manifest_dev.json"; export const dojoConfig = createDojoConfig({ manifest, diff --git a/examples/example-vite-react-sdk/package.json b/examples/example-vite-react-sdk/package.json index 999df01d..13fc89c5 100644 --- a/examples/example-vite-react-sdk/package.json +++ b/examples/example-vite-react-sdk/package.json @@ -21,8 +21,8 @@ "@starknet-react/core": "catalog:", "@types/uuid": "^10.0.0", "immer": "^10.1.1", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "catalog:", + "react-dom": "catalog:", "starknet": "catalog:", "uuid": "^10.0.0", "vite-plugin-top-level-await": "^1.5.0", diff --git a/examples/example-vite-react-sdk/src/App.tsx b/examples/example-vite-react-sdk/src/App.tsx index 386fd4cf..072ea224 100644 --- a/examples/example-vite-react-sdk/src/App.tsx +++ b/examples/example-vite-react-sdk/src/App.tsx @@ -1,14 +1,18 @@ -import { useEffect, useMemo } from "react"; import { KeysClause, ToriiQueryBuilder } from "@dojoengine/sdk"; -import { getEntityIdFromKeys } from "@dojoengine/utils"; -import { AccountInterface, addAddressPadding, CairoCustomEnum } from "starknet"; import { ModelsMapping } from "./typescript/models.gen.ts"; import { useSystemCalls } from "./useSystemCalls.ts"; import { useAccount } from "@starknet-react/core"; import { WalletAccount } from "./wallet-account.tsx"; import { HistoricalEvents } from "./historical-events.tsx"; -import { useDojoSDK, useModel } from "@dojoengine/sdk/react"; +import { + useDojoSDK, + useEntityId, + useEntityQuery, + useModel, +} from "@dojoengine/sdk/react"; +import { addAddressPadding, CairoCustomEnum } from "starknet"; +import { Events } from "./events.tsx"; /** * Main application component that provides game functionality and UI. @@ -17,79 +21,26 @@ import { useDojoSDK, useModel } from "@dojoengine/sdk/react"; * @param props.sdk - The Dojo SDK instance configured with the game schema */ function App() { - const { useDojoStore, client, sdk } = useDojoSDK(); + const { useDojoStore, client } = useDojoSDK(); const { account } = useAccount(); - const state = useDojoStore((state) => state); const entities = useDojoStore((state) => state.entities); const { spawn } = useSystemCalls(); - const entityId = useMemo(() => { - if (account) { - return getEntityIdFromKeys([BigInt(account.address)]); - } - return BigInt(0); - }, [account]); - - // This is experimental feature. - // Use those queries if you want to be closer to how you should query your ecs system with torii - // useEffect(() => { - // async function fetchToriiClause() { - // const res = await sdk.client.getEntities( - // new ToriiQueryBuilder() - // .withClause( - // new ClauseBuilder() - // .keys([], [undefined], "VariableLen") - // .build() - // ) - // .withLimit(2) - // .addOrderBy(ModelsMapping.Moves, "remaining", "Desc") - // .build() - // ); - // return res; - // } - // fetchToriiClause().then(console.log); - // }); - - useEffect(() => { - let unsubscribe: (() => void) | undefined; - - const subscribe = async (account: AccountInterface) => { - const [initialData, subscription] = await sdk.subscribeEntityQuery({ - query: new ToriiQueryBuilder() - .withClause( - // Querying Moves and Position models that has at least [account.address] as key - KeysClause( - [ModelsMapping.Moves, ModelsMapping.Position], - [addAddressPadding(account.address)], - "VariableLen" - ).build() - ) - .includeHashedKeys(), - callback: ({ error, data }) => { - if (error) { - console.error("Error setting up entity sync:", error); - } else if (data && data[0].entityId !== "0x0") { - state.updateEntity(data[0]); - } - }, - }); - - state.setEntities(initialData); - - unsubscribe = () => subscription.cancel(); - }; - - if (account) { - subscribe(account); - } - - return () => { - if (unsubscribe) { - unsubscribe(); - } - }; - }, [sdk, account, state]); + const entityId = useEntityId(account?.address ?? "0"); + + useEntityQuery( + new ToriiQueryBuilder() + .withClause( + // Querying Moves and Position models that has at least [account.address] as key + KeysClause( + [ModelsMapping.Moves, ModelsMapping.Position], + [addAddressPadding(account?.address ?? "0")], + "FixedLen" + ).build() + ) + .includeHashedKeys() + ); const moves = useModel(entityId as string, ModelsMapping.Moves); const position = useModel(entityId as string, ModelsMapping.Position); @@ -253,6 +204,7 @@ function App() { + {/* // Here sdk is passed as props but this can be done via contexts */} diff --git a/examples/example-vite-react-sdk/src/events.tsx b/examples/example-vite-react-sdk/src/events.tsx new file mode 100644 index 00000000..452d7ab4 --- /dev/null +++ b/examples/example-vite-react-sdk/src/events.tsx @@ -0,0 +1,40 @@ +import { KeysClause, ToriiQueryBuilder } from "@dojoengine/sdk"; +import { useEntityId, useEventQuery, useModel } from "@dojoengine/sdk/react"; +import { useAccount } from "@starknet-react/core"; +import { addAddressPadding } from "starknet"; +import { ModelsMapping } from "./typescript/models.gen"; + +export function Events() { + const { account } = useAccount(); + const entityId = useEntityId(account?.address ?? "0"); + useEventQuery( + new ToriiQueryBuilder() + .withClause( + KeysClause( + [], + [addAddressPadding(account?.address ?? "0")], + "VariableLen" + ).build() + ) + .includeHashedKeys() + ); + const moved = useModel(entityId, ModelsMapping.Moved); + if (!account) { + return ( +
+

Please connect your wallet

+
+ ); + } + return ( +
+

+ Player Last Movement : {moved && moved.direction}{" "} +

+ + {/* {events.map((e: ParsedEntity, key) => { + return ; + })} */} +
+ ); +} diff --git a/examples/example-vite-react-sdk/src/historical-events.tsx b/examples/example-vite-react-sdk/src/historical-events.tsx index a8805940..ae38b878 100644 --- a/examples/example-vite-react-sdk/src/historical-events.tsx +++ b/examples/example-vite-react-sdk/src/historical-events.tsx @@ -1,54 +1,20 @@ import { KeysClause, ParsedEntity, ToriiQueryBuilder } from "@dojoengine/sdk"; import { useAccount } from "@starknet-react/core"; import { SchemaType } from "./typescript/models.gen"; -import { AccountInterface, addAddressPadding } from "starknet"; -import { useEffect, useState } from "react"; -import { Subscription } from "@dojoengine/torii-client"; -import { useDojoSDK } from "@dojoengine/sdk/react"; +import { addAddressPadding } from "starknet"; +import { useHistoricalEventsQuery } from "@dojoengine/sdk/react"; export function HistoricalEvents() { const { account } = useAccount(); - const { sdk } = useDojoSDK(); - const [events, setEvents] = useState[]>([]); - const [subscription, setSubscription] = useState(null); - - useEffect(() => { - async function subscribeHistoricalEvent(account: AccountInterface) { - try { - const [e, s] = await sdk.subscribeEventQuery({ - query: new ToriiQueryBuilder().withClause( - KeysClause( - [], - [addAddressPadding(account.address)], - "VariableLen" - ).build() - ), - callback: ({ data, error }) => { - if (data && data.length > 0) { - console.log(data); - } - if (error) { - console.error(error); - } - }, - historical: true, - }); - setEvents(e as unknown as ParsedEntity[]); - setSubscription(s); - } catch (error) { - setEvents([]); - if (subscription) { - subscription.free(); - } - console.error(error); - } - } - - if (account) { - subscribeHistoricalEvent(account); - } - }, [account, setEvents, sdk]); - + const events = useHistoricalEventsQuery( + new ToriiQueryBuilder().withClause( + KeysClause( + [], + [addAddressPadding(account?.address ?? "0")], + "VariableLen" + ).build() + ) + ); if (!account) { return (
@@ -59,6 +25,7 @@ export function HistoricalEvents() { return (

Player Events :

+ {/* @ts-ignore */} {events.map((e: ParsedEntity, key) => { return ; })} diff --git a/examples/example-vite-react-sdk/src/starknet-provider.tsx b/examples/example-vite-react-sdk/src/starknet-provider.tsx index 43554781..ea314545 100644 --- a/examples/example-vite-react-sdk/src/starknet-provider.tsx +++ b/examples/example-vite-react-sdk/src/starknet-provider.tsx @@ -32,6 +32,7 @@ export default function StarknetProvider({ children }: PropsWithChildren) { explorer={voyager} autoConnect > + {/* @ts-ignore react version mismatch */} {children} ); diff --git a/examples/example-vite-react-sdk/tsconfig.app.tsbuildinfo b/examples/example-vite-react-sdk/tsconfig.app.tsbuildinfo index ce91cf1a..f71190e8 100644 --- a/examples/example-vite-react-sdk/tsconfig.app.tsbuildinfo +++ b/examples/example-vite-react-sdk/tsconfig.app.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/app.tsx","./src/historical-events.tsx","./src/main.tsx","./src/starknet-provider.tsx","./src/usesystemcalls.ts","./src/vite-env.d.ts","./src/wallet-account.tsx","./src/typescript/contracts.gen.ts","./src/typescript/models.gen.ts"],"version":"5.7.3"} \ No newline at end of file +{"root":["./src/app.tsx","./src/events.tsx","./src/historical-events.tsx","./src/main.tsx","./src/starknet-provider.tsx","./src/usesystemcalls.ts","./src/vite-env.d.ts","./src/wallet-account.tsx","./src/typescript/contracts.gen.ts","./src/typescript/models.gen.ts"],"version":"5.7.3"} \ No newline at end of file diff --git a/examples/example-vite-react-sql/src/hooks/usePlayerActions.ts b/examples/example-vite-react-sql/src/hooks/usePlayerActions.ts index 184646c5..4686d8fc 100644 --- a/examples/example-vite-react-sql/src/hooks/usePlayerActions.ts +++ b/examples/example-vite-react-sql/src/hooks/usePlayerActions.ts @@ -1,62 +1,20 @@ -import { useEffect, useMemo } from "react"; - -import { KeysClause, ParsedEntity, ToriiQueryBuilder } from "@dojoengine/sdk"; -import { useDojoSDK } from "@dojoengine/sdk/react"; -import { getEntityIdFromKeys } from "@dojoengine/utils"; -import { ModelsMapping, SchemaType } from "@/typescript/models.gen"; +import { KeysClause, ToriiQueryBuilder } from "@dojoengine/sdk"; +import { useEntityId, useEntityQuery } from "@dojoengine/sdk/react"; +import { ModelsMapping, type SchemaType } from "@/typescript/models.gen"; import { addAddressPadding } from "starknet"; export function usePlayerActions(address: string | undefined) { - const { sdk, useDojoStore } = useDojoSDK(); - const state = useDojoStore((state) => state); - - const entityId = useMemo(() => { - if (address) { - return getEntityIdFromKeys([BigInt(address)]); - } - return BigInt(0); - }, [address]); - - useEffect(() => { - let unsubscribe: (() => void) | undefined; - - const subscribe = async (address: string) => { - const [entities, subscription] = await sdk.subscribeEntityQuery({ - query: new ToriiQueryBuilder() - .withClause( - KeysClause( - [ModelsMapping.Moves, ModelsMapping.Position], - [addAddressPadding(address)], - "VariableLen" - ).build() - ) - .includeHashedKeys(), - callback: ({ error, data }) => { - if (error) { - console.error("Error setting up entity sync:", error); - } else if ( - data && - (data[0] as ParsedEntity).entityId !== "0x0" - ) { - state.updateEntity(data[0] as ParsedEntity); - } - }, - }); - state.setEntities(entities); - - unsubscribe = () => subscription.cancel(); - }; - - if (address) { - subscribe(address); - } - - return () => { - if (unsubscribe) { - unsubscribe(); - } - }; - }, [sdk, address]); - + const entityId = useEntityId(address ?? "0"); + useEntityQuery( + new ToriiQueryBuilder() + .withClause( + KeysClause( + [ModelsMapping.Moves, ModelsMapping.Position], + [addAddressPadding(address ?? "0")], + "VariableLen" + ).build() + ) + .includeHashedKeys() + ); return entityId; } diff --git a/examples/example-vite-react-sql/src/routes/__root.tsx b/examples/example-vite-react-sql/src/routes/__root.tsx index 81507374..e99f0358 100644 --- a/examples/example-vite-react-sql/src/routes/__root.tsx +++ b/examples/example-vite-react-sql/src/routes/__root.tsx @@ -21,6 +21,7 @@ function RootComponent() {
+ {/* @ts-ignore */}
diff --git a/examples/example-vite-react-threejs-recs/src/gameComponents/Player.tsx b/examples/example-vite-react-threejs-recs/src/gameComponents/Player.tsx index 89206b19..24b400b3 100644 --- a/examples/example-vite-react-threejs-recs/src/gameComponents/Player.tsx +++ b/examples/example-vite-react-threejs-recs/src/gameComponents/Player.tsx @@ -140,6 +140,7 @@ export const Player = (props: any) => { return ( <> + {/* @ts-ignore */} { const initialCameraPosition = new Vector3(0, 100.0, 100); // Desired initial position return ( + // @ts-ignore + {/* @ts-ignore */} ( ): Promise => { return await client.getControllers(contract_addresses); }, + /** + * Convert torii clause into EntityKeysClause[]; + * + * @param {query} query - ToriiQueryBuilder + * @returns [ToriiResponse,torii.EntityKeysClause[]] + */ + toriiQueryIntoHashedKeys: async ( + query: ToriiQueryBuilder + ): Promise<[ToriiResponse, torii.EntityKeysClause[]]> => { + const q = query.build(); + const entities = parseEntities(await client.getEntities(q)); + return [entities, intoEntityKeysClause(q.clause, entities)]; + }, + + /** + * Convert torii clause into EntityKeysClause[]; + * + * @param {query} query - ToriiQueryBuilder + * @returns [ToriiResponse,torii.EntityKeysClause[]] + */ + toriiEventMessagesQueryIntoHashedKeys: async ( + query: ToriiQueryBuilder, + historical: H + ): Promise<[ToriiResponse, torii.EntityKeysClause[]]> => { + const q = query.build(); + + const events = await client.getEventMessages( + q, + historical ? historical : false + ); + return [ + (historical + ? parseHistoricalEvents(events) + : parseEntities(events)) as ToriiResponse, + + // @ts-expect-error will fix + intoEntityKeysClause(q.clause, events), + ]; + }, }; } diff --git a/packages/sdk/src/react/hooks.ts b/packages/sdk/src/react/hooks.ts index 7555556d..860e7e79 100644 --- a/packages/sdk/src/react/hooks.ts +++ b/packages/sdk/src/react/hooks.ts @@ -1,10 +1,20 @@ -import { useContext } from "react"; -import { BigNumberish } from "starknet"; -import { SchemaType } from "../types"; -import { DojoContext, DojoContextType } from "./provider"; -import { create, StoreApi, UseBoundStore } from "zustand"; +import { + useCallback, + useContext, + useEffect, + useMemo, + useRef, + useState, +} from "react"; +import type { BigNumberish } from "starknet"; +import { StandardizedQueryResult, type SchemaType } from "../types"; +import { DojoContext, type DojoContextType } from "./provider"; +import { create, type StoreApi, type UseBoundStore } from "zustand"; import { createDojoStoreFactory } from "../state/zustand"; -import { GameState } from "../state"; +import type { GameState } from "../state"; +import { ToriiQueryBuilder } from "../toriiQueryBuilder"; +import { Subscription } from "@dojoengine/torii-client"; +import { getEntityIdFromKeys } from "@dojoengine/utils"; /** * Factory function to create a React Zustand store based on a given SchemaType. @@ -47,9 +57,399 @@ export function useModel< return modelData; } +/** + * Hook that exposes sdk features. + * + * @template Client Client function generated with `sozo build --typescript` + * @template Schema Schema function generated with `sozo build --typescript` + * @returns DojoContextType + */ export function useDojoSDK< Client extends (...args: any) => any, Schema extends SchemaType, >(): DojoContextType { return useContext>(DojoContext); } + +/** + * If you know all distinct keys of your model, here is a way to compose it. + * + * @param keys Each keys corresponding to your model keys. + * @returns Composed entityId + */ +export function useEntityId(...keys: BigNumberish[]): BigNumberish { + const entityId = useMemo(() => { + if (keys.length > 0) { + return getEntityIdFromKeys(keys.map((k) => BigInt(k))); + } + return BigInt(0); + }, [keys]); + + return entityId; +} + +/** + * Subscribe to entity changes. This hook fetches initial data from torii and subscribe to each entity change. Use `useModel` to access your data. + * + * @param query ToriiQuery + */ +export function useEntityQuery( + query: ToriiQueryBuilder +) { + const { sdk, useDojoStore } = useDojoSDK(); + const state = useDojoStore((s) => s); + + // Subscription handle to update. Avoid unecessary creating/cancelling subscriptions + const subscriptionRef = useRef(null); + // Handle to user input query. + const fetchingRef = useRef | null>(null); + // Async lock to sync with event loop + const isUpdating = useRef(false); + + const fetchData = useCallback(async () => { + // Wait until lock is released + while (isUpdating.current) { + await sleep(50); + } + + // Lock function + isUpdating.current = true; + + if (subscriptionRef.current) { + const [entities, clause] = await sdk.toriiQueryIntoHashedKeys( + fetchingRef.current! + ); + await sdk.updateEntitySubscription(subscriptionRef.current, clause); + state.mergeEntities(entities); + return null; + } + + const [initialData, subscription] = await sdk.subscribeEntityQuery({ + query: fetchingRef.current!, + callback: ({ data, error }) => { + if (data) { + const entity = data.pop(); + if (entity && entity.entityId !== "0x0") { + state.updateEntity(entity); + } + } + if (error) { + console.error( + "Dojo.js - useEntityQuery - error subscribing to entity with query : ", + query.toString() + ); + console.error(error); + } + }, + }); + + state.mergeEntities(initialData); + + return subscription; + }, [query, subscriptionRef]); + + useEffect(() => { + if (!deepEqual(query, fetchingRef.current)) { + fetchingRef.current = query; + + fetchData() + .then((s) => { + if (s !== null) { + subscriptionRef.current = s; + } + // Important to release lock at this point. + isUpdating.current = false; + }) + .catch((err) => { + console.error( + "Dojo.js - useEntityQuery - error fetching entities for query ", + JSON.stringify(query) + ); + console.error(err); + }) + .finally(() => { + // Important to release lock at this point. + isUpdating.current = false; + }); + } + + return () => { + if (subscriptionRef.current) { + // subscriptionRef.current?.cancel(); + // subscriptionRef.current = null; + // setSub(null); + } + }; + }, [query, subscriptionRef, fetchData]); +} + +/** + * Subscribe to entity changes. This hook fetches initial data from torii and subscribe to each entity change. Use `useModel` to access your data. + * + * @param query ToriiQuery + */ +export function useEventQuery( + query: ToriiQueryBuilder +) { + const { sdk, useDojoStore } = useDojoSDK(); + const state = useDojoStore((s) => s); + + // Subscription handle to update. Avoid unecessary creating/cancelling subscriptions + const subscriptionRef = useRef(null); + // Handle to user input query. + const fetchingRef = useRef | null>(null); + // Async lock to sync with event loop + const isUpdating = useRef(false); + + const fetchData = useCallback(async () => { + // Wait until lock is released + while (isUpdating.current) { + await sleep(50); + } + + // Lock function + isUpdating.current = true; + + if (subscriptionRef.current) { + const [events, clause] = + await sdk.toriiEventMessagesQueryIntoHashedKeys( + fetchingRef.current!, + false + ); + await sdk.updateEventMessageSubscription( + subscriptionRef.current, + clause, + false + ); + state.mergeEntities(events); + + return null; + } + + const [initialData, subscription] = await sdk.subscribeEventQuery({ + query: fetchingRef.current!, + callback: ({ data, error }) => { + if (data) { + const event = data.pop(); + if (event && event.entityId !== "0x0") { + state.updateEntity(event); + } + } + if (error) { + console.error( + "Dojo.js - useEventQuery - error subscribing to events with query : ", + query.toString() + ); + console.error(error); + } + }, + historical: false, + }); + + state.mergeEntities(initialData); + + return subscription; + }, [query, subscriptionRef]); + + useEffect(() => { + if (!deepEqual(query, fetchingRef.current)) { + fetchingRef.current = query; + + fetchData() + .then((s) => { + if (s !== null) { + subscriptionRef.current = s; + } + // Important to release lock at this point. + isUpdating.current = false; + }) + .catch((err) => { + console.error( + "Dojo.js - useEventQuery - error fetching events for query ", + JSON.stringify(query) + ); + console.error(err); + }) + .finally(() => { + // Important to release lock at this point. + isUpdating.current = false; + }); + } + + return () => { + if (subscriptionRef.current) { + // subscriptionRef.current?.cancel(); + // subscriptionRef.current = null; + // setSub(null); + } + }; + }, [query, subscriptionRef, fetchData]); +} + +/** + * Subscribe to historical events changes. This hook fetches initial data from torii and subscribe to each entity change. Use `useModel` to access your data. + * You need to specify to torii which events has to be taken in account as historical events. + * + * @param query ToriiQuery + */ +export function useHistoricalEventsQuery( + query: ToriiQueryBuilder +) { + const { sdk } = useDojoSDK<() => any, Schema>(); + const [events, setEvents] = useState[]>([]); + + // Subscription handle to update. Avoid unecessary creating/cancelling subscriptions + const subscriptionRef = useRef(null); + // Handle to user input query. + const fetchingRef = useRef | null>(null); + // Async lock to sync with event loop + const isUpdating = useRef(false); + + const fetchData = useCallback(async () => { + // Wait until lock is released + while (isUpdating.current) { + await sleep(50); + } + + // Lock function + isUpdating.current = true; + + if (subscriptionRef.current) { + const [events, clause] = + await sdk.toriiEventMessagesQueryIntoHashedKeys( + fetchingRef.current!, + true + ); + await sdk.updateEventMessageSubscription( + subscriptionRef.current, + clause, + true + ); + setEvents(events); + return null; + } + + const [initialData, subscription] = await sdk.subscribeEventQuery({ + query: fetchingRef.current!, + callback: ({ data, error }) => { + if (data) { + const event = data.pop(); + if (event) { + setEvents((ev) => [event, ...ev]); + } + } + if (error) { + console.error( + "Dojo.js - useHistoricalEventsQuery - error subscribing to events with query : ", + query.toString() + ); + console.error(error); + } + }, + historical: true, + }); + + setEvents(initialData); + + return subscription; + }, [query, subscriptionRef]); + + useEffect(() => { + if (!deepEqual(query, fetchingRef.current)) { + fetchingRef.current = query; + + fetchData() + .then((s) => { + if (s !== null) { + subscriptionRef.current = s; + } + }) + .catch((err) => { + console.error( + "Dojo.js - useHistoricalEventsQuery - error fetching events for query ", + JSON.stringify(query) + ); + console.error(err); + }) + .finally(() => { + // Important to release lock at this point. + isUpdating.current = false; + }); + } + + return () => { + if (subscriptionRef.current) { + // subscriptionRef.current?.cancel(); + // subscriptionRef.current = null; + // setSub(null); + } + }; + }, [query, subscriptionRef, fetchData]); + + return events; +} + +/** + * Performs a deep comparison between two values to determine if they are equivalent. + * @param a First value to compare + * @param b Second value to compare + * @returns True if the values are equivalent, false otherwise + */ +function deepEqual(a: any, b: any): boolean { + // If the values are strictly equal, return true + if (a === b) return true; + + // If either value is null or not an object, they're not equal + if ( + a === null || + b === null || + typeof a !== "object" || + typeof b !== "object" + ) { + return false; + } + + // Handle arrays + if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) return false; + + for (let i = 0; i < a.length; i++) { + if (!deepEqual(a[i], b[i])) return false; + } + + return true; + } + + // Handle Date objects + if (a instanceof Date && b instanceof Date) { + return a.getTime() === b.getTime(); + } + + // Handle regular expressions + if (a instanceof RegExp && b instanceof RegExp) { + return a.toString() === b.toString(); + } + + // Get all keys from both objects + const keysA = Object.keys(a); + const keysB = Object.keys(b); + + // If number of keys is different, objects are not equal + if (keysA.length !== keysB.length) return false; + + // Check if every key in a exists in b and has the same value + return keysA.every( + (key) => + Object.prototype.hasOwnProperty.call(b, key) && + deepEqual(a[key], b[key]) + ); +} + +/** + * Creates a Promise that resolves after the specified time + * @param ms The time to sleep in milliseconds + * @returns A Promise that resolves after the specified time + */ +function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/packages/sdk/src/state/index.ts b/packages/sdk/src/state/index.ts index 4aebd1df..cac146cb 100644 --- a/packages/sdk/src/state/index.ts +++ b/packages/sdk/src/state/index.ts @@ -15,6 +15,7 @@ export interface GameState { entities: Record>; pendingTransactions: Record; setEntities: (entities: ParsedEntity[]) => void; + mergeEntities: (entities: ParsedEntity[]) => void; updateEntity: (entity: Partial>) => void; applyOptimisticUpdate: ( transactionId: string, diff --git a/packages/sdk/src/state/zustand.ts b/packages/sdk/src/state/zustand.ts index 4aaf0524..ac209f1e 100644 --- a/packages/sdk/src/state/zustand.ts +++ b/packages/sdk/src/state/zustand.ts @@ -42,6 +42,66 @@ export function createDojoStoreFactory( }); }); }, + mergeEntities: (entities: ParsedEntity[]) => { + set((state: Draft>) => { + entities.forEach((entity) => { + if (entity.entityId && entity.models) { + const existingEntity = + state.entities[entity.entityId]; + + if (existingEntity) { + // Create new models object without spread + const mergedModels: typeof existingEntity.models = + Object.assign( + {}, + existingEntity.models + ); + + // Iterate through each namespace in the new models + Object.entries(entity.models).forEach( + ([namespace, namespaceModels]) => { + const typedNamespace = + namespace as keyof ParsedEntity["models"]; + if ( + !( + typedNamespace in + mergedModels + ) + ) { + mergedModels[ + typedNamespace as keyof typeof mergedModels + ] = {} as any; + } + + mergedModels[ + typedNamespace as keyof typeof mergedModels + ] = Object.assign( + {}, + mergedModels[ + typedNamespace as keyof typeof mergedModels + ], + namespaceModels + ); + } + ); + + // Update the entity + state.entities[entity.entityId] = { + ...existingEntity, + ...entity, + models: mergedModels, + }; + } else { + // Set new entity + state.entities[entity.entityId] = + entity as WritableDraft< + ParsedEntity + >; + } + } + }); + }); + }, updateEntity: (entity: Partial>) => { set((state: Draft>) => { if (entity.entityId && entity.models) { diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index ab825bd1..03ed5a10 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -432,6 +432,26 @@ export interface SDK { getControllers: ( contract_addresses: string[] ) => Promise; + + /** + * Convert torii clause into EntityKeysClause[]; + * + * @param {query} query - ToriiQueryBuilder + * @returns [ToriiResponse,torii.EntityKeysClause[]] + */ + toriiQueryIntoHashedKeys: ( + query: ToriiQueryBuilder + ) => Promise<[ToriiResponse, torii.EntityKeysClause[]]>; + /** + * Convert torii clause into EntityKeysClause[]; + * + * @param {query} query - ToriiQueryBuilder + * @returns [ToriiResponse,torii.EntityKeysClause[]] + */ + toriiEventMessagesQueryIntoHashedKeys: ( + query: ToriiQueryBuilder, + historical: H + ) => Promise<[ToriiResponse, torii.EntityKeysClause[]]>; } /** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a27ea0cc..eed0f530 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,7 +132,7 @@ importers: version: 3.0.11 bun-types: specifier: latest - version: 1.2.2 + version: 1.2.4 graphql: specifier: ^16.9.0 version: 16.10.0 @@ -917,10 +917,10 @@ importers: specifier: ^10.1.1 version: 10.1.1 react: - specifier: ^18.3.1 + specifier: 'catalog:' version: 18.3.1 react-dom: - specifier: ^18.3.1 + specifier: 'catalog:' version: 18.3.1(react@18.3.1) starknet: specifier: 'catalog:' @@ -1042,7 +1042,7 @@ importers: version: 2.1.1 drizzle-orm: specifier: ^0.38.3 - version: 0.38.3(@libsql/client@0.14.0)(@types/react@18.3.18)(bun-types@1.2.2)(react@18.3.1) + version: 0.38.3(@libsql/client@0.14.0)(@types/react@18.3.18)(bun-types@1.2.4)(react@18.3.1) lucide-react: specifier: ^0.469.0 version: 0.469.0(react@18.3.1) @@ -1691,9 +1691,12 @@ importers: '@dojoengine/torii-client': specifier: workspace:* version: link:../torii-client + '@dojoengine/utils': + specifier: workspace:* + version: link:../utils '@tanstack/react-query': specifier: ^5.62.16 - version: 5.62.16(react@18.3.1) + version: 5.66.9(react@18.3.1) '@types/react': specifier: 'catalog:' version: 18.3.18 @@ -1713,15 +1716,15 @@ importers: specifier: 'catalog:' version: 6.21.0(encoding@0.1.13) zustand: - specifier: ^4.5.5 - version: 4.5.5(@types/react@18.3.18)(immer@10.1.1)(react@18.3.1) + specifier: ^4.5.6 + version: 4.5.6(@types/react@18.3.18)(immer@10.1.1)(react@18.3.1) devDependencies: '@rollup/plugin-commonjs': - specifier: ^28.0.0 + specifier: ^28.0.2 version: 28.0.2(rollup@4.34.8) '@vitest/coverage-v8': - specifier: ^1.6.0 - version: 1.6.0(vitest@1.6.0(@types/node@22.13.1)(jsdom@24.1.3)(lightningcss@1.29.1)(terser@5.39.0)) + specifier: ^1.6.1 + version: 1.6.1(vitest@1.6.1(@types/node@22.13.1)(jsdom@24.1.3)(lightningcss@1.29.1)(terser@5.39.0)) benchmark: specifier: ^2.1.4 version: 2.1.4 @@ -1735,20 +1738,20 @@ importers: specifier: ^2.8.8 version: 2.8.8 tsup: - specifier: ^8.3.0 - version: 8.3.5(@swc/core@1.10.18(@swc/helpers@0.5.5))(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.7.0) + specifier: ^8.4.0 + version: 8.4.0(@swc/core@1.10.18(@swc/helpers@0.5.5))(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) typescript: - specifier: ^5.6.2 - version: 5.7.2 + specifier: ^5.7.3 + version: 5.7.3 vite: specifier: ^3.2.11 version: 3.2.11(@types/node@22.13.1)(terser@5.39.0) vite-plugin-wasm: - specifier: ^3.3.0 + specifier: ^3.4.1 version: 3.4.1(vite@3.2.11(@types/node@22.13.1)(terser@5.39.0)) vitest: - specifier: ^1.6.0 - version: 1.6.0(@types/node@22.13.1)(jsdom@24.1.3)(lightningcss@1.29.1)(terser@5.39.0) + specifier: ^1.6.1 + version: 1.6.1(@types/node@22.13.1)(jsdom@24.1.3)(lightningcss@1.29.1)(terser@5.39.0) packages/state: dependencies: @@ -2829,6 +2832,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.25.0': + resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.17.19': resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} engines: {node: '>=12'} @@ -2865,6 +2874,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.25.0': + resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.15.18': resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} engines: {node: '>=12'} @@ -2907,6 +2922,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.25.0': + resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.17.19': resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} engines: {node: '>=12'} @@ -2943,6 +2964,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.25.0': + resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.17.19': resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} engines: {node: '>=12'} @@ -2979,6 +3006,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.25.0': + resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.17.19': resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} engines: {node: '>=12'} @@ -3015,6 +3048,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.25.0': + resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.17.19': resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} engines: {node: '>=12'} @@ -3051,6 +3090,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.25.0': + resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.17.19': resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} engines: {node: '>=12'} @@ -3087,6 +3132,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.0': + resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.17.19': resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} engines: {node: '>=12'} @@ -3123,6 +3174,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.25.0': + resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.17.19': resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} engines: {node: '>=12'} @@ -3159,6 +3216,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.25.0': + resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.17.19': resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} engines: {node: '>=12'} @@ -3195,6 +3258,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.25.0': + resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.15.18': resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} engines: {node: '>=12'} @@ -3237,6 +3306,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.25.0': + resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.17.19': resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} engines: {node: '>=12'} @@ -3273,6 +3348,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.25.0': + resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.17.19': resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} engines: {node: '>=12'} @@ -3309,6 +3390,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.25.0': + resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.17.19': resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} engines: {node: '>=12'} @@ -3345,6 +3432,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.25.0': + resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.17.19': resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} engines: {node: '>=12'} @@ -3381,6 +3474,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.25.0': + resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.17.19': resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} engines: {node: '>=12'} @@ -3417,12 +3516,24 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.25.0': + resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.24.2': resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.25.0': + resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.17.19': resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} engines: {node: '>=12'} @@ -3459,6 +3570,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.0': + resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.23.1': resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} engines: {node: '>=18'} @@ -3471,6 +3588,12 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.25.0': + resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.17.19': resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} engines: {node: '>=12'} @@ -3507,6 +3630,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.0': + resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.17.19': resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} engines: {node: '>=12'} @@ -3543,6 +3672,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.25.0': + resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.17.19': resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} engines: {node: '>=12'} @@ -3579,6 +3714,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.25.0': + resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.17.19': resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} engines: {node: '>=12'} @@ -3615,6 +3756,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.25.0': + resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.17.19': resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} engines: {node: '>=12'} @@ -3651,6 +3798,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.25.0': + resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6918,27 +7071,19 @@ packages: resolution: {integrity: sha512-xFdpGJqwSLUJW5TYRNjRO5T41KjGkJeHWyhANZsNJ1KDm7uCVNkfLxNXeCI1XhIFbpzJmk13vo/mY0WJDe0A5g==} engines: {node: '>=12'} - '@tanstack/query-core@5.62.16': - resolution: {integrity: sha512-9Sgft7Qavcd+sN0V25xVyo0nfmcZXBuODy3FVG7BMWTg1HMLm8wwG5tNlLlmSic1u7l1v786oavn+STiFaPH2g==} - '@tanstack/query-core@5.64.1': resolution: {integrity: sha512-978Wx4Wl4UJZbmvU/rkaM9cQtXXrbhK0lsz/UZhYIbyKYA8E4LdomTwyh2GHZ4oU0BKKoDH4YlKk2VscCUgNmg==} '@tanstack/query-core@5.66.4': resolution: {integrity: sha512-skM/gzNX4shPkqmdTCSoHtJAPMTtmIJNS0hE+xwTTUVYwezArCT34NMermABmBVUg5Ls5aiUXEDXfqwR1oVkcA==} - '@tanstack/react-query@5.62.16': - resolution: {integrity: sha512-XJIZNj65d2IdvU8VBESmrPakfIm6FSdHDzrS1dPrAwmq3ZX+9riMh/ZfbNQHAWnhrgmq7KoXpgZSRyXnqMYT9A==} - peerDependencies: - react: ^18 || ^19 - '@tanstack/react-query@5.64.1': resolution: {integrity: sha512-vW5ggHpIO2Yjj44b4sB+Fd3cdnlMJppXRBJkEHvld6FXh3j5dwWJoQo7mGtKI2RbSFyiyu/PhGAy0+Vv5ev9Eg==} peerDependencies: react: ^18 || ^19 - '@tanstack/react-query@5.66.8': - resolution: {integrity: sha512-LqYHYArmM7ycyT1I/Txc/n6KzI8S/hBFw2SQ9Uj1GpbZ89AvZLEvetquiQEHkZ5rFEm+iVNpZ6zYjTiPmJ9N5Q==} + '@tanstack/react-query@5.66.9': + resolution: {integrity: sha512-NRI02PHJsP5y2gAuWKP+awamTIBFBSKMnO6UVzi03GTclmHHHInH5UzVgzi5tpu4+FmGfsdT7Umqegobtsp23A==} peerDependencies: react: ^18 || ^19 @@ -7623,12 +7768,20 @@ packages: peerDependencies: vitest: 1.6.0 + '@vitest/coverage-v8@1.6.1': + resolution: {integrity: sha512-6YeRZwuO4oTGKxD3bijok756oktHSIm3eczVVzNe3scqzuhLwltIF3S9ZL/vwOVIpURmU6SnZhziXXAfw8/Qlw==} + peerDependencies: + vitest: 1.6.1 + '@vitest/expect@0.34.7': resolution: {integrity: sha512-G9iEtwrD6ZQ4MVHZufif9Iqz3eLtuwBBNx971fNAGPaugM7ftAWjQN+ob2zWhtzURp8RK3zGXOxVb01mFo3zAQ==} '@vitest/expect@1.6.0': resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} + '@vitest/expect@1.6.1': + resolution: {integrity: sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==} + '@vitest/expect@2.1.8': resolution: {integrity: sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==} @@ -7649,12 +7802,18 @@ packages: '@vitest/runner@1.6.0': resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} + '@vitest/runner@1.6.1': + resolution: {integrity: sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==} + '@vitest/runner@2.1.8': resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==} '@vitest/snapshot@1.6.0': resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} + '@vitest/snapshot@1.6.1': + resolution: {integrity: sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==} + '@vitest/snapshot@2.1.8': resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==} @@ -7664,6 +7823,9 @@ packages: '@vitest/spy@1.6.0': resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + '@vitest/spy@1.6.1': + resolution: {integrity: sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==} + '@vitest/spy@2.1.8': resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==} @@ -7673,6 +7835,9 @@ packages: '@vitest/utils@1.6.0': resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + '@vitest/utils@1.6.1': + resolution: {integrity: sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==} + '@vitest/utils@2.1.8': resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==} @@ -8254,8 +8419,8 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - bun-types@1.2.2: - resolution: {integrity: sha512-RCbMH5elr9gjgDGDhkTTugA21XtJAy/9jkKe/G3WR2q17VPGhcquf9Sir6uay9iW+7P/BV0CAHA1XlHXMAVKHg==} + bun-types@1.2.4: + resolution: {integrity: sha512-nDPymR207ZZEoWD4AavvEaa/KZe/qlrbMSchqpQwovPZCKc7pwMoENjEtHgMKaAjJhy+x6vfqSBA1QU3bJgs0Q==} bundle-require@5.1.0: resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} @@ -8587,6 +8752,10 @@ packages: resolution: {integrity: sha512-Qil5KwghMzlqd51UXM0b6fyaGHtOC22scxrwrz4A2882LyUMwQjnvaedN1HAeXzphspQ6CpHkzMAWxBTUruDLg==} engines: {node: ^14.18.0 || >=16.10.0} + consola@3.4.0: + resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + engines: {node: ^14.18.0 || >=16.10.0} + console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} @@ -9430,6 +9599,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.25.0: + resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -9773,6 +9947,14 @@ packages: picomatch: optional: true + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} @@ -11848,8 +12030,8 @@ packages: ml-tree-similarity@1.0.0: resolution: {integrity: sha512-XJUyYqjSuUQkNQHMscr6tcjldsOoAekxADTplt40QKfwW6nd++1wHWV9AArl0Zvw/TIHgNaZZNvr8QGvE8wLRg==} - mlly@1.7.3: - resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==} + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} mobx@6.13.5: resolution: {integrity: sha512-/HTWzW2s8J1Gqt+WmUj5Y0mddZk+LInejADc79NJadrWla3rHzmRHki/mnEUH1AvOmbNTZ1BRbKxr8DSgfdjMA==} @@ -12439,6 +12621,9 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} @@ -12504,8 +12689,8 @@ packages: resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} engines: {node: '>=10'} - pkg-types@1.2.1: - resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} platform@1.3.6: resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} @@ -12965,9 +13150,9 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - readdirp@4.0.2: - resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} - engines: {node: '>= 14.16.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} recast@0.23.9: resolution: {integrity: sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==} @@ -13874,10 +14059,17 @@ packages: tinyexec@0.3.1: resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyglobby@0.2.10: resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + tinypool@0.8.4: resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} @@ -14034,6 +14226,25 @@ packages: typescript: optional: true + tsup@8.4.0: + resolution: {integrity: sha512-b+eZbPCjz10fRryaAA7C8xlIHnf8VnsaRqydheLIqwG/Mcpfk8Z5zp3HayX7GaTygkigHl5cBUs+IhcySiIexQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + tsutils@3.21.0: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -14450,6 +14661,11 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true + vite-node@1.6.1: + resolution: {integrity: sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite-node@2.1.8: resolution: {integrity: sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -14811,6 +15027,31 @@ packages: jsdom: optional: true + vitest@1.6.1: + resolution: {integrity: sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.1 + '@vitest/ui': 1.6.1 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vitest@2.1.8: resolution: {integrity: sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -17232,6 +17473,9 @@ snapshots: '@esbuild/aix-ppc64@0.24.2': optional: true + '@esbuild/aix-ppc64@0.25.0': + optional: true + '@esbuild/android-arm64@0.17.19': optional: true @@ -17250,6 +17494,9 @@ snapshots: '@esbuild/android-arm64@0.24.2': optional: true + '@esbuild/android-arm64@0.25.0': + optional: true + '@esbuild/android-arm@0.15.18': optional: true @@ -17271,6 +17518,9 @@ snapshots: '@esbuild/android-arm@0.24.2': optional: true + '@esbuild/android-arm@0.25.0': + optional: true + '@esbuild/android-x64@0.17.19': optional: true @@ -17289,6 +17539,9 @@ snapshots: '@esbuild/android-x64@0.24.2': optional: true + '@esbuild/android-x64@0.25.0': + optional: true + '@esbuild/darwin-arm64@0.17.19': optional: true @@ -17307,6 +17560,9 @@ snapshots: '@esbuild/darwin-arm64@0.24.2': optional: true + '@esbuild/darwin-arm64@0.25.0': + optional: true + '@esbuild/darwin-x64@0.17.19': optional: true @@ -17325,6 +17581,9 @@ snapshots: '@esbuild/darwin-x64@0.24.2': optional: true + '@esbuild/darwin-x64@0.25.0': + optional: true + '@esbuild/freebsd-arm64@0.17.19': optional: true @@ -17343,6 +17602,9 @@ snapshots: '@esbuild/freebsd-arm64@0.24.2': optional: true + '@esbuild/freebsd-arm64@0.25.0': + optional: true + '@esbuild/freebsd-x64@0.17.19': optional: true @@ -17361,6 +17623,9 @@ snapshots: '@esbuild/freebsd-x64@0.24.2': optional: true + '@esbuild/freebsd-x64@0.25.0': + optional: true + '@esbuild/linux-arm64@0.17.19': optional: true @@ -17379,6 +17644,9 @@ snapshots: '@esbuild/linux-arm64@0.24.2': optional: true + '@esbuild/linux-arm64@0.25.0': + optional: true + '@esbuild/linux-arm@0.17.19': optional: true @@ -17397,6 +17665,9 @@ snapshots: '@esbuild/linux-arm@0.24.2': optional: true + '@esbuild/linux-arm@0.25.0': + optional: true + '@esbuild/linux-ia32@0.17.19': optional: true @@ -17415,6 +17686,9 @@ snapshots: '@esbuild/linux-ia32@0.24.2': optional: true + '@esbuild/linux-ia32@0.25.0': + optional: true + '@esbuild/linux-loong64@0.15.18': optional: true @@ -17436,6 +17710,9 @@ snapshots: '@esbuild/linux-loong64@0.24.2': optional: true + '@esbuild/linux-loong64@0.25.0': + optional: true + '@esbuild/linux-mips64el@0.17.19': optional: true @@ -17454,6 +17731,9 @@ snapshots: '@esbuild/linux-mips64el@0.24.2': optional: true + '@esbuild/linux-mips64el@0.25.0': + optional: true + '@esbuild/linux-ppc64@0.17.19': optional: true @@ -17472,6 +17752,9 @@ snapshots: '@esbuild/linux-ppc64@0.24.2': optional: true + '@esbuild/linux-ppc64@0.25.0': + optional: true + '@esbuild/linux-riscv64@0.17.19': optional: true @@ -17490,6 +17773,9 @@ snapshots: '@esbuild/linux-riscv64@0.24.2': optional: true + '@esbuild/linux-riscv64@0.25.0': + optional: true + '@esbuild/linux-s390x@0.17.19': optional: true @@ -17508,6 +17794,9 @@ snapshots: '@esbuild/linux-s390x@0.24.2': optional: true + '@esbuild/linux-s390x@0.25.0': + optional: true + '@esbuild/linux-x64@0.17.19': optional: true @@ -17526,9 +17815,15 @@ snapshots: '@esbuild/linux-x64@0.24.2': optional: true + '@esbuild/linux-x64@0.25.0': + optional: true + '@esbuild/netbsd-arm64@0.24.2': optional: true + '@esbuild/netbsd-arm64@0.25.0': + optional: true + '@esbuild/netbsd-x64@0.17.19': optional: true @@ -17547,12 +17842,18 @@ snapshots: '@esbuild/netbsd-x64@0.24.2': optional: true + '@esbuild/netbsd-x64@0.25.0': + optional: true + '@esbuild/openbsd-arm64@0.23.1': optional: true '@esbuild/openbsd-arm64@0.24.2': optional: true + '@esbuild/openbsd-arm64@0.25.0': + optional: true + '@esbuild/openbsd-x64@0.17.19': optional: true @@ -17571,6 +17872,9 @@ snapshots: '@esbuild/openbsd-x64@0.24.2': optional: true + '@esbuild/openbsd-x64@0.25.0': + optional: true + '@esbuild/sunos-x64@0.17.19': optional: true @@ -17589,6 +17893,9 @@ snapshots: '@esbuild/sunos-x64@0.24.2': optional: true + '@esbuild/sunos-x64@0.25.0': + optional: true + '@esbuild/win32-arm64@0.17.19': optional: true @@ -17607,6 +17914,9 @@ snapshots: '@esbuild/win32-arm64@0.24.2': optional: true + '@esbuild/win32-arm64@0.25.0': + optional: true + '@esbuild/win32-ia32@0.17.19': optional: true @@ -17625,6 +17935,9 @@ snapshots: '@esbuild/win32-ia32@0.24.2': optional: true + '@esbuild/win32-ia32@0.25.0': + optional: true + '@esbuild/win32-x64@0.17.19': optional: true @@ -17643,6 +17956,9 @@ snapshots: '@esbuild/win32-x64@0.24.2': optional: true + '@esbuild/win32-x64@0.25.0': + optional: true + '@eslint-community/eslint-utils@4.4.1(eslint@8.57.1)': dependencies: eslint: 8.57.1 @@ -21058,7 +21374,7 @@ snapshots: dependencies: '@starknet-io/types-js': 0.7.10 '@starknet-react/chains': 3.1.0 - '@tanstack/react-query': 5.66.8(react@18.3.1) + '@tanstack/react-query': 5.66.9(react@18.3.1) eventemitter3: 5.0.1 get-starknet-core: 4.0.0 react: 18.3.1 @@ -21074,7 +21390,7 @@ snapshots: dependencies: '@starknet-io/types-js': 0.7.10 '@starknet-react/chains': 3.1.0 - '@tanstack/react-query': 5.66.8(react@18.3.1) + '@tanstack/react-query': 5.66.9(react@18.3.1) eventemitter3: 5.0.1 get-starknet-core: 4.0.0 react: 18.3.1 @@ -21090,7 +21406,7 @@ snapshots: dependencies: '@starknet-io/types-js': 0.7.10 '@starknet-react/chains': 3.1.0 - '@tanstack/react-query': 5.66.8(react@18.3.1) + '@tanstack/react-query': 5.66.9(react@18.3.1) eventemitter3: 5.0.1 get-starknet-core: 4.0.0 react: 18.3.1 @@ -21106,7 +21422,7 @@ snapshots: dependencies: '@starknet-io/types-js': 0.7.10 '@starknet-react/chains': 3.1.0 - '@tanstack/react-query': 5.66.8(react@19.0.0) + '@tanstack/react-query': 5.66.9(react@19.0.0) eventemitter3: 5.0.1 get-starknet-core: 4.0.0 react: 19.0.0 @@ -22008,28 +22324,21 @@ snapshots: '@tanstack/history@1.97.0': {} - '@tanstack/query-core@5.62.16': {} - '@tanstack/query-core@5.64.1': {} '@tanstack/query-core@5.66.4': {} - '@tanstack/react-query@5.62.16(react@18.3.1)': - dependencies: - '@tanstack/query-core': 5.62.16 - react: 18.3.1 - '@tanstack/react-query@5.64.1(react@18.3.1)': dependencies: '@tanstack/query-core': 5.64.1 react: 18.3.1 - '@tanstack/react-query@5.66.8(react@18.3.1)': + '@tanstack/react-query@5.66.9(react@18.3.1)': dependencies: '@tanstack/query-core': 5.66.4 react: 18.3.1 - '@tanstack/react-query@5.66.8(react@19.0.0)': + '@tanstack/react-query@5.66.9(react@19.0.0)': dependencies: '@tanstack/query-core': 5.66.4 react: 19.0.0 @@ -23062,6 +23371,25 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitest/coverage-v8@1.6.1(vitest@1.6.1(@types/node@22.13.1)(jsdom@24.1.3)(lightningcss@1.29.1)(terser@5.39.0))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.4.0 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + magicast: 0.3.5 + picocolors: 1.1.1 + std-env: 3.8.0 + strip-literal: 2.1.1 + test-exclude: 6.0.0 + vitest: 1.6.1(@types/node@22.13.1)(jsdom@24.1.3)(lightningcss@1.29.1)(terser@5.39.0) + transitivePeerDependencies: + - supports-color + '@vitest/expect@0.34.7': dependencies: '@vitest/spy': 0.34.7 @@ -23074,6 +23402,12 @@ snapshots: '@vitest/utils': 1.6.0 chai: 4.5.0 + '@vitest/expect@1.6.1': + dependencies: + '@vitest/spy': 1.6.1 + '@vitest/utils': 1.6.1 + chai: 4.5.0 + '@vitest/expect@2.1.8': dependencies: '@vitest/spy': 2.1.8 @@ -23099,6 +23433,12 @@ snapshots: p-limit: 5.0.0 pathe: 1.1.2 + '@vitest/runner@1.6.1': + dependencies: + '@vitest/utils': 1.6.1 + p-limit: 5.0.0 + pathe: 1.1.2 + '@vitest/runner@2.1.8': dependencies: '@vitest/utils': 2.1.8 @@ -23110,6 +23450,12 @@ snapshots: pathe: 1.1.2 pretty-format: 29.7.0 + '@vitest/snapshot@1.6.1': + dependencies: + magic-string: 0.30.17 + pathe: 1.1.2 + pretty-format: 29.7.0 + '@vitest/snapshot@2.1.8': dependencies: '@vitest/pretty-format': 2.1.8 @@ -23124,6 +23470,10 @@ snapshots: dependencies: tinyspy: 2.2.1 + '@vitest/spy@1.6.1': + dependencies: + tinyspy: 2.2.1 + '@vitest/spy@2.1.8': dependencies: tinyspy: 3.0.2 @@ -23141,6 +23491,13 @@ snapshots: loupe: 2.3.7 pretty-format: 29.7.0 + '@vitest/utils@1.6.1': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + '@vitest/utils@2.1.8': dependencies: '@vitest/pretty-format': 2.1.8 @@ -23886,7 +24243,7 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - bun-types@1.2.2: + bun-types@1.2.4: dependencies: '@types/node': 20.17.10 '@types/ws': 8.5.13 @@ -23896,6 +24253,11 @@ snapshots: esbuild: 0.24.2 load-tsconfig: 0.2.5 + bundle-require@5.1.0(esbuild@0.25.0): + dependencies: + esbuild: 0.25.0 + load-tsconfig: 0.2.5 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 @@ -24107,7 +24469,7 @@ snapshots: chokidar@4.0.3: dependencies: - readdirp: 4.0.2 + readdirp: 4.1.2 chownr@1.1.4: {} @@ -24119,7 +24481,7 @@ snapshots: citty@0.1.6: dependencies: - consola: 3.3.3 + consola: 3.4.0 class-variance-authority@0.7.1: dependencies: @@ -24280,6 +24642,8 @@ snapshots: consola@3.3.3: {} + consola@3.4.0: {} + console-control-strings@1.1.0: {} constant-case@3.0.4: @@ -24750,11 +25114,11 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.38.3(@libsql/client@0.14.0)(@types/react@18.3.18)(bun-types@1.2.2)(react@18.3.1): + drizzle-orm@0.38.3(@libsql/client@0.14.0)(@types/react@18.3.18)(bun-types@1.2.4)(react@18.3.1): optionalDependencies: '@libsql/client': 0.14.0 '@types/react': 18.3.18 - bun-types: 1.2.2 + bun-types: 1.2.4 react: 18.3.1 dset@3.1.4: {} @@ -25223,6 +25587,34 @@ snapshots: '@esbuild/win32-ia32': 0.24.2 '@esbuild/win32-x64': 0.24.2 + esbuild@0.25.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.0 + '@esbuild/android-arm': 0.25.0 + '@esbuild/android-arm64': 0.25.0 + '@esbuild/android-x64': 0.25.0 + '@esbuild/darwin-arm64': 0.25.0 + '@esbuild/darwin-x64': 0.25.0 + '@esbuild/freebsd-arm64': 0.25.0 + '@esbuild/freebsd-x64': 0.25.0 + '@esbuild/linux-arm': 0.25.0 + '@esbuild/linux-arm64': 0.25.0 + '@esbuild/linux-ia32': 0.25.0 + '@esbuild/linux-loong64': 0.25.0 + '@esbuild/linux-mips64el': 0.25.0 + '@esbuild/linux-ppc64': 0.25.0 + '@esbuild/linux-riscv64': 0.25.0 + '@esbuild/linux-s390x': 0.25.0 + '@esbuild/linux-x64': 0.25.0 + '@esbuild/netbsd-arm64': 0.25.0 + '@esbuild/netbsd-x64': 0.25.0 + '@esbuild/openbsd-arm64': 0.25.0 + '@esbuild/openbsd-x64': 0.25.0 + '@esbuild/sunos-x64': 0.25.0 + '@esbuild/win32-arm64': 0.25.0 + '@esbuild/win32-ia32': 0.25.0 + '@esbuild/win32-x64': 0.25.0 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -25806,6 +26198,10 @@ snapshots: optionalDependencies: picomatch: 4.0.2 + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 @@ -26103,7 +26499,7 @@ snapshots: giget@1.2.3: dependencies: citty: 0.1.6 - consola: 3.3.3 + consola: 3.4.0 defu: 6.1.4 node-fetch-native: 1.6.4 nypm: 0.3.12 @@ -27361,8 +27757,8 @@ snapshots: local-pkg@0.5.1: dependencies: - mlly: 1.7.3 - pkg-types: 1.2.1 + mlly: 1.7.4 + pkg-types: 1.3.1 locate-character@3.0.0: {} @@ -27499,8 +27895,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.26.5 - '@babel/types': 7.26.5 + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 source-map-js: 1.2.1 make-dir@2.1.0: @@ -27791,11 +28187,11 @@ snapshots: binary-search: 1.3.6 num-sort: 2.1.0 - mlly@1.7.3: + mlly@1.7.4: dependencies: acorn: 8.14.0 - pathe: 1.1.2 - pkg-types: 1.2.1 + pathe: 2.0.3 + pkg-types: 1.3.1 ufo: 1.5.4 mobx@6.13.5: {} @@ -28083,10 +28479,10 @@ snapshots: nypm@0.3.12: dependencies: citty: 0.1.6 - consola: 3.3.3 + consola: 3.4.0 execa: 8.0.1 pathe: 1.1.2 - pkg-types: 1.2.1 + pkg-types: 1.3.1 ufo: 1.5.4 object-assign@4.1.1: {} @@ -28488,6 +28884,8 @@ snapshots: pathe@1.1.2: {} + pathe@2.0.3: {} + pathval@1.1.1: {} pathval@2.0.0: {} @@ -28542,11 +28940,11 @@ snapshots: dependencies: find-up: 5.0.0 - pkg-types@1.2.1: + pkg-types@1.3.1: dependencies: confbox: 0.1.8 - mlly: 1.7.3 - pathe: 1.1.2 + mlly: 1.7.4 + pathe: 2.0.3 platform@1.3.6: {} @@ -29021,7 +29419,7 @@ snapshots: dependencies: picomatch: 2.3.1 - readdirp@4.0.2: {} + readdirp@4.1.2: {} recast@0.23.9: dependencies: @@ -30191,11 +30589,18 @@ snapshots: tinyexec@0.3.1: {} + tinyexec@0.3.2: {} + tinyglobby@0.2.10: dependencies: fdir: 6.4.2(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + tinypool@0.8.4: {} tinypool@1.0.2: {} @@ -30362,6 +30767,34 @@ snapshots: - tsx - yaml + tsup@8.4.0(@swc/core@1.10.18(@swc/helpers@0.5.5))(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0): + dependencies: + bundle-require: 5.1.0(esbuild@0.25.0) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.0 + debug: 4.4.0 + esbuild: 0.25.0 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.2)(yaml@2.7.0) + resolve-from: 5.0.0 + rollup: 4.34.8 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.12 + tree-kill: 1.2.2 + optionalDependencies: + '@swc/core': 1.10.18(@swc/helpers@0.5.5) + postcss: 8.5.3 + typescript: 5.7.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + tsutils@3.21.0(typescript@5.7.2): dependencies: tslib: 1.14.1 @@ -30877,6 +31310,24 @@ snapshots: - supports-color - terser + vite-node@1.6.1(@types/node@22.13.1)(lightningcss@1.29.1)(terser@5.39.0): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + pathe: 1.1.2 + picocolors: 1.1.1 + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(terser@5.39.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-node@2.1.8(@types/node@22.13.1)(lightningcss@1.29.1)(terser@5.39.0): dependencies: cac: 6.7.14 @@ -31294,6 +31745,41 @@ snapshots: - supports-color - terser + vitest@1.6.1(@types/node@22.13.1)(jsdom@24.1.3)(lightningcss@1.29.1)(terser@5.39.0): + dependencies: + '@vitest/expect': 1.6.1 + '@vitest/runner': 1.6.1 + '@vitest/snapshot': 1.6.1 + '@vitest/spy': 1.6.1 + '@vitest/utils': 1.6.1 + acorn-walk: 8.3.4 + chai: 4.5.0 + debug: 4.4.0 + execa: 8.0.1 + local-pkg: 0.5.1 + magic-string: 0.30.17 + pathe: 1.1.2 + picocolors: 1.1.1 + std-env: 3.8.0 + strip-literal: 2.1.1 + tinybench: 2.9.0 + tinypool: 0.8.4 + vite: 5.4.14(@types/node@22.13.1)(lightningcss@1.29.1)(terser@5.39.0) + vite-node: 1.6.1(@types/node@22.13.1)(lightningcss@1.29.1)(terser@5.39.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.13.1 + jsdom: 24.1.3 + transitivePeerDependencies: + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vitest@2.1.8(@types/node@22.13.1)(jsdom@24.1.3)(lightningcss@1.29.1)(terser@5.39.0): dependencies: '@vitest/expect': 2.1.8