fix(canvas): refresh sync engine hook dependencies

This commit is contained in:
2026-04-03 21:26:24 +02:00
parent c060c57ad8
commit 5223d3d8d7
6 changed files with 570 additions and 78 deletions

View File

@@ -0,0 +1,173 @@
// @vitest-environment jsdom
import { act, useEffect, useRef, useState } from "react";
import { createRoot, type Root } from "react-dom/client";
import type { Edge as RFEdge, Node as RFNode } from "@xyflow/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import type { Id } from "@/convex/_generated/dataModel";
const mocks = vi.hoisted(() => ({
enqueueCanvasSyncOp: vi.fn(async () => ({ replacedIds: [] as string[] })),
countCanvasSyncOps: vi.fn(async () => 0),
listCanvasSyncOps: vi.fn(async () => []),
mutationMocks: new Map<unknown, ReturnType<typeof vi.fn>>(),
}));
vi.mock("@/convex/_generated/api", () => ({
api: {
nodes: {
move: "nodes.move",
resize: "nodes.resize",
updateData: "nodes.updateData",
create: "nodes.create",
createWithEdgeFromSource: "nodes.createWithEdgeFromSource",
createWithEdgeToTarget: "nodes.createWithEdgeToTarget",
createWithEdgeSplit: "nodes.createWithEdgeSplit",
batchRemove: "nodes.batchRemove",
splitEdgeAtExistingNode: "nodes.splitEdgeAtExistingNode",
},
edges: {
create: "edges.create",
remove: "edges.remove",
},
},
}));
vi.mock("convex/react", () => ({
useConvexConnectionState: () => ({ isWebSocketConnected: true }),
useMutation: (key: unknown) => {
let mutation = mocks.mutationMocks.get(key);
if (!mutation) {
mutation = vi.fn(async () => undefined);
Object.assign(mutation, {
withOptimisticUpdate: () => mutation,
});
mocks.mutationMocks.set(key, mutation);
}
return mutation;
},
}));
vi.mock("@/lib/canvas-op-queue", () => ({
ackCanvasSyncOp: vi.fn(async () => undefined),
countCanvasSyncOps: mocks.countCanvasSyncOps,
dropCanvasSyncOpsByClientRequestIds: vi.fn(async () => []),
dropCanvasSyncOpsByEdgeIds: vi.fn(async () => []),
dropCanvasSyncOpsByNodeIds: vi.fn(async () => []),
dropExpiredCanvasSyncOps: vi.fn(async () => []),
enqueueCanvasSyncOp: mocks.enqueueCanvasSyncOp,
listCanvasSyncOps: mocks.listCanvasSyncOps,
markCanvasSyncOpFailed: vi.fn(async () => undefined),
remapCanvasSyncNodeId: vi.fn(async () => 0),
}));
vi.mock("@/lib/canvas-local-persistence", () => ({
dropCanvasOpsByClientRequestIds: vi.fn(() => []),
dropCanvasOpsByEdgeIds: vi.fn(() => []),
dropCanvasOpsByNodeIds: vi.fn(() => []),
enqueueCanvasOp: vi.fn(() => "op-1"),
remapCanvasOpNodeId: vi.fn(() => 0),
resolveCanvasOp: vi.fn(() => undefined),
resolveCanvasOps: vi.fn(() => undefined),
}));
vi.mock("@/lib/toast", () => ({
toast: {
info: vi.fn(),
warning: vi.fn(),
},
}));
import { useCanvasSyncEngine } from "@/components/canvas/use-canvas-sync-engine";
const asCanvasId = (id: string): Id<"canvases"> => id as Id<"canvases">;
const asNodeId = (id: string): Id<"nodes"> => id as Id<"nodes">;
const latestHookValueRef: {
current: ReturnType<typeof useCanvasSyncEngine> | null;
} = { current: null };
(globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
function HookHarness({ canvasId }: { canvasId: Id<"canvases"> }) {
const [, setNodes] = useState<RFNode[]>([]);
const [edges, setEdges] = useState<RFEdge[]>([]);
const edgesRef = useRef<RFEdge[]>(edges);
const deletingNodeIds = useRef(new Set<string>());
const [, setAssetBrowserTargetNodeId] = useState<string | null>(null);
const [, setEdgeSyncNonce] = useState(0);
useEffect(() => {
edgesRef.current = edges;
}, [edges]);
const hookValue = useCanvasSyncEngine({
canvasId,
setNodes,
setEdges,
edgesRef,
setAssetBrowserTargetNodeId,
setEdgeSyncNonce,
deletingNodeIds,
});
useEffect(() => {
latestHookValueRef.current = hookValue;
}, [hookValue]);
return null;
}
describe("useCanvasSyncEngine hook wiring", () => {
let container: HTMLDivElement | null = null;
let root: Root | null = null;
afterEach(async () => {
latestHookValueRef.current = null;
mocks.mutationMocks.clear();
vi.clearAllMocks();
if (root) {
await act(async () => {
root?.unmount();
});
}
container?.remove();
root = null;
container = null;
});
it("uses the latest canvas id after rerendering the mounted hook", async () => {
container = document.createElement("div");
document.body.appendChild(container);
root = createRoot(container);
await act(async () => {
root?.render(<HookHarness canvasId={asCanvasId("canvas-1")} />);
});
await act(async () => {
root?.render(<HookHarness canvasId={asCanvasId("canvas-2")} />);
});
await act(async () => {
await latestHookValueRef.current?.actions.resizeNode({
nodeId: asNodeId("node-1"),
width: 480,
height: 320,
});
});
expect(mocks.enqueueCanvasSyncOp).toHaveBeenLastCalledWith(
expect.objectContaining({
canvasId: "canvas-2",
type: "resizeNode",
payload: {
nodeId: "node-1",
width: 480,
height: 320,
},
}),
);
});
});

View File

@@ -14,9 +14,9 @@ describe("useCanvasSyncEngine", () => {
const controller = createCanvasSyncEngineController({
canvasId: asCanvasId("canvas-1"),
isSyncOnline: true,
enqueueSyncMutation,
runBatchRemoveNodes,
runSplitEdgeAtExistingNode,
getEnqueueSyncMutation: () => enqueueSyncMutation,
getRunBatchRemoveNodes: () => runBatchRemoveNodes,
getRunSplitEdgeAtExistingNode: () => runSplitEdgeAtExistingNode,
});
controller.pendingMoveAfterCreateRef.current.set("req-1", {
@@ -48,9 +48,9 @@ describe("useCanvasSyncEngine", () => {
const controller = createCanvasSyncEngineController({
canvasId: asCanvasId("canvas-1"),
isSyncOnline: true,
enqueueSyncMutation,
runBatchRemoveNodes: vi.fn(async () => undefined),
runSplitEdgeAtExistingNode: vi.fn(async () => undefined),
getEnqueueSyncMutation: () => enqueueSyncMutation,
getRunBatchRemoveNodes: () => vi.fn(async () => undefined),
getRunSplitEdgeAtExistingNode: () => vi.fn(async () => undefined),
});
await controller.queueNodeResize({

View File

@@ -51,6 +51,12 @@ type QueueSyncMutation = <TType extends keyof CanvasSyncOpPayloadByType>(
payload: CanvasSyncOpPayloadByType[TType],
) => Promise<void>;
type DynamicValue<T> = T | (() => T);
function resolveDynamicValue<T>(value: DynamicValue<T>): T {
return typeof value === "function" ? (value as () => T)() : value;
}
type RunMoveNodeMutation = (args: {
nodeId: Id<"nodes">;
positionX: number;
@@ -75,16 +81,18 @@ type RunSplitEdgeAtExistingNodeMutation = (args: {
}) => Promise<void>;
type CanvasSyncEngineControllerParams = {
canvasId: Id<"canvases">;
isSyncOnline: boolean | (() => boolean);
enqueueSyncMutation: QueueSyncMutation;
runMoveNodeMutation?: RunMoveNodeMutation;
runBatchRemoveNodes?: RunBatchRemoveNodesMutation;
runSplitEdgeAtExistingNode?: RunSplitEdgeAtExistingNodeMutation;
setAssetBrowserTargetNodeId?: Dispatch<SetStateAction<string | null>>;
setNodes?: Dispatch<SetStateAction<RFNode[]>>;
setEdges?: Dispatch<SetStateAction<RFEdge[]>>;
deletingNodeIds?: MutableRefObject<Set<string>>;
canvasId: DynamicValue<Id<"canvases">>;
isSyncOnline: DynamicValue<boolean>;
getEnqueueSyncMutation: () => QueueSyncMutation;
getRunMoveNodeMutation?: () => RunMoveNodeMutation | undefined;
getRunBatchRemoveNodes?: () => RunBatchRemoveNodesMutation | undefined;
getRunSplitEdgeAtExistingNode?: () => RunSplitEdgeAtExistingNodeMutation | undefined;
getSetAssetBrowserTargetNodeId?: () =>
| Dispatch<SetStateAction<string | null>>
| undefined;
getSetNodes?: () => Dispatch<SetStateAction<RFNode[]>> | undefined;
getSetEdges?: () => Dispatch<SetStateAction<RFEdge[]>> | undefined;
getDeletingNodeIds?: () => MutableRefObject<Set<string>> | undefined;
};
type UseCanvasSyncEngineParams = {
@@ -165,17 +173,17 @@ function summarizeResizePayload(payload: unknown): Record<string, unknown> {
export function createCanvasSyncEngineController({
canvasId,
isSyncOnline,
enqueueSyncMutation,
runMoveNodeMutation,
runBatchRemoveNodes,
runSplitEdgeAtExistingNode,
setAssetBrowserTargetNodeId,
setNodes,
setEdges,
deletingNodeIds,
getEnqueueSyncMutation,
getRunMoveNodeMutation,
getRunBatchRemoveNodes,
getRunSplitEdgeAtExistingNode,
getSetAssetBrowserTargetNodeId,
getSetNodes,
getSetEdges,
getDeletingNodeIds,
}: CanvasSyncEngineControllerParams) {
const getIsSyncOnline = () =>
typeof isSyncOnline === "function" ? isSyncOnline() : isSyncOnline;
const getCanvasId = () => resolveDynamicValue(canvasId);
const getIsSyncOnline = () => resolveDynamicValue(isSyncOnline);
const pendingMoveAfterCreateRef = {
current: new Map<string, { positionX: number; positionY: number }>(),
@@ -206,7 +214,7 @@ export function createCanvasSyncEngineController({
const pendingResize = pendingResizeAfterCreateRef.current.get(clientRequestId);
if (!pendingResize) return;
pendingResizeAfterCreateRef.current.delete(clientRequestId);
await enqueueSyncMutation("resizeNode", {
await getEnqueueSyncMutation()("resizeNode", {
nodeId: realId,
width: pendingResize.width,
height: pendingResize.height,
@@ -220,7 +228,7 @@ export function createCanvasSyncEngineController({
if (!pendingDataAfterCreateRef.current.has(clientRequestId)) return;
const pendingData = pendingDataAfterCreateRef.current.get(clientRequestId);
pendingDataAfterCreateRef.current.delete(clientRequestId);
await enqueueSyncMutation("updateData", {
await getEnqueueSyncMutation()("updateData", {
nodeId: realId,
data: pendingData,
});
@@ -233,7 +241,7 @@ export function createCanvasSyncEngineController({
}): Promise<void> => {
const rawNodeId = args.nodeId as string;
if (!isOptimisticNodeId(rawNodeId) || !getIsSyncOnline()) {
await enqueueSyncMutation("resizeNode", args);
await getEnqueueSyncMutation()("resizeNode", args);
return;
}
@@ -243,7 +251,7 @@ export function createCanvasSyncEngineController({
: undefined;
if (resolvedRealId) {
await enqueueSyncMutation("resizeNode", {
await getEnqueueSyncMutation()("resizeNode", {
nodeId: resolvedRealId,
width: args.width,
height: args.height,
@@ -265,7 +273,7 @@ export function createCanvasSyncEngineController({
}): Promise<void> => {
const rawNodeId = args.nodeId as string;
if (!isOptimisticNodeId(rawNodeId) || !getIsSyncOnline()) {
await enqueueSyncMutation("updateData", args);
await getEnqueueSyncMutation()("updateData", args);
return;
}
@@ -275,7 +283,7 @@ export function createCanvasSyncEngineController({
: undefined;
if (resolvedRealId) {
await enqueueSyncMutation("updateData", {
await getEnqueueSyncMutation()("updateData", {
nodeId: resolvedRealId,
data: args.data,
});
@@ -308,6 +316,9 @@ export function createCanvasSyncEngineController({
resolvedRealIdByClientRequestRef.current.delete(clientRequestId);
const realNodeId = realId as string;
const deletingNodeIds = getDeletingNodeIds?.();
const setNodes = getSetNodes?.();
const setEdges = getSetEdges?.();
deletingNodeIds?.current.add(realNodeId);
setNodes?.((current) => current.filter((node) => node.id !== realNodeId));
setEdges?.((current) =>
@@ -315,13 +326,15 @@ export function createCanvasSyncEngineController({
(edge) => edge.source !== realNodeId && edge.target !== realNodeId,
),
);
if (runBatchRemoveNodes) {
await runBatchRemoveNodes({ nodeIds: [realId] });
const batchRemoveNodes = getRunBatchRemoveNodes?.();
if (batchRemoveNodes) {
await batchRemoveNodes({ nodeIds: [realId] });
}
return;
}
const optimisticNodeId = `${OPTIMISTIC_NODE_PREFIX}${clientRequestId}`;
const setAssetBrowserTargetNodeId = getSetAssetBrowserTargetNodeId?.();
setAssetBrowserTargetNodeId?.((current) =>
current === optimisticNodeId ? (realId as string) : current,
);
@@ -336,9 +349,10 @@ export function createCanvasSyncEngineController({
pendingMoveAfterCreateRef.current.delete(clientRequestId);
}
resolvedRealIdByClientRequestRef.current.delete(clientRequestId);
if (runSplitEdgeAtExistingNode) {
await runSplitEdgeAtExistingNode({
canvasId,
const splitEdgeAtExistingNode = getRunSplitEdgeAtExistingNode?.();
if (splitEdgeAtExistingNode) {
await splitEdgeAtExistingNode({
canvasId: getCanvasId(),
splitEdgeId: splitPayload.intersectedEdgeId,
middleNodeId: realId,
splitSourceHandle: splitPayload.intersectedSourceHandle,
@@ -361,14 +375,15 @@ export function createCanvasSyncEngineController({
x: pendingMove.positionX,
y: pendingMove.positionY,
});
if (runMoveNodeMutation) {
await runMoveNodeMutation({
const moveNodeMutation = getRunMoveNodeMutation?.();
if (moveNodeMutation) {
await moveNodeMutation({
nodeId: realId,
positionX: pendingMove.positionX,
positionY: pendingMove.positionY,
});
} else {
await enqueueSyncMutation("moveNode", {
await getEnqueueSyncMutation()("moveNode", {
nodeId: realId,
positionX: pendingMove.positionX,
positionY: pendingMove.positionY,
@@ -396,9 +411,10 @@ export function createCanvasSyncEngineController({
const splitPayload = pendingEdgeSplitByClientRequestRef.current.get(clientRequestId);
if (splitPayload) {
pendingEdgeSplitByClientRequestRef.current.delete(clientRequestId);
if (runSplitEdgeAtExistingNode) {
await runSplitEdgeAtExistingNode({
canvasId,
const splitEdgeAtExistingNode = getRunSplitEdgeAtExistingNode?.();
if (splitEdgeAtExistingNode) {
await splitEdgeAtExistingNode({
canvasId: getCanvasId(),
splitEdgeId: splitPayload.intersectedEdgeId,
middleNodeId: resolvedRealId,
splitSourceHandle: splitPayload.intersectedSourceHandle,
@@ -417,14 +433,15 @@ export function createCanvasSyncEngineController({
x: pendingMove.positionX,
y: pendingMove.positionY,
});
if (runMoveNodeMutation) {
await runMoveNodeMutation({
const moveNodeMutation = getRunMoveNodeMutation?.();
if (moveNodeMutation) {
await moveNodeMutation({
nodeId: resolvedRealId,
positionX: pendingMove.positionX,
positionY: pendingMove.positionY,
});
} else {
await enqueueSyncMutation("moveNode", {
await getEnqueueSyncMutation()("moveNode", {
nodeId: resolvedRealId,
positionX: pendingMove.positionX,
positionY: pendingMove.positionY,
@@ -477,9 +494,21 @@ export function useCanvasSyncEngine({
const isSyncOnline =
isBrowserOnline === true && connectionState.isWebSocketConnected === true;
const canvasIdRef = useRef(canvasId);
canvasIdRef.current = canvasId;
const isSyncOnlineRef = useRef(isSyncOnline);
isSyncOnlineRef.current = isSyncOnline;
const setNodesRef = useRef(setNodes);
setNodesRef.current = setNodes;
const setEdgesRef = useRef(setEdges);
setEdgesRef.current = setEdges;
const setAssetBrowserTargetNodeIdRef = useRef(setAssetBrowserTargetNodeId);
setAssetBrowserTargetNodeIdRef.current = setAssetBrowserTargetNodeId;
const deletingNodeIdsRef = useRef(deletingNodeIds);
deletingNodeIdsRef.current = deletingNodeIds;
const enqueueSyncMutationRef = useRef<QueueSyncMutation>(async () => undefined);
const runMoveNodeMutationRef = useRef<RunMoveNodeMutation>(async () => undefined);
const runBatchRemoveNodesMutationRef = useRef<RunBatchRemoveNodesMutation>(
async () => {},
);
@@ -514,6 +543,7 @@ export function useCanvasSyncEngine({
},
[canvasId, refreshPendingSyncCount],
);
enqueueSyncMutationRef.current = enqueueSyncMutation;
const runMoveNodeMutation = useCallback<RunMoveNodeMutation>(
async (args) => {
@@ -521,6 +551,7 @@ export function useCanvasSyncEngine({
},
[enqueueSyncMutation],
);
runMoveNodeMutationRef.current = runMoveNodeMutation;
const runBatchMoveNodesMutation = useCallback(
async (args: {
@@ -748,20 +779,22 @@ export function useCanvasSyncEngine({
const controllerRef = useRef<CanvasSyncEngineController | null>(null);
if (controllerRef.current === null) {
controllerRef.current = createCanvasSyncEngineController({
canvasId,
canvasId: () => canvasIdRef.current,
isSyncOnline: () => isSyncOnlineRef.current,
enqueueSyncMutation,
runMoveNodeMutation,
runBatchRemoveNodes: async (args) => {
getEnqueueSyncMutation: () => enqueueSyncMutationRef.current,
getRunMoveNodeMutation: () => runMoveNodeMutationRef.current,
getRunBatchRemoveNodes: () => async (args: { nodeIds: Id<"nodes">[] }) => {
await runBatchRemoveNodesMutationRef.current(args);
},
runSplitEdgeAtExistingNode: async (args) => {
getRunSplitEdgeAtExistingNode: () => async (
args: Parameters<RunSplitEdgeAtExistingNodeMutation>[0],
) => {
await runSplitEdgeAtExistingNodeMutationRef.current(args);
},
setAssetBrowserTargetNodeId,
setNodes,
setEdges,
deletingNodeIds,
getSetAssetBrowserTargetNodeId: () => setAssetBrowserTargetNodeIdRef.current,
getSetNodes: () => setNodesRef.current,
getSetEdges: () => setEdgesRef.current,
getDeletingNodeIds: () => deletingNodeIdsRef.current,
});
}
const controller = controllerRef.current;

View File

@@ -57,6 +57,7 @@
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.2.1",
"jsdom": "^29.0.1",
"tailwindcss": "^4",
"typescript": "^5",
"vitest": "^3.2.4"

330
pnpm-lock.yaml generated
View File

@@ -10,10 +10,10 @@ importers:
dependencies:
'@convex-dev/better-auth':
specifier: ^0.11.3
version: 0.11.3(@standard-schema/spec@1.1.0)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(convex@1.34.0(react@19.2.4))(hono@4.12.9)(react@19.2.4)(typescript@5.9.3)
version: 0.11.3(@standard-schema/spec@1.1.0)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(convex@1.34.0(react@19.2.4))(hono@4.12.9)(react@19.2.4)(typescript@5.9.3)
'@daveyplate/better-auth-ui':
specifier: ^3.4.0
version: 3.4.0(43fe9e8f7c24dd7a61ee43b650bb480d)
version: 3.4.0(33090e10f4680aa961584df50b0a91cd)
'@dnd-kit/core':
specifier: ^6.3.1
version: 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -25,7 +25,7 @@ importers:
version: 0.1.97
'@polar-sh/better-auth':
specifier: ^1.8.3
version: 1.8.3(@polar-sh/sdk@0.46.7)(@stripe/react-stripe-js@4.0.2(@stripe/stripe-js@7.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@stripe/stripe-js@7.9.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(react-dom@19.2.4(react@19.2.4))(react-is@16.13.1)(react@19.2.4)(redux@5.0.1)(zod@4.3.6)
version: 1.8.3(@polar-sh/sdk@0.46.7)(@stripe/react-stripe-js@4.0.2(@stripe/stripe-js@7.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@stripe/stripe-js@7.9.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(react-dom@19.2.4(react@19.2.4))(react-is@16.13.1)(react@19.2.4)(redux@5.0.1)(zod@4.3.6)
'@polar-sh/sdk':
specifier: ^0.46.7
version: 0.46.7
@@ -40,7 +40,7 @@ importers:
version: 12.10.1(@types/react@19.2.14)(immer@11.1.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
better-auth:
specifier: ^1.5.6
version: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
version: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
class-variance-authority:
specifier: ^0.7.1
version: 0.7.1
@@ -138,6 +138,9 @@ importers:
eslint-config-next:
specifier: 16.2.1
version: 16.2.1(@typescript-eslint/parser@8.57.2(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)
jsdom:
specifier: ^29.0.1
version: 29.0.1(@noble/hashes@2.0.1)
tailwindcss:
specifier: ^4
version: 4.2.2
@@ -146,7 +149,7 @@ importers:
version: 5.9.3
vitest:
specifier: ^3.2.4
version: 3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)
version: 3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)
packages:
@@ -154,6 +157,17 @@ packages:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
'@asamuzakjp/css-color@5.1.4':
resolution: {integrity: sha512-503MoTEmPSyEJ7zQ+5vlkwPtkyxDhbDwR9ajk/jpPGrCLiUFHzgEG4iViUPKdGlZPRT1mWSPSbDL2qkOoLU4vg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
'@asamuzakjp/dom-selector@7.0.4':
resolution: {integrity: sha512-jXR6x4AcT3eIrS2fSNAwJpwirOkGcd+E7F7CP3zjdTqz9B/2huHOL8YJZBgekKwLML+u7qB/6P1LXQuMScsx0w==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
'@asamuzakjp/nwsapi@2.3.9':
resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==}
'@babel/code-frame@7.29.0':
resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
engines: {node: '>=6.9.0'}
@@ -375,6 +389,10 @@ packages:
'@better-fetch/fetch@1.1.21':
resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==}
'@bramus/specificity@2.4.2':
resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
hasBin: true
'@captchafox/react@1.11.0':
resolution: {integrity: sha512-/oF/PahBiNwk/ZVC0XQBl9hHwwRo7Eg8k6tz0U835jH15OJpIZvGHPN4xZ5cRTct+sXAdVcMqfuEP0bsg4yTBw==}
peerDependencies:
@@ -391,6 +409,42 @@ packages:
convex: ^1.25.0
react: ^18.3.1 || ^19.0.0
'@csstools/color-helpers@6.0.2':
resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==}
engines: {node: '>=20.19.0'}
'@csstools/css-calc@3.1.1':
resolution: {integrity: sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==}
engines: {node: '>=20.19.0'}
peerDependencies:
'@csstools/css-parser-algorithms': ^4.0.0
'@csstools/css-tokenizer': ^4.0.0
'@csstools/css-color-parser@4.0.2':
resolution: {integrity: sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==}
engines: {node: '>=20.19.0'}
peerDependencies:
'@csstools/css-parser-algorithms': ^4.0.0
'@csstools/css-tokenizer': ^4.0.0
'@csstools/css-parser-algorithms@4.0.0':
resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==}
engines: {node: '>=20.19.0'}
peerDependencies:
'@csstools/css-tokenizer': ^4.0.0
'@csstools/css-syntax-patches-for-csstree@1.1.2':
resolution: {integrity: sha512-5GkLzz4prTIpoyeUiIu3iV6CSG3Plo7xRVOFPKI7FVEJ3mZ0A8SwK0XU3Gl7xAkiQ+mDyam+NNp875/C5y+jSA==}
peerDependencies:
css-tree: ^3.2.1
peerDependenciesMeta:
css-tree:
optional: true
'@csstools/css-tokenizer@4.0.0':
resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==}
engines: {node: '>=20.19.0'}
'@date-fns/tz@1.4.1':
resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==}
@@ -671,6 +725,15 @@ packages:
resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@exodus/bytes@1.15.0':
resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
peerDependencies:
'@noble/hashes': ^1.8.0 || ^2.0.0
peerDependenciesMeta:
'@noble/hashes':
optional: true
'@fastify/otel@0.17.1':
resolution: {integrity: sha512-K4wyxfUZx2ux5o+b6BtTqouYFVILohLZmSbA2tKUueJstNcBnoGPVhllCaOvbQ3ZrXdUxUC/fyrSWSCqHhdOPg==}
peerDependencies:
@@ -3732,6 +3795,9 @@ packages:
zod:
optional: true
bidi-js@1.0.3:
resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==}
bmp-ts@1.0.9:
resolution: {integrity: sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==}
@@ -3982,6 +4048,10 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
css-tree@3.2.1:
resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
@@ -4063,6 +4133,10 @@ packages:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
data-urls@7.0.0:
resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
data-view-buffer@1.0.2:
resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
engines: {node: '>= 0.4'}
@@ -4101,6 +4175,9 @@ packages:
decimal.js-light@2.5.1:
resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
decimal.js@10.6.0:
resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
dedent@1.7.2:
resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==}
peerDependencies:
@@ -4228,6 +4305,10 @@ packages:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
entities@6.0.1:
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
engines: {node: '>=0.12'}
env-paths@2.2.1:
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
engines: {node: '>=6'}
@@ -4753,6 +4834,10 @@ packages:
resolution: {integrity: sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==}
engines: {node: '>=16.9.0'}
html-encoding-sniffer@6.0.0:
resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
html-to-text@9.0.5:
resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==}
engines: {node: '>=14'}
@@ -4960,6 +5045,9 @@ packages:
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
engines: {node: '>=12'}
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
is-promise@4.0.0:
resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
@@ -5075,6 +5163,15 @@ packages:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
hasBin: true
jsdom@29.0.1:
resolution: {integrity: sha512-z6JOK5gRO7aMybVq/y/MlIpKh8JIi68FBKMUtKkK2KH/wMSRlCxQ682d08LB9fYXplyY/UXG8P4XXTScmdjApg==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0}
peerDependencies:
canvas: ^3.0.0
peerDependenciesMeta:
canvas:
optional: true
jsesc@3.1.0:
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
engines: {node: '>=6'}
@@ -5292,6 +5389,9 @@ packages:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
mdn-data@2.27.1:
resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
media-typer@1.1.0:
resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
engines: {node: '>= 0.8'}
@@ -5603,6 +5703,9 @@ packages:
resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==}
engines: {node: '>=18'}
parse5@8.0.0:
resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==}
parseley@0.12.1:
resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==}
@@ -6058,6 +6161,10 @@ packages:
resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==}
engines: {node: '>=11.0.0'}
saxes@6.0.0:
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
engines: {node: '>=v12.22.7'}
scheduler@0.27.0:
resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
@@ -6310,6 +6417,9 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
tagged-tag@1.0.0:
resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==}
engines: {node: '>=20'}
@@ -6402,6 +6512,10 @@ packages:
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
tr46@6.0.0:
resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==}
engines: {node: '>=20'}
ts-api-utils@2.5.0:
resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==}
engines: {node: '>=18.12'}
@@ -6489,6 +6603,10 @@ packages:
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
undici@7.24.7:
resolution: {integrity: sha512-H/nlJ/h0ggGC+uRL3ovD+G0i4bqhvsDOpbDv7At5eFLlj2b41L8QliGbnl2H7SnDiYhENphh1tQFJZf+MyfLsQ==}
engines: {node: '>=20.18.1'}
unicorn-magic@0.3.0:
resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
engines: {node: '>=18'}
@@ -6650,6 +6768,10 @@ packages:
jsdom:
optional: true
w3c-xmlserializer@5.0.0:
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
engines: {node: '>=18'}
warning@4.0.3:
resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
@@ -6667,6 +6789,10 @@ packages:
webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
webidl-conversions@8.0.1:
resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
engines: {node: '>=20'}
webpack-sources@3.3.4:
resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==}
engines: {node: '>=10.13.0'}
@@ -6681,6 +6807,14 @@ packages:
webpack-cli:
optional: true
whatwg-mimetype@5.0.0:
resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==}
engines: {node: '>=20'}
whatwg-url@16.0.1:
resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==}
engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
@@ -6746,6 +6880,10 @@ packages:
resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==}
engines: {node: '>=20'}
xml-name-validator@5.0.0:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'}
xml-parse-from-string@1.0.1:
resolution: {integrity: sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==}
@@ -6757,6 +6895,9 @@ packages:
resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
engines: {node: '>=4.0'}
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
@@ -6824,6 +6965,24 @@ snapshots:
'@alloc/quick-lru@5.2.0': {}
'@asamuzakjp/css-color@5.1.4':
dependencies:
'@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
'@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
'@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
'@csstools/css-tokenizer': 4.0.0
lru-cache: 11.2.7
'@asamuzakjp/dom-selector@7.0.4':
dependencies:
'@asamuzakjp/nwsapi': 2.3.9
bidi-js: 1.0.3
css-tree: 3.2.1
is-potential-custom-element-name: 1.0.1
lru-cache: 11.2.7
'@asamuzakjp/nwsapi@2.3.9': {}
'@babel/code-frame@7.29.0':
dependencies:
'@babel/helper-validator-identifier': 7.28.5
@@ -7010,11 +7169,11 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5
'@better-auth/api-key@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))':
'@better-auth/api-key@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))':
dependencies:
'@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)
'@better-auth/utils': 0.3.1
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
zod: 4.3.6
'@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)':
@@ -7052,14 +7211,14 @@ snapshots:
'@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)
'@better-auth/utils': 0.3.1
'@better-auth/passkey@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(better-call@1.3.2(zod@4.3.6))(nanostores@1.2.0)':
'@better-auth/passkey@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(better-call@1.3.2(zod@4.3.6))(nanostores@1.2.0)':
dependencies:
'@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)
'@better-auth/utils': 0.3.1
'@better-fetch/fetch': 1.1.21
'@simplewebauthn/browser': 13.3.0
'@simplewebauthn/server': 13.3.0
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
better-call: 1.3.2(zod@4.3.6)
nanostores: 1.2.0
zod: 4.3.6
@@ -7079,6 +7238,10 @@ snapshots:
'@better-fetch/fetch@1.1.21': {}
'@bramus/specificity@2.4.2':
dependencies:
css-tree: 3.2.1
'@captchafox/react@1.11.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
'@captchafox/types': 1.4.0
@@ -7087,10 +7250,10 @@ snapshots:
'@captchafox/types@1.4.0': {}
'@convex-dev/better-auth@0.11.3(@standard-schema/spec@1.1.0)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(convex@1.34.0(react@19.2.4))(hono@4.12.9)(react@19.2.4)(typescript@5.9.3)':
'@convex-dev/better-auth@0.11.3(@standard-schema/spec@1.1.0)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(convex@1.34.0(react@19.2.4))(hono@4.12.9)(react@19.2.4)(typescript@5.9.3)':
dependencies:
'@better-fetch/fetch': 1.1.21
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
common-tags: 1.8.2
convex: 1.34.0(react@19.2.4)
convex-helpers: 0.1.114(@standard-schema/spec@1.1.0)(convex@1.34.0(react@19.2.4))(hono@4.12.9)(react@19.2.4)(typescript@5.9.3)(zod@4.3.6)
@@ -7105,23 +7268,47 @@ snapshots:
- hono
- typescript
'@csstools/color-helpers@6.0.2': {}
'@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
dependencies:
'@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
'@csstools/css-tokenizer': 4.0.0
'@csstools/css-color-parser@4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
dependencies:
'@csstools/color-helpers': 6.0.2
'@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
'@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
'@csstools/css-tokenizer': 4.0.0
'@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)':
dependencies:
'@csstools/css-tokenizer': 4.0.0
'@csstools/css-syntax-patches-for-csstree@1.1.2(css-tree@3.2.1)':
optionalDependencies:
css-tree: 3.2.1
'@csstools/css-tokenizer@4.0.0': {}
'@date-fns/tz@1.4.1': {}
'@daveyplate/better-auth-tanstack@1.3.6(@tanstack/query-core@5.95.2)(@tanstack/react-query@5.95.2(react@19.2.4))(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
'@daveyplate/better-auth-tanstack@1.3.6(@tanstack/query-core@5.95.2)(@tanstack/react-query@5.95.2(react@19.2.4))(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
'@tanstack/query-core': 5.95.2
'@tanstack/react-query': 5.95.2(react@19.2.4)
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
'@daveyplate/better-auth-ui@3.4.0(43fe9e8f7c24dd7a61ee43b650bb480d)':
'@daveyplate/better-auth-ui@3.4.0(33090e10f4680aa961584df50b0a91cd)':
dependencies:
'@better-auth/api-key': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))
'@better-auth/passkey': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(better-call@1.3.2(zod@4.3.6))(nanostores@1.2.0)
'@better-auth/api-key': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))
'@better-auth/passkey': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(better-call@1.3.2(zod@4.3.6))(nanostores@1.2.0)
'@better-fetch/fetch': 1.1.21
'@captchafox/react': 1.11.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@daveyplate/better-auth-tanstack': 1.3.6(@tanstack/query-core@5.95.2)(@tanstack/react-query@5.95.2(react@19.2.4))(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@daveyplate/better-auth-tanstack': 1.3.6(@tanstack/query-core@5.95.2)(@tanstack/react-query@5.95.2(react@19.2.4))(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@hcaptcha/react-hcaptcha': 2.0.2
'@hookform/resolvers': 5.2.2(react-hook-form@7.72.0(react@19.2.4))
'@instantdb/react': 0.22.169(react@19.2.4)
@@ -7146,7 +7333,7 @@ snapshots:
'@triplit/client': 1.0.50(typescript@5.9.3)
'@triplit/react': 1.0.51(react@19.2.4)(typescript@5.9.3)
'@wojtekmaj/react-recaptcha-v3': 0.1.4(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
better-call: 2.0.2(zod@4.3.6)
bowser: 2.14.1
class-variance-authority: 0.7.1
@@ -7343,6 +7530,10 @@ snapshots:
'@eslint/core': 0.17.0
levn: 0.4.1
'@exodus/bytes@1.15.0(@noble/hashes@2.0.1)':
optionalDependencies:
'@noble/hashes': 2.0.1
'@fastify/otel@0.17.1(@opentelemetry/api@1.9.0)':
dependencies:
'@opentelemetry/api': 1.9.0
@@ -8360,11 +8551,11 @@ snapshots:
tslib: 2.8.1
tsyringe: 4.10.0
'@polar-sh/better-auth@1.8.3(@polar-sh/sdk@0.46.7)(@stripe/react-stripe-js@4.0.2(@stripe/stripe-js@7.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@stripe/stripe-js@7.9.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(react-dom@19.2.4(react@19.2.4))(react-is@16.13.1)(react@19.2.4)(redux@5.0.1)(zod@4.3.6)':
'@polar-sh/better-auth@1.8.3(@polar-sh/sdk@0.46.7)(@stripe/react-stripe-js@4.0.2(@stripe/stripe-js@7.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@stripe/stripe-js@7.9.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)))(react-dom@19.2.4(react@19.2.4))(react-is@16.13.1)(react@19.2.4)(redux@5.0.1)(zod@4.3.6)':
dependencies:
'@polar-sh/checkout': 0.2.0(@stripe/react-stripe-js@4.0.2(@stripe/stripe-js@7.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(@stripe/stripe-js@7.9.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react-is@16.13.1)(react@19.2.4)(redux@5.0.1)
'@polar-sh/sdk': 0.46.7
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
better-auth: 1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1))
zod: 4.3.6
transitivePeerDependencies:
- '@stripe/react-stripe-js'
@@ -10471,7 +10662,7 @@ snapshots:
baseline-browser-mapping@2.10.10: {}
better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)):
better-auth@1.5.6(@opentelemetry/api@1.9.0)(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)):
dependencies:
'@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0)
'@better-auth/drizzle-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@4.3.6))(jose@6.2.2)(kysely@0.28.14)(nanostores@1.2.0))(@better-auth/utils@0.3.1)
@@ -10494,7 +10685,7 @@ snapshots:
next: 16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
vitest: 3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)
vitest: 3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1)
transitivePeerDependencies:
- '@cloudflare/workers-types'
- '@opentelemetry/api'
@@ -10517,6 +10708,10 @@ snapshots:
optionalDependencies:
zod: 4.3.6
bidi-js@1.0.3:
dependencies:
require-from-string: 2.0.2
bmp-ts@1.0.9: {}
body-parser@2.2.2:
@@ -10736,6 +10931,11 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
css-tree@3.2.1:
dependencies:
mdn-data: 2.27.1
source-map-js: 1.2.1
cssesc@3.0.0: {}
csstype@3.2.3: {}
@@ -10808,6 +11008,13 @@ snapshots:
data-uri-to-buffer@4.0.1: {}
data-urls@7.0.0(@noble/hashes@2.0.1):
dependencies:
whatwg-mimetype: 5.0.0
whatwg-url: 16.0.1(@noble/hashes@2.0.1)
transitivePeerDependencies:
- '@noble/hashes'
data-view-buffer@1.0.2:
dependencies:
call-bound: 1.0.4
@@ -10840,6 +11047,8 @@ snapshots:
decimal.js-light@2.5.1: {}
decimal.js@10.6.0: {}
dedent@1.7.2: {}
deep-eql@5.0.2: {}
@@ -10943,6 +11152,8 @@ snapshots:
entities@4.5.0: {}
entities@6.0.1: {}
env-paths@2.2.1: {}
error-ex@1.3.4:
@@ -11658,6 +11869,12 @@ snapshots:
hono@4.12.9: {}
html-encoding-sniffer@6.0.0(@noble/hashes@2.0.1):
dependencies:
'@exodus/bytes': 1.15.0(@noble/hashes@2.0.1)
transitivePeerDependencies:
- '@noble/hashes'
html-to-text@9.0.5:
dependencies:
'@selderee/plugin-htmlparser2': 0.11.0
@@ -11876,6 +12093,8 @@ snapshots:
is-plain-obj@4.1.0: {}
is-potential-custom-element-name@1.0.1: {}
is-promise@4.0.0: {}
is-reference@1.2.1:
@@ -12004,6 +12223,32 @@ snapshots:
dependencies:
argparse: 2.0.1
jsdom@29.0.1(@noble/hashes@2.0.1):
dependencies:
'@asamuzakjp/css-color': 5.1.4
'@asamuzakjp/dom-selector': 7.0.4
'@bramus/specificity': 2.4.2
'@csstools/css-syntax-patches-for-csstree': 1.1.2(css-tree@3.2.1)
'@exodus/bytes': 1.15.0(@noble/hashes@2.0.1)
css-tree: 3.2.1
data-urls: 7.0.0(@noble/hashes@2.0.1)
decimal.js: 10.6.0
html-encoding-sniffer: 6.0.0(@noble/hashes@2.0.1)
is-potential-custom-element-name: 1.0.1
lru-cache: 11.2.7
parse5: 8.0.0
saxes: 6.0.0
symbol-tree: 3.2.4
tough-cookie: 6.0.1
undici: 7.24.7
w3c-xmlserializer: 5.0.0
webidl-conversions: 8.0.1
whatwg-mimetype: 5.0.0
whatwg-url: 16.0.1(@noble/hashes@2.0.1)
xml-name-validator: 5.0.0
transitivePeerDependencies:
- '@noble/hashes'
jsesc@3.1.0: {}
json-buffer@3.0.1: {}
@@ -12171,6 +12416,8 @@ snapshots:
math-intrinsics@1.1.0: {}
mdn-data@2.27.1: {}
media-typer@1.1.0: {}
merge-descriptors@2.0.0: {}
@@ -12490,6 +12737,10 @@ snapshots:
parse-ms@4.0.0: {}
parse5@8.0.0:
dependencies:
entities: 6.0.1
parseley@0.12.1:
dependencies:
leac: 0.6.0
@@ -13009,6 +13260,10 @@ snapshots:
sax@1.6.0: {}
saxes@6.0.0:
dependencies:
xmlchars: 2.2.0
scheduler@0.27.0: {}
schema-utils@4.3.3:
@@ -13364,6 +13619,8 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
symbol-tree@3.2.4: {}
tagged-tag@1.0.0: {}
tailwind-merge@3.5.0: {}
@@ -13431,6 +13688,10 @@ snapshots:
tr46@0.0.3: {}
tr46@6.0.0:
dependencies:
punycode: 2.3.1
ts-api-utils@2.5.0(typescript@5.9.3):
dependencies:
typescript: 5.9.3
@@ -13538,6 +13799,8 @@ snapshots:
undici-types@6.21.0: {}
undici@7.24.7: {}
unicorn-magic@0.3.0: {}
universalify@2.0.1: {}
@@ -13683,7 +13946,7 @@ snapshots:
lightningcss: 1.32.0
terser: 5.46.1
vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1):
vitest@3.2.4(@types/node@20.19.37)(jiti@2.6.1)(jsdom@29.0.1(@noble/hashes@2.0.1))(lightningcss@1.32.0)(msw@2.12.14(@types/node@20.19.37)(typescript@5.9.3))(terser@5.46.1):
dependencies:
'@types/chai': 5.2.3
'@vitest/expect': 3.2.4
@@ -13710,6 +13973,7 @@ snapshots:
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 20.19.37
jsdom: 29.0.1(@noble/hashes@2.0.1)
transitivePeerDependencies:
- jiti
- less
@@ -13724,6 +13988,10 @@ snapshots:
- tsx
- yaml
w3c-xmlserializer@5.0.0:
dependencies:
xml-name-validator: 5.0.0
warning@4.0.3:
dependencies:
loose-envify: 1.4.0
@@ -13739,6 +14007,8 @@ snapshots:
webidl-conversions@3.0.1: {}
webidl-conversions@8.0.1: {}
webpack-sources@3.3.4: {}
webpack@5.105.4:
@@ -13773,6 +14043,16 @@ snapshots:
- esbuild
- uglify-js
whatwg-mimetype@5.0.0: {}
whatwg-url@16.0.1(@noble/hashes@2.0.1):
dependencies:
'@exodus/bytes': 1.15.0(@noble/hashes@2.0.1)
tr46: 6.0.0
webidl-conversions: 8.0.1
transitivePeerDependencies:
- '@noble/hashes'
whatwg-url@5.0.0:
dependencies:
tr46: 0.0.3
@@ -13855,6 +14135,8 @@ snapshots:
is-wsl: 3.1.1
powershell-utils: 0.1.0
xml-name-validator@5.0.0: {}
xml-parse-from-string@1.0.1: {}
xml2js@0.5.0:
@@ -13864,6 +14146,8 @@ snapshots:
xmlbuilder@11.0.1: {}
xmlchars@2.2.0: {}
xtend@4.0.2: {}
y18n@5.0.8: {}

View File

@@ -13,6 +13,7 @@ export default defineConfig({
"tests/**/*.test.ts",
"components/canvas/__tests__/canvas-flow-reconciliation-helpers.test.ts",
"components/canvas/__tests__/use-canvas-sync-engine.test.ts",
"components/canvas/__tests__/use-canvas-sync-engine-hook.test.tsx",
],
},
});