diff --git a/biome.json b/biome.json index 8113890c1b..513449a8e3 100644 --- a/biome.json +++ b/biome.json @@ -5,7 +5,7 @@ "frontend/**/*.{tsx,ts,js}", "!frontend/packages", "!**/*.gen.*", - "rivetkit-typescript/**/*.{tsx,ts,css}", + "rivetkit-typescript/**/*.{tsx,ts,css,svelte}", "examples/**/*.{ts,tsx}", "!/**/node_modules" ], @@ -94,6 +94,21 @@ } } } - } + }, + { + "includes": ["**/*.svelte", "**/*.astro", "**/*.vue"], + "linter": { + "rules": { + "style": { + "useConst": "off", + "useImportType": "off" + }, + "correctness": { + "noUnusedVariables": "off", + "noUnusedImports": "off" + } + } + } + } ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44bf8ee89b..2130f22d3d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -171,7 +171,7 @@ importers: version: 5.9.3 vitest: specifier: ^1.6.1 - version: 1.6.1(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 1.6.1(@types/node@22.19.10)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) engine/sdks/typescript/runner-protocol: dependencies: @@ -230,7 +230,7 @@ importers: version: 5.9.3 vitest: specifier: ^1.6.1 - version: 1.6.1(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 1.6.1(@types/node@22.19.10)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/actor-actions: dependencies: @@ -273,7 +273,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/actor-actions-vercel: dependencies: @@ -322,7 +322,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/ai-agent: dependencies: @@ -371,7 +371,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/ai-agent-vercel: dependencies: @@ -426,7 +426,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/ai-and-user-generated-actors-freestyle: dependencies: @@ -484,7 +484,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^2.1.8 - version: 2.1.9(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 2.1.9(@types/node@22.19.10)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/chat-room: dependencies: @@ -527,7 +527,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/chat-room-vercel: dependencies: @@ -576,7 +576,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/cloudflare-workers: dependencies: @@ -678,7 +678,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/collaborative-document-vercel: dependencies: @@ -733,7 +733,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/cross-actor-actions: dependencies: @@ -776,7 +776,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/cross-actor-actions-vercel: dependencies: @@ -825,7 +825,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/cursors: dependencies: @@ -868,7 +868,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/cursors-raw-websocket: dependencies: @@ -911,7 +911,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/cursors-raw-websocket-vercel: dependencies: @@ -960,7 +960,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/cursors-vercel: dependencies: @@ -1009,7 +1009,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/custom-serverless: dependencies: @@ -1028,7 +1028,7 @@ importers: version: 5.9.3 vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/elysia: dependencies: @@ -1108,7 +1108,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/experimental-durable-streams-ai-agent-vercel: dependencies: @@ -1175,7 +1175,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/geo-distributed-database: dependencies: @@ -1218,7 +1218,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/geo-distributed-database-vercel: dependencies: @@ -1267,7 +1267,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/hello-world: dependencies: @@ -1310,7 +1310,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/hello-world-vercel: dependencies: @@ -1359,7 +1359,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/hono: dependencies: @@ -1424,7 +1424,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/hono-react-vercel: dependencies: @@ -1473,7 +1473,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/kitchen-sink: dependencies: @@ -1608,7 +1608,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/multiplayer-game: dependencies: @@ -1651,7 +1651,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/multiplayer-game-patterns: dependencies: @@ -1706,7 +1706,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/multiplayer-game-patterns-vercel: dependencies: @@ -1764,7 +1764,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/multiplayer-game-vercel: dependencies: @@ -1813,7 +1813,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/native-websockets: dependencies: @@ -1859,7 +1859,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) ws: specifier: ^8.16.0 version: 8.19.0 @@ -1914,7 +1914,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) ws: specifier: ^8.16.0 version: 8.19.0 @@ -2000,7 +2000,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/per-tenant-database-vercel: dependencies: @@ -2049,7 +2049,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/raw-fetch-handler: dependencies: @@ -2095,7 +2095,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/raw-fetch-handler-vercel: dependencies: @@ -2144,7 +2144,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/raw-websocket-handler: dependencies: @@ -2187,7 +2187,7 @@ importers: version: 6.4.1(@types/node@22.19.10)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/raw-websocket-handler-proxy: dependencies: @@ -2245,7 +2245,7 @@ importers: version: 6.4.1(@types/node@22.19.10)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/raw-websocket-handler-proxy-vercel: dependencies: @@ -2300,7 +2300,7 @@ importers: version: 6.4.1(@types/node@22.19.10)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/raw-websocket-handler-vercel: dependencies: @@ -2349,7 +2349,7 @@ importers: version: 6.4.1(@types/node@22.19.10)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/react: dependencies: @@ -2392,7 +2392,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/react-vercel: dependencies: @@ -2441,7 +2441,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/sandbox: dependencies: @@ -2566,7 +2566,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/sandbox-coding-agent-vercel: dependencies: @@ -2615,7 +2615,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/sandbox-vercel: dependencies: @@ -2731,7 +2731,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/scheduling-vercel: dependencies: @@ -2780,7 +2780,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/sqlite-drizzle: dependencies: @@ -2860,7 +2860,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/state-vercel: dependencies: @@ -2909,7 +2909,7 @@ importers: version: 5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/stream: dependencies: @@ -2952,7 +2952,7 @@ importers: version: 5.4.21(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.13)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/stream-vercel: dependencies: @@ -3001,7 +3001,7 @@ importers: version: 5.4.21(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@20.19.13)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) examples/trpc: dependencies: @@ -3471,7 +3471,7 @@ importers: version: 17.2.3 vitest: specifier: ^4.0.18 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) frontend/packages/components: dependencies: @@ -3818,7 +3818,7 @@ importers: version: 5.9.3 vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.7.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@24.7.1)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.7.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@24.7.1)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) wrangler: specifier: ^4.22.0 version: 4.44.0(@cloudflare/workers-types@4.20251014.0) @@ -3905,7 +3905,7 @@ importers: version: 5.9.3 vitest: specifier: ^3.0.6 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) rivetkit-typescript/packages/next-js: dependencies: @@ -4127,7 +4127,7 @@ importers: version: 5.1.4(typescript@5.9.3)(vite@7.3.1(@types/node@22.19.10)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) ws: specifier: ^8.18.1 version: 8.19.0 @@ -4176,7 +4176,7 @@ importers: version: 5.9.3 vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) rivetkit-typescript/packages/sqlite-vfs-test: dependencies: @@ -4195,7 +4195,38 @@ importers: version: 5.9.3 vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + + rivetkit-typescript/packages/svelte: + dependencies: + '@rivetkit/framework-base': + specifier: 2.1.10 + version: 2.1.10 + esm-env: + specifier: ^1.2.2 + version: 1.2.2 + rivetkit: + specifier: workspace:* + version: link:../rivetkit + devDependencies: + '@sveltejs/package': + specifier: ^2.5.7 + version: 2.5.7(svelte@5.55.1)(typescript@5.9.3) + jsdom: + specifier: ^28.0.0 + version: 28.1.0(@noble/hashes@1.8.0) + svelte: + specifier: ^5.0.0 + version: 5.55.1 + svelte-check: + specifier: ^4.4.3 + version: 4.4.5(picomatch@4.0.3)(svelte@5.55.1)(typescript@5.9.3) + typescript: + specifier: ^5.5.0 + version: 5.9.3 + vitest: + specifier: ^4.0.0 + version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.0.7)(jiti@1.21.7)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@25.0.7)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) rivetkit-typescript/packages/traces: dependencies: @@ -4232,7 +4263,7 @@ importers: version: 5.9.3 vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) rivetkit-typescript/packages/workflow-engine: dependencies: @@ -4275,7 +4306,7 @@ importers: version: 5.9.3 vitest: specifier: ^3.1.1 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) scripts/release: dependencies: @@ -4607,7 +4638,7 @@ importers: version: link:../../../rivetkit-typescript/packages/rivetkit vitest: specifier: ^3.0.9 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) zod: specifier: ^4.1.0 version: 4.1.13 @@ -4638,6 +4669,9 @@ packages: graphql: optional: true + '@acemir/cssom@0.9.31': + resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} + '@adobe/css-tools@4.3.3': resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==} @@ -4729,6 +4763,16 @@ packages: '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + '@asamuzakjp/css-color@5.1.1': + resolution: {integrity: sha512-iGWN8E45Ws0XWx3D44Q1t6vX2LqhCKcwfmwBYCDsFrYFS6m4q/Ks61L2veETaLv+ckDC6+dTETJoaAAb7VjLiw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/dom-selector@6.8.1': + resolution: {integrity: sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==} + + '@asamuzakjp/nwsapi@2.3.9': + resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@asteasolutions/zod-to-openapi@8.2.0': resolution: {integrity: sha512-u05zNUirlukJAf9oEHmxSF31L1XQhz9XdpVILt7+xhrz65oQqBpiOWFkGvRWL0IpjOUJ878idKoNmYPxrFnkeg==} peerDependencies: @@ -5520,6 +5564,10 @@ packages: '@braintree/sanitize-url@7.1.1': resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} + '@bramus/specificity@2.4.2': + resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} + hasBin: true + '@bufbuild/protobuf@2.11.0': resolution: {integrity: sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ==} @@ -5743,6 +5791,42 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@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/utc@1.2.0': resolution: {integrity: sha512-YLq+crMPJiBmIdkRmv9nZuZy1mVtMlDcUKlg4mvI0UsC/dZeIaGoGB5p/C4FrpeOhZ7zBTK03T58S0DFkRNMnw==} @@ -6752,6 +6836,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 + '@expo/cli@54.0.13': resolution: {integrity: sha512-wUJVTByZzDN0q8UjXDlu6WD2BWoTJCKVVBGUBNmvViDX4FhnESwefmtXPoO54QUUKs6vY89WZryHllGArGfLLw==} hasBin: true @@ -9055,6 +9148,9 @@ packages: '@rivetkit/fast-json-patch@3.1.2': resolution: {integrity: sha512-CtA50xgsSSzICQduF/NDShPRzvucnNvsW/lQO0WgMTT1XAj9Lfae4pm7r3llFwilgG+9iq76Hv1LUqNy72v6yw==} + '@rivetkit/framework-base@2.1.10': + resolution: {integrity: sha512-ZU1gsdyeu5jEf1OR3MevKzZyU6G+z2bR127Nxqo3mLcg+JQIEqxQN/szzQmaqEx5uhjhsZTKSwglhcgnRr25aQ==} + '@rivetkit/on-change@6.0.2-rc.1': resolution: {integrity: sha512-5RC9Ze/wTKqSlJvopdCgr+EfyV93+iiH8Thog0QXrl8PT1unuBNw/jadXNMtwgAxrIaCJL+JLaHQH9w7rqpMDw==} engines: {node: '>=20'} @@ -9831,6 +9927,18 @@ packages: resolution: {integrity: sha512-w8CEY73X/7tw2KKlL3iOk679V9bWseE4GzNz3zlaYxcTjmcmWOathRb0emgo/QQ3eoNzmq68+2Y2gxluAv3xGw==} engines: {node: '>=12.16'} + '@sveltejs/acorn-typescript@1.0.9': + resolution: {integrity: sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==} + peerDependencies: + acorn: ^8.9.0 + + '@sveltejs/package@2.5.7': + resolution: {integrity: sha512-qqD9xa9H7TDiGFrF6rz7AirOR8k15qDK/9i4MIE8te4vWsv5GEogPks61rrZcLy+yWph+aI6pIj2MdoK3YI8AQ==} + engines: {node: ^16.14 || >=18} + hasBin: true + peerDependencies: + svelte: ^3.44.0 || ^4.0.0 || ^5.0.0-next.1 + '@swc/core-darwin-arm64@1.15.11': resolution: {integrity: sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==} engines: {node: '>=10'} @@ -10468,6 +10576,10 @@ packages: '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + '@typescript-eslint/types@8.58.0': + resolution: {integrity: sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@uiw/codemirror-extensions-basic-setup@4.25.1': resolution: {integrity: sha512-zxgA2QkvP3ZDKxTBc9UltNFTrSeFezGXcZtZj6qcsBxiMzowoEMP5mVwXcKjpzldpZVRuY+JCC+RsekEgid4vg==} peerDependencies: @@ -11066,6 +11178,10 @@ packages: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} + aria-query@5.3.1: + resolution: {integrity: sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==} + engines: {node: '>= 0.4'} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -11267,6 +11383,9 @@ packages: resolution: {integrity: sha512-RxD2Vd96sQDjQr20kdP+F+dK/1OUNiVOl200vKBZY8u0vTwysfolF6Hq+3ZK2+h8My9YvZhHsF+RSGZW2VYrPQ==} engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + big-integer@1.6.52: resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} engines: {node: '>=0.6'} @@ -11526,6 +11645,10 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -11864,6 +11987,10 @@ packages: resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + cssstyle@6.2.0: + resolution: {integrity: sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==} + engines: {node: '>=20'} + csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -12035,6 +12162,10 @@ packages: dagre-d3-es@7.0.13: resolution: {integrity: sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==} + data-urls@7.0.0: + resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + date-fns@4.1.0: resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} @@ -12075,6 +12206,9 @@ packages: decimal.js-light@2.5.1: resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decode-named-character-reference@1.2.0: resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} @@ -12090,6 +12224,9 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} + dedent-js@1.0.1: + resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} + dedent@1.7.0: resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==} peerDependencies: @@ -12190,6 +12327,9 @@ packages: devalue@5.6.1: resolution: {integrity: sha512-jDwizj+IlEZBunHcOuuFVBnIMPAEHvTsJj0BcIp94xYguLRVBcXO853px/MyIJvbVzWdsGvrRweIUWJw8hBP7A==} + devalue@5.6.4: + resolution: {integrity: sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -12658,6 +12798,9 @@ packages: jiti: optional: true + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + espree@10.4.0: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -12671,6 +12814,9 @@ packages: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} + esrap@2.2.4: + resolution: {integrity: sha512-suICpxAmZ9A8bzJjEl/+rLJiDKC0X4gYWUxT6URAWBLvlXmtbZd5ySMu/N2ZGEtMCAmflUDPSehrP9BQcsGcSg==} + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} @@ -13490,6 +13636,10 @@ packages: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.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-escaper@3.0.3: resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} @@ -13514,6 +13664,10 @@ packages: resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -13711,9 +13865,15 @@ packages: resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -13899,6 +14059,15 @@ packages: jsc-safe-url@0.2.4: resolution: {integrity: sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==} + jsdom@28.1.0: + resolution: {integrity: sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==} + engines: {node: ^20.19.0 || ^22.12.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'} @@ -14176,6 +14345,9 @@ packages: resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} engines: {node: '>=14'} + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -14251,6 +14423,10 @@ packages: resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} engines: {node: 20 || >=22} + lru-cache@11.2.7: + resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -14805,6 +14981,10 @@ packages: react-dom: optional: true + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + mrmime@2.0.1: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} @@ -15269,6 +15449,9 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parse5@8.0.0: + resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -16030,6 +16213,10 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + real-require@0.2.0: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} @@ -16276,6 +16463,10 @@ packages: rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -16341,6 +16532,10 @@ packages: resolution: {integrity: sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==} engines: {node: '>=11.0.0'} + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + scheduler@0.26.0: resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} @@ -16348,6 +16543,9 @@ packages: resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} engines: {node: '>= 10.13.0'} + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} @@ -16795,6 +16993,24 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svelte-check@4.4.5: + resolution: {integrity: sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==} + engines: {node: '>= 18.0.0'} + hasBin: true + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: '>=5.0.0' + + svelte2tsx@0.7.52: + resolution: {integrity: sha512-svdT1FTrCLpvlU62evO5YdJt/kQ7nxgQxII/9BpQUvKr+GJRVdAXNVw8UWOt0fhoe5uWKyU0WsUTMRVAtRbMQg==} + peerDependencies: + svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 + typescript: ^4.9.4 || ^5.0.0 + + svelte@5.55.1: + resolution: {integrity: sha512-QjvU7EFemf6mRzdMGlAFttMWtAAVXrax61SZYHdkD6yoVGQ89VeyKfZD4H1JrV1WLmJBxWhFch9H6ig/87VGjw==} + engines: {node: '>=18'} + svgo@4.0.0: resolution: {integrity: sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==} engines: {node: '>=16'} @@ -16805,6 +17021,9 @@ packages: peerDependencies: react: 19.1.0 + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + tabbable@6.3.0: resolution: {integrity: sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==} @@ -16998,6 +17217,10 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -17218,10 +17441,6 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici@6.23.0: - resolution: {integrity: sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==} - engines: {node: '>=18.17'} - undici@6.24.1: resolution: {integrity: sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==} engines: {node: '>=18.17'} @@ -17846,6 +18065,10 @@ packages: w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} @@ -17879,6 +18102,10 @@ packages: resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} engines: {node: '>=8'} + webidl-conversions@8.0.1: + resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} + engines: {node: '>=20'} + webpack-sources@3.3.3: resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} engines: {node: '>=10.13.0'} @@ -17906,10 +18133,18 @@ packages: whatwg-fetch@3.6.20: resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + whatwg-mimetype@5.0.0: + resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} + engines: {node: '>=20'} + whatwg-url-without-unicode@8.0.0-3: resolution: {integrity: sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==} engines: {node: '>=10'} + 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==} @@ -18062,6 +18297,10 @@ packages: resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} hasBin: true + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + xml2js@0.6.0: resolution: {integrity: sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==} engines: {node: '>=4.0.0'} @@ -18082,6 +18321,9 @@ packages: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} engines: {node: '>=8.0'} + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xstate@5.21.0: resolution: {integrity: sha512-y4wmqxjyAa0tgz4k3m/MgTF1kDOahE5+xLfWt5eh1sk+43DatLhKlI8lQDJZpvihZavjbD3TUgy2PRMphhhqgQ==} @@ -18172,6 +18414,9 @@ packages: engines: {node: '>=8.0.0'} hasBin: true + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + zod-to-json-schema@3.25.1: resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} peerDependencies: @@ -18260,6 +18505,8 @@ snapshots: optionalDependencies: graphql: 16.12.0 + '@acemir/cssom@0.9.31': {} + '@adobe/css-tools@4.3.3': optional: true @@ -18392,6 +18639,24 @@ snapshots: package-manager-detector: 1.6.0 tinyexec: 1.0.2 + '@asamuzakjp/css-color@5.1.1': + 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@6.8.1': + dependencies: + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.0.3 + css-tree: 3.1.0 + is-potential-custom-element-name: 1.0.1 + lru-cache: 11.2.6 + + '@asamuzakjp/nwsapi@2.3.9': {} + '@asteasolutions/zod-to-openapi@8.2.0(zod@4.1.13)': dependencies: openapi3-ts: 4.5.0 @@ -19633,6 +19898,10 @@ snapshots: '@braintree/sanitize-url@7.1.1': {} + '@bramus/specificity@2.4.2': + dependencies: + css-tree: 3.1.0 + '@bufbuild/protobuf@2.11.0': {} '@capsizecss/unpack@4.0.0': @@ -19925,6 +20194,30 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@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.1.0)': + optionalDependencies: + css-tree: 3.1.0 + + '@csstools/css-tokenizer@4.0.0': {} + '@date-fns/utc@1.2.0': {} '@daytonaio/api-client@0.150.0': @@ -20566,6 +20859,10 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@exodus/bytes@1.15.0(@noble/hashes@1.8.0)': + optionalDependencies: + '@noble/hashes': 1.8.0 + '@expo/cli@54.0.13(@modelcontextprotocol/sdk@1.25.3(hono@4.11.9)(zod@3.25.76))(expo-router@4.0.21)(expo@54.0.18)(graphql@16.12.0)(react-native@0.82.1(@babel/core@7.29.0)(@types/react@19.2.13)(react@19.1.0))': dependencies: '@0no-co/graphql.web': 1.2.0(graphql@16.12.0) @@ -20916,7 +21213,7 @@ snapshots: abort-controller: 3.0.0 debug: 4.4.3 source-map-support: 0.5.21 - undici: 6.23.0 + undici: 6.24.1 transitivePeerDependencies: - supports-color @@ -21346,6 +21643,14 @@ snapshots: '@types/node': 24.7.1 optional: true + '@inquirer/confirm@5.1.21(@types/node@25.0.7)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@25.0.7) + '@inquirer/type': 3.0.10(@types/node@25.0.7) + optionalDependencies: + '@types/node': 25.0.7 + optional: true + '@inquirer/core@10.3.2(@types/node@20.19.13)': dependencies: '@inquirer/ansi': 1.0.2 @@ -21387,6 +21692,20 @@ snapshots: '@types/node': 24.7.1 optional: true + '@inquirer/core@10.3.2(@types/node@25.0.7)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@25.0.7) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 25.0.7 + optional: true + '@inquirer/figures@1.0.15': {} '@inquirer/type@3.0.10(@types/node@20.19.13)': @@ -21403,6 +21722,11 @@ snapshots: '@types/node': 24.7.1 optional: true + '@inquirer/type@3.0.10(@types/node@25.0.7)': + optionalDependencies: + '@types/node': 25.0.7 + optional: true + '@isaacs/balanced-match@4.0.1': {} '@isaacs/brace-expansion@5.0.1': @@ -21643,7 +21967,7 @@ snapshots: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 '@types/mdx': 2.0.13 - acorn: 8.15.0 + acorn: 8.16.0 collapse-white-space: 2.1.0 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 @@ -21652,7 +21976,7 @@ snapshots: hast-util-to-jsx-runtime: 2.3.6 markdown-extensions: 2.0.0 recma-build-jsx: 1.0.0 - recma-jsx: 1.0.1(acorn@8.15.0) + recma-jsx: 1.0.1(acorn@8.16.0) recma-stringify: 1.0.0 rehype-recma: 1.0.0 remark-mdx: 3.1.1 @@ -23622,6 +23946,12 @@ snapshots: '@rivetkit/fast-json-patch@3.1.2': {} + '@rivetkit/framework-base@2.1.10': + dependencies: + '@tanstack/store': 0.7.5 + fast-deep-equal: 3.1.3 + rivetkit: link:rivetkit-typescript/packages/rivetkit + '@rivetkit/on-change@6.0.2-rc.1': {} '@rivetkit/sqlite@0.1.1': {} @@ -24697,6 +25027,21 @@ snapshots: '@stripe/stripe-js@5.6.0': {} + '@sveltejs/acorn-typescript@1.0.9(acorn@8.16.0)': + dependencies: + acorn: 8.16.0 + + '@sveltejs/package@2.5.7(svelte@5.55.1)(typescript@5.9.3)': + dependencies: + chokidar: 5.0.0 + kleur: 4.1.5 + sade: 1.8.1 + semver: 7.7.4 + svelte: 5.55.1 + svelte2tsx: 0.7.52(svelte@5.55.1)(typescript@5.9.3) + transitivePeerDependencies: + - typescript + '@swc/core-darwin-arm64@1.15.11': optional: true @@ -25358,8 +25703,7 @@ snapshots: fflate: 0.8.2 meshoptimizer: 0.18.1 - '@types/trusted-types@2.0.7': - optional: true + '@types/trusted-types@2.0.7': {} '@types/unist@2.0.11': {} @@ -25383,6 +25727,8 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 + '@typescript-eslint/types@8.58.0': {} + '@uiw/codemirror-extensions-basic-setup@4.25.1(@codemirror/autocomplete@6.18.7)(@codemirror/commands@6.8.1)(@codemirror/language@6.11.3)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.11)(@codemirror/state@6.5.2)(@codemirror/view@6.38.2)': dependencies: '@codemirror/autocomplete': 6.18.7 @@ -25747,6 +26093,15 @@ snapshots: msw: 2.12.10(@types/node@20.19.13)(typescript@5.9.3) vite: 6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + '@vitest/mocker@4.0.18(msw@2.12.10(@types/node@25.0.7)(typescript@5.9.3))(vite@6.4.1(@types/node@25.0.7)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + dependencies: + '@vitest/spy': 4.0.18 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + msw: 2.12.10(@types/node@25.0.7)(typescript@5.9.3) + vite: 6.4.1(@types/node@25.0.7)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + '@vitest/pretty-format@2.1.9': dependencies: tinyrainbow: 1.2.0 @@ -25832,7 +26187,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0) '@vitest/utils@1.6.1': dependencies: @@ -26076,9 +26431,9 @@ snapshots: mime-types: 3.0.2 negotiator: 1.0.0 - acorn-import-attributes@1.9.5(acorn@8.15.0): + acorn-import-attributes@1.9.5(acorn@8.16.0): dependencies: - acorn: 8.15.0 + acorn: 8.16.0 acorn-import-phases@1.0.4(acorn@8.16.0): dependencies: @@ -26089,6 +26444,10 @@ snapshots: dependencies: acorn: 8.15.0 + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + acorn-walk@8.3.2: {} acorn-walk@8.3.4: @@ -26269,6 +26628,8 @@ snapshots: dependencies: tslib: 2.8.1 + aria-query@5.3.1: {} + aria-query@5.3.2: {} array-iterate@2.0.1: {} @@ -26618,6 +26979,10 @@ snapshots: prebuild-install: 7.1.3 optional: true + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + big-integer@1.6.52: {} binary-extensions@2.3.0: {} @@ -26935,6 +27300,10 @@ snapshots: dependencies: readdirp: 4.1.2 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + chownr@1.1.4: {} chownr@3.0.0: {} @@ -27275,6 +27644,13 @@ snapshots: dependencies: css-tree: 2.2.1 + cssstyle@6.2.0: + dependencies: + '@asamuzakjp/css-color': 5.1.1 + '@csstools/css-syntax-patches-for-csstree': 1.1.2(css-tree@3.1.0) + css-tree: 3.1.0 + lru-cache: 11.2.6 + csstype@3.2.3: {} cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): @@ -27473,6 +27849,13 @@ snapshots: d3: 7.9.0 lodash-es: 4.17.22 + data-urls@7.0.0(@noble/hashes@1.8.0): + dependencies: + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1(@noble/hashes@1.8.0) + transitivePeerDependencies: + - '@noble/hashes' + date-fns@4.1.0: {} dateformat@4.6.3: {} @@ -27495,6 +27878,8 @@ snapshots: decimal.js-light@2.5.1: {} + decimal.js@10.6.0: {} + decode-named-character-reference@1.2.0: dependencies: character-entities: 2.0.2 @@ -27508,6 +27893,8 @@ snapshots: mimic-response: 3.1.0 optional: true + dedent-js@1.0.1: {} + dedent@1.7.0(babel-plugin-macros@3.1.0): optionalDependencies: babel-plugin-macros: 3.1.0 @@ -27574,6 +27961,8 @@ snapshots: devalue@5.6.1: {} + devalue@5.6.4: {} + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -28051,10 +28440,12 @@ snapshots: transitivePeerDependencies: - supports-color + esm-env@1.2.2: {} + espree@10.4.0: dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 4.2.1 esprima@4.0.1: {} @@ -28063,6 +28454,11 @@ snapshots: dependencies: estraverse: 5.3.0 + esrap@2.2.4: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@typescript-eslint/types': 8.58.0 + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 @@ -29122,6 +29518,12 @@ snapshots: dependencies: lru-cache: 10.4.3 + html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0): + dependencies: + '@exodus/bytes': 1.15.0(@noble/hashes@1.8.0) + transitivePeerDependencies: + - '@noble/hashes' + html-escaper@3.0.3: {} html-url-attributes@3.0.1: {} @@ -29151,6 +29553,13 @@ snapshots: statuses: 2.0.2 toidentifier: 1.0.1 + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 @@ -29213,8 +29622,8 @@ snapshots: import-in-the-middle@2.0.6: dependencies: - acorn: 8.15.0 - acorn-import-attributes: 1.9.5(acorn@8.15.0) + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) cjs-module-lexer: 2.2.0 module-details-from-path: 1.0.4 @@ -29309,8 +29718,14 @@ snapshots: is-port-reachable@4.0.0: {} + is-potential-custom-element-name@1.0.1: {} + is-promise@4.0.0: {} + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.8 + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -29504,6 +29919,33 @@ snapshots: jsc-safe-url@0.2.4: {} + jsdom@28.1.0(@noble/hashes@1.8.0): + dependencies: + '@acemir/cssom': 0.9.31 + '@asamuzakjp/dom-selector': 6.8.1 + '@bramus/specificity': 2.4.2 + '@exodus/bytes': 1.15.0(@noble/hashes@1.8.0) + cssstyle: 6.2.0 + data-urls: 7.0.0(@noble/hashes@1.8.0) + decimal.js: 10.6.0 + html-encoding-sniffer: 6.0.0(@noble/hashes@1.8.0) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + parse5: 8.0.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 6.0.0 + undici: 7.24.6 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 8.0.1 + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1(@noble/hashes@1.8.0) + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - '@noble/hashes' + - supports-color + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -29780,6 +30222,8 @@ snapshots: mlly: 1.8.0 pkg-types: 1.3.1 + locate-character@3.0.0: {} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -29836,6 +30280,8 @@ snapshots: lru-cache@11.2.6: {} + lru-cache@11.2.7: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -30888,6 +31334,8 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) + mri@1.2.0: {} + mrmime@2.0.1: {} ms@2.0.0: {} @@ -30987,6 +31435,32 @@ snapshots: - '@types/node' optional: true + msw@2.12.10(@types/node@25.0.7)(typescript@5.9.3): + dependencies: + '@inquirer/confirm': 5.1.21(@types/node@25.0.7) + '@mswjs/interceptors': 0.41.2 + '@open-draft/deferred-promise': 2.2.0 + '@types/statuses': 2.0.6 + cookie: 1.1.1 + graphql: 16.12.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + rettime: 0.10.1 + statuses: 2.0.2 + strict-event-emitter: 0.5.1 + tough-cookie: 6.0.0 + type-fest: 5.4.4 + until-async: 3.0.2 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/node' + optional: true + muggle-string@0.3.1: {} mute-stream@2.0.0: {} @@ -31446,6 +31920,10 @@ snapshots: dependencies: entities: 6.0.1 + parse5@8.0.0: + dependencies: + entities: 6.0.1 + parseurl@1.3.3: {} pascal-case@3.1.2: @@ -32184,6 +32662,8 @@ snapshots: readdirp@4.1.2: {} + readdirp@5.0.0: {} + real-require@0.2.0: {} recast@0.23.11: @@ -32217,10 +32697,10 @@ snapshots: estree-util-build-jsx: 3.0.1 vfile: 6.0.3 - recma-jsx@1.0.1(acorn@8.15.0): + recma-jsx@1.0.1(acorn@8.16.0): dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) estree-util-to-js: 2.0.0 recma-parse: 1.0.0 recma-stringify: 1.0.0 @@ -32568,6 +33048,10 @@ snapshots: dependencies: tslib: 2.8.1 + sade@1.8.1: + dependencies: + mri: 1.2.0 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -32614,6 +33098,10 @@ snapshots: sax@1.5.0: {} + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + scheduler@0.26.0: {} schema-utils@4.3.3: @@ -32623,6 +33111,8 @@ snapshots: ajv-formats: 2.1.1(ajv@8.17.1) ajv-keywords: 5.1.0(ajv@8.17.1) + scule@1.3.0: {} + secure-json-parse@2.7.0: {} secure-json-parse@4.1.0: {} @@ -33153,6 +33643,44 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svelte-check@4.4.5(picomatch@4.0.3)(svelte@5.55.1)(typescript@5.9.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + chokidar: 4.0.3 + fdir: 6.5.0(picomatch@4.0.3) + picocolors: 1.1.1 + sade: 1.8.1 + svelte: 5.55.1 + typescript: 5.9.3 + transitivePeerDependencies: + - picomatch + + svelte2tsx@0.7.52(svelte@5.55.1)(typescript@5.9.3): + dependencies: + dedent-js: 1.0.1 + scule: 1.3.0 + svelte: 5.55.1 + typescript: 5.9.3 + + svelte@5.55.1: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) + '@types/estree': 1.0.8 + '@types/trusted-types': 2.0.7 + acorn: 8.16.0 + aria-query: 5.3.1 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.6.4 + esm-env: 1.2.2 + esrap: 2.2.4 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + svgo@4.0.0: dependencies: commander: 11.1.0 @@ -33169,6 +33697,8 @@ snapshots: react: 19.1.0 use-sync-external-store: 1.6.0(react@19.1.0) + symbol-tree@3.2.4: {} + tabbable@6.3.0: {} tagged-tag@1.0.0: {} @@ -33371,6 +33901,10 @@ snapshots: tr46@0.0.3: {} + tr46@6.0.0: + dependencies: + punycode: 2.3.1 + tree-kill@1.2.2: {} trim-lines@3.0.1: {} @@ -33393,7 +33927,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 20.19.13 - acorn: 8.15.0 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -33414,7 +33948,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 22.19.10 - acorn: 8.15.0 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -33434,7 +33968,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 25.0.7 - acorn: 8.15.0 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -33749,8 +34283,6 @@ snapshots: undici-types@7.16.0: optional: true - undici@6.23.0: {} - undici@6.24.1: {} undici@7.14.0: {} @@ -33898,7 +34430,7 @@ snapshots: unplugin@1.16.1: dependencies: - acorn: 8.15.0 + acorn: 8.16.0 webpack-virtual-modules: 0.6.2 unplugin@2.3.10: @@ -34423,7 +34955,7 @@ snapshots: optionalDependencies: vite: 6.4.1(@types/node@25.0.7)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - vitest@1.6.1(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): + vitest@1.6.1(@types/node@22.19.10)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): dependencies: '@vitest/expect': 1.6.1 '@vitest/runner': 1.6.1 @@ -34447,6 +34979,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.19.10 + jsdom: 28.1.0(@noble/hashes@1.8.0) transitivePeerDependencies: - less - lightningcss @@ -34457,7 +34990,7 @@ snapshots: - supports-color - terser - vitest@2.1.9(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): + vitest@2.1.9(@types/node@22.19.10)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): dependencies: '@vitest/expect': 2.1.9 '@vitest/mocker': 2.1.9(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(vite@5.4.21(@types/node@22.19.10)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)) @@ -34481,6 +35014,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.19.10 + jsdom: 28.1.0(@noble/hashes@1.8.0) transitivePeerDependencies: - less - lightningcss @@ -34492,7 +35026,7 @@ snapshots: - supports-color - terser - vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@20.19.13)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 @@ -34520,6 +35054,7 @@ snapshots: optionalDependencies: '@types/debug': 4.1.12 '@types/node': 20.19.13 + jsdom: 28.1.0(@noble/hashes@1.8.0) transitivePeerDependencies: - less - lightningcss @@ -34531,7 +35066,7 @@ snapshots: - supports-color - terser - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.19.10)(@vitest/ui@3.1.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@22.19.10)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 @@ -34560,6 +35095,7 @@ snapshots: '@types/debug': 4.1.12 '@types/node': 22.19.10 '@vitest/ui': 3.1.1(vitest@3.2.4) + jsdom: 28.1.0(@noble/hashes@1.8.0) transitivePeerDependencies: - less - lightningcss @@ -34571,7 +35107,7 @@ snapshots: - supports-color - terser - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.7.1)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@24.7.1)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.7.1)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@24.7.1)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 @@ -34599,6 +35135,7 @@ snapshots: optionalDependencies: '@types/debug': 4.1.12 '@types/node': 24.7.1 + jsdom: 28.1.0(@noble/hashes@1.8.0) transitivePeerDependencies: - less - lightningcss @@ -34610,7 +35147,7 @@ snapshots: - supports-color - terser - vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@20.19.13)(typescript@5.9.3))(vite@6.4.1(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) @@ -34635,6 +35172,46 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.0 '@types/node': 20.19.13 + jsdom: 28.1.0(@noble/hashes@1.8.0) + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.0.7)(jiti@1.21.7)(jsdom@28.1.0(@noble/hashes@1.8.0))(less@4.4.1)(lightningcss@1.32.0)(msw@2.12.10(@types/node@25.0.7)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(msw@2.12.10(@types/node@25.0.7)(typescript@5.9.3))(vite@6.4.1(@types/node@25.0.7)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + es-module-lexer: 1.7.0 + expect-type: 1.2.2 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 6.4.1(@types/node@25.0.7)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/node': 25.0.7 + jsdom: 28.1.0(@noble/hashes@1.8.0) transitivePeerDependencies: - jiti - less @@ -34681,6 +35258,10 @@ snapshots: w3c-keyname@2.2.8: {} + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + walker@1.0.8: dependencies: makeerror: 1.0.12 @@ -34709,6 +35290,8 @@ snapshots: webidl-conversions@5.0.0: {} + webidl-conversions@8.0.1: {} + webpack-sources@3.3.3: {} webpack-sources@3.3.4: @@ -34753,12 +35336,22 @@ snapshots: whatwg-fetch@3.6.20: {} + whatwg-mimetype@5.0.0: {} + whatwg-url-without-unicode@8.0.0-3: dependencies: buffer: 5.7.1 punycode: 2.3.1 webidl-conversions: 5.0.0 + whatwg-url@16.0.1(@noble/hashes@1.8.0): + dependencies: + '@exodus/bytes': 1.15.0(@noble/hashes@1.8.0) + tr46: 6.0.0 + webidl-conversions: 8.0.1 + transitivePeerDependencies: + - '@noble/hashes' + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -34882,6 +35475,8 @@ snapshots: dependencies: sax: 1.4.4 + xml-name-validator@5.0.0: {} + xml2js@0.6.0: dependencies: sax: 1.5.0 @@ -34898,6 +35493,8 @@ snapshots: xmlbuilder@15.1.1: {} + xmlchars@2.2.0: {} + xstate@5.21.0: {} xtend@4.0.2: {} @@ -34974,6 +35571,8 @@ snapshots: optionalDependencies: commander: 9.5.0 + zimmerframe@1.1.4: {} + zod-to-json-schema@3.25.1(zod@3.25.76): dependencies: zod: 3.25.76 diff --git a/rivetkit-typescript/packages/svelte/AGENTS.md b/rivetkit-typescript/packages/svelte/AGENTS.md new file mode 100644 index 0000000000..b28a99660c --- /dev/null +++ b/rivetkit-typescript/packages/svelte/AGENTS.md @@ -0,0 +1,269 @@ +# Packages / rivetkit-svelte + +**Parent:** [Root](../../AGENTS.md) + +Official Svelte 5 adapter for RivetKit actors. Thin adapter over `@rivetkit/framework-base`, with Svelte-first ergonomics for app-owned typed context, shared clients, and reactive actor handles. + +--- + +## Workspace + +| | | +| ----------- | -------------------------------------------------------------------- | +| Package | `@rivetkit/svelte` | +| Scripts | `build`, `check-types`, `test` | +| Depends on | `@rivetkit/framework-base`, `rivetkit`, `esm-env` | +| Peer deps | `svelte` ^5.0.0 | +| Dev deps | `vitest`, `jsdom`, `@sveltejs/package`, `svelte-check`, `typescript` | +| Consumed by | `apps/web`, `apps/connectivity-source`, and external SvelteKit apps | + +## Architecture + +The package supports two primary shapes: + +```text +Provider pattern: + app-local module + → createRivetContext() + → layout calls context.set(...) or context.setup(...) + → descendants call appLocalContext.get().useActor(...) + +Shared-client pattern: + app-local createClient(...) + → createSharedRivetKit(() => client) + → shared wrapper reused by ViewModels and provider setup +``` + +Reactive actor state is still powered by framework-base subscriptions bridged into Svelte runes: + +```text +useActor(opts | () => opts) + → extract(MaybeGetter) + → framework-base getOrCreateActor() + → $effect subscription + → getter-backed object + Proxy-forwarded actor methods + +createReactiveActor(opts) + → framework-base getOrCreateActor() + → manual subscription lifecycle + → getter-backed object + Proxy-forwarded actor methods + +preloadActor(opts) + → BROWSER guard (no-op during SSR) + → dedup check (Set keyed by name:key) + → client Proxy accessor → getOrCreate(key) + → handle.resolve() (single HTTP PUT, no WebSocket) + → fire-and-forget (catch removes from dedup on failure) +``` + +## Structure + +```text +packages/rivetkit-svelte/ +├── package.json +├── tsconfig.json +├── AGENTS.md +├── README.md +└── src/ + ├── check-types/ + │ └── noop.svelte # Keeps svelte-check happy for the package workspace + └── lib/ + ├── index.ts # Main barrel exports + ├── rivetkit.svelte.ts # createRivetKit, createReactiveActor, useActor, ActionDefaults + ├── shared.svelte.ts # createSharedRivetKit, withActorParams, createReactiveConnection + ├── context.ts # createRivetContext + ├── connection-health.svelte.ts # createConnectionHealth aggregate health + ├── internal/ + │ ├── types.ts # Getter, MaybeGetter + │ └── extract.ts # extract(MaybeGetter) + ├── testing/ + │ ├── index.ts + │ └── test-helpers.svelte.ts + └── __tests__/ + ├── action-middleware.test.ts # Action middleware interceptor tests (12 tests) + ├── context.test.ts + ├── reactive-actor.test.ts + ├── shared.test.ts + ├── helpers.ts + └── runes-shim.ts +``` + +## Public API + +### Factory Functions + +- `createRivetKit(endpoint?, opts?)` +- `createRivetKitWithClient(client, opts?)` + +Both return `{ useActor, createReactiveActor, preloadActor }`. + +### Context Helper + +- `createRivetContext()` — typed context helper with `set`, `get`, `has`, `setup`, `setupWithClient` + +Apps are expected to create and own their own context instance. The package no longer exports default-context helpers. + +### Shared-Client / Mixed-Mode Helpers + +- `createSharedRivetKit(getClient, opts?)` — lazily reuse one RivetKit wrapper for a shared client factory +- `withActorParams(base, params)` — merge actor options with static or reactive params +- `createReactiveConnection(source)` — bridge raw connection handling into reactive `connStatus` / `error` state + +### Action Middleware (`actionDefaults`) + +Both `useActor` and `createReactiveActor` accept an `actionDefaults` option (also configurable at the client level via `SvelteRivetKitOptions`). When provided, every proxied action call is wrapped with built-in middleware: + +- **Timeout** — configurable per-actor or per-client +- **Error capture** — errors captured to `lastActionError` reactive state (not thrown by default) +- **Loading tracking** — `isMutating`, `pendingActions` counters updated automatically +- **Connection guard** — rejects immediately if disconnected (configurable) +- **Lifecycle callbacks** — `onActionStart`, `onActionSuccess`, `onActionError`, `onActionSettled` + +```typescript +const actor = rivet.createReactiveActor({ + name: "user", + key: ["user", userId], + actionDefaults: { + timeout: 30_000, + throwOnError: false, // default — errors captured reactively + onActionError: (err, name) => console.error(name, err), + }, +}); + +// Direct action call — no manual wrapping needed +await actor.updateProfile({ name: "New" }); + +// Reactive tracking (all $state-backed) +actor.isMutating; // boolean +actor.pendingActions; // number +actor.lastActionError; // Error | null +actor.lastAction; // string | null +actor.resetActionState(); // clear error state +``` + +**Cascade:** Client-level `actionDefaults` are shallow-merged with actor-level overrides. Actor-level wins. + +**Types:** `ActionDefaults`, `SvelteRivetKitOptions` exported from `@rivetkit/svelte`. + +### Reactive Actor Primitives + +- `useActor(opts: MaybeGetter)` + - component initialization only + - accepts static options or a getter thunk + - returns getter-backed reactive metadata plus proxied actor methods + - exposes `lastError` and `hasEverConnected` in addition to `connection`, `handle`, `connStatus`, `error`, `isConnected`, `hash`, `onEvent` + - when `actionDefaults` provided: also exposes `isMutating`, `pendingActions`, `lastActionError`, `lastAction`, `resetActionState()` + +- `createReactiveActor(opts)` + - safe in modules and `.svelte.ts` classes + - manual lifecycle via `mount()` and `dispose()` + - `onEvent()` rebinds listeners when the underlying connection changes + - proxied actor methods are cached per connection instance for stable repeated reads + - when `actionDefaults` provided: also exposes `isMutating`, `pendingActions`, `lastActionError`, `lastAction`, `resetActionState()` + +### Actor Preloading + +- `preloadActor(opts: PreloadActorOptions)` + - wakes an actor via a single HTTP `resolve()` call — no WebSocket connection + - analogous to SvelteKit's `data-sveltekit-preload-data` for routes + - deduplicates: same actor (name + key) is only resolved once per RivetKit lifetime + - fire-and-forget: errors are silently caught; failed attempts removed from dedup set for retry + - SSR-safe: no-ops when `BROWSER` is false (via `esm-env`) + - intended for hover-based preloading to eliminate cold-start latency + +```typescript +// Preload a document actor on hover +rivet.preloadActor({ name: "document", key: ["doc", docId] }); +``` + +### Other Exports + +- `createConnectionHealth(getSources)` +- `extract()` +- `Getter` / `MaybeGetter` +- `PreloadActorOptions` type +- `ActionDefaults` type +- `SvelteRivetKitOptions` type +- `createClient` re-export from `rivetkit/client` +- `ActorConnStatus`, `ActorOptions`, `AnyActorRegistry` types + +### Testing Subpath + +`@rivetkit/svelte/testing` exports: + +- `testWithEffect(name, fn)` +- `effectRootScope(fn)` + +## Design Notes + +### App-Owned Typed Context + +The preferred provider-level API is `createRivetContext()`. Each app should own a local context instance rather than depending on a package-global default context. + +### Shared Client Ownership Is Explicit + +The package does not hide the raw `rivetkit/client` model. Apps that want a single transport should own that client locally and wrap it with `createSharedRivetKit()`. + +### App-Owned Auth + +Auth stays outside the package. `withActorParams()` exists to make token/org/session params ergonomic without baking Better Auth, Layerr token refresh, or framework-specific session logic into the adapter. + +### Familiar Svelte Conventions + +- `Getter` / `MaybeGetter` follow the same ergonomic direction teams will recognize from Runed and Bits UI +- provider/shared-client setup maps well to the mental model teams already have from TanStack Query +- composable primitives are preferred over monolithic app-framework wrappers + +### Closure-Based Rune State + +`createReactiveActor()` uses closure-based `$state` instead of class-field state so Proxy forwarding works correctly. Svelte class-field runes compile to private fields, and private fields do not cooperate with JS `Proxy`. + +### Action Middleware Architecture + +The action interceptor is built from `ActionDefaults` and passed to `proxyWithConnection()`. Every proxied method call flows through the interceptor, which: + +1. Checks connection guard (fail-fast if disconnected) +2. Increments `pendingActions` / sets `isMutating` +3. Races the action against timeout (if configured) +4. On success: clears `lastActionError`, fires `onActionSuccess` +5. On failure: captures error to `lastActionError`, fires `onActionError`. With `throwOnError: false` (default), resolves to `undefined` instead of rejecting. +6. Decrements `pendingActions` / clears `isMutating` when all actions complete + +The interceptor is a closure that captures `$state` variables directly — same pattern as the existing connection state tracking. No class fields, no double-proxy. + +### SSR Safety + +- `useActor()` is SSR-safe because `$effect` is the browser-only lifecycle boundary +- `createReactiveActor()` can be constructed during SSR, but `mount()` still belongs in a browser lifecycle +- `preloadActor()` is SSR-safe — guarded by `BROWSER` from `esm-env`; no-ops during SSR to avoid wasteful HTTP calls +- prefer app-local typed context and browser-owned singletons over request-time mutable globals in SvelteKit code + +## Integration With apps/web + +The web app now uses: + +- `apps/web/src/lib/context/actor-rivet-context.ts` for the app-local typed Rivet context +- `apps/web/src/lib/clients/actor-client.ts` for shared raw client and shared wrapper ownership + +That composition point owns: + +- `getActorClient(endpoint)` — shared raw client per endpoint +- `getActorRivet(endpoint)` — shared wrapper via `createSharedRivetKit()` +- `setupActorRivetContext(endpoint)` — typed-context provider setup + +`BaseActorViewModel` consumes `getActorRivet(endpoint)` and `withActorParams(...)`, so primary reactive actors and any lazy actor handles continue sharing one transport while Layerr-specific token refresh remains in app code. + +`BaseActorViewModel._createAndMount()` passes `actionDefaults` with `timeout: 30_000`, `throwOnError: false`, `guardConnection: true`, and callback bridges that sync the package's action tracking state to the ViewModel's reactive `isMutating` and `error` fields. Subclass ViewModels call `this.actor.someAction()` directly — no `callAction()` wrapper needed. The `callAction` method still exists as a thin adapter for legacy code that expects the `T | null` return shape. + +## Verification Expectations + +When changing this package, verify at minimum: + +- `bun run --filter @rivetkit/svelte check-types` +- `bun run --filter @rivetkit/svelte test` +- `bun run --filter @rivetkit/svelte build` when public exports or generated declarations changed +- consumer typecheck for `apps/web` and any other in-repo Svelte consumer if package surface or inferred types changed + +## Related + +[README.md](./README.md) | [Root AGENTS.md](../../AGENTS.md) | [Web App](../../apps/web/AGENTS.md) | [Real-Time Architecture](../../docs/architecture/Real-Time%20Architecture.md) diff --git a/rivetkit-typescript/packages/svelte/README.md b/rivetkit-typescript/packages/svelte/README.md new file mode 100644 index 0000000000..01a95a2e0a --- /dev/null +++ b/rivetkit-typescript/packages/svelte/README.md @@ -0,0 +1,601 @@ +# @rivetkit/svelte + +Official Svelte 5 adapter for [RivetKit](https://rivet.gg) actors. + +`@rivetkit/svelte` keeps the core RivetKit client model intact while giving Svelte apps a first-class DX for: + +- app-local typed context in layouts +- shared client reuse across components and ViewModels +- reactive actor state via Svelte runes +- mixed reactive/raw connection handling when low-level control still matters + +Built on `@rivetkit/framework-base`, alongside the React adapter, but shaped for Svelte patterns that feel familiar if you already use TanStack Query for shared clients, Runed for getter ergonomics, Bits UI for composable primitives, or Better Auth for app-owned auth wiring. + +## Install + +```bash +npm install @rivetkit/svelte rivetkit +``` + +## Migration Note + +The package no longer exports package-global default-context helpers. Existing apps should move to an app-local typed context created with `createRivetContext()` and provide it from a layout or other provider component. + +## Choose A Setup Pattern + +### Simple app: app-local typed context in your layout + +```ts +// lib/rivet.ts +import { createRivetContext } from "@rivetkit/svelte"; +import type { AppRegistry } from "./registry"; + +export const rivetContext = createRivetContext("AppRivet"); +``` + +```svelte + + +{@render children()} +``` + +### Shared client app: one transport, one wrapper, many consumers + +This is the recommended pattern when you want component-level `useActor()` and app-level ViewModels to share the same client. + +```ts +// lib/rivet.ts +import { + createClient, + createRivetContext, + createSharedRivetKit, +} from "@rivetkit/svelte"; +import type { AppRegistry } from "./registry"; + +export const rivetContext = createRivetContext("AppRivet"); + +const getClient = (() => { + let client: ReturnType> | null = null; + + return () => { + if (!client) { + client = createClient({ + endpoint: "http://localhost:3000", + devtools: false, + }); + } + + return client; + }; +})(); + +export const getRivet = createSharedRivetKit(getClient); +``` + +```svelte + + +{@render children()} +``` + +That shared-client mental model mirrors how TanStack Query centralizes one client instance at the provider boundary, but keeps RivetKit actor connections and transport ownership explicit. + +## Picking The Right Primitive + +| Primitive | Best for | Lifecycle | +| ---------------------------------- | --------------------------------------------------------------------- | ----------------------- | +| `useActor()` | Components that render live actor state | Automatic via `$effect` | +| `createReactiveActor()` | ViewModels, singletons, manual connection ownership | `mount()` / `dispose()` | +| shared raw client (`createClient`) | One-off actions, low-level handles, custom orchestration | App-owned | +| `createReactiveConnection()` | Bridging a raw connection into reactive connection status/error state | App-owned | + +A good rule of thumb: + +- use `useActor()` or `createReactiveActor()` when UI needs reactive connection state +- use the shared raw client for one-off operations and direct handles +- keep auth refresh, org switching, and app-specific orchestration outside the package + +## Core APIs + +### `createRivetContext()` + +Creates a typed Svelte context helper with `set`, `get`, `has`, `setup`, and `setupWithClient`. + +```ts +import { createRivetContext } from "@rivetkit/svelte"; + +export const rivetContext = createRivetContext("AppRivet"); +``` + +This follows the typed context style that is common in modern Svelte libraries instead of pushing consumers toward ad-hoc string keys or package-global defaults. + +### `createSharedRivetKit(getClient, opts?)` + +Lazily creates one RivetKit wrapper around a shared `rivetkit/client` instance and reuses it. + +```ts +const getRivet = createSharedRivetKit(() => getClient()); + +const a = getRivet(); +const b = getRivet(); +// a === b +``` + +Use this when you already have a shared raw client and want one obvious wrapper for `useActor()` and `createReactiveActor()`. + +### `withActorParams(base, params)` + +Merges actor options with static or reactive params. + +```ts +import { withActorParams } from "@rivetkit/svelte"; + +const getActorOptions = withActorParams( + { name: "chatRoom", key: ["room-123"] }, + () => ({ token: session.actorToken, orgId: session.orgId }), +); +``` + +This is intentionally generic. If your app uses Better Auth or another auth layer, keep refresh/session rules in the app and pass the resolved token into actor params from there. + +### `createReactiveConnection(source)` + +Wraps an existing raw connection source in reactive connection state. + +```ts +import { createReactiveConnection } from "@rivetkit/svelte"; + +const reactive = createReactiveConnection({ + connect: () => handle.connect(), +}); + +reactive.connect(); +reactive.connStatus; +reactive.error; +reactive.isConnected; +``` + +This is useful when a low-level handle should stay low-level, but the UI still wants Svelte-friendly `connStatus` and `error` reads. + +## Core Factories And Utilities + +These APIs remain part of the public surface: + +- `createRivetKit()` +- `createRivetKitWithClient()` +- `useActor()` +- `createReactiveActor()` +- `createConnectionHealth()` +- `extract()`, `Getter`, `MaybeGetter` + +## `useActor()` + +```svelte + + +{#if chat.isConnected} + +{:else if chat.error} +

{chat.error.message}

+{/if} +``` + +`useActor()` accepts a `MaybeGetter`, so reactive reads inside the getter re-subscribe automatically when inputs change. + +Returned reactive metadata includes: + +- `connection` +- `handle` +- `connStatus` +- `error` +- `lastError` +- `isConnected` +- `hasEverConnected` +- `hash` +- `onEvent()` +- `isMutating` — true when any action is in-flight (requires `actionDefaults`) +- `pendingActions` — count of concurrent in-flight actions (requires `actionDefaults`) +- `lastActionError` — most recent action error (requires `actionDefaults`) +- `lastAction` — name of the last called action (requires `actionDefaults`) +- `resetActionState()` — clear error/action state (requires `actionDefaults`) +- proxied actor methods + +## `createReactiveActor()` + +```ts +import { createRivetKit } from "@rivetkit/svelte"; +import type { AppRegistry } from "./registry"; + +const { createReactiveActor } = createRivetKit( + "http://localhost:3000", +); + +export class ChatViewModel { + actor = createReactiveActor({ + name: "chatRoom", + key: ["room-123"], + }); + + draft = $state(""); + + async send() { + await this.actor.sendMessage({ text: this.draft }); + this.draft = ""; + } +} +``` + +`createReactiveActor()` is the right primitive when the app wants ref counting, token refresh, lazy secondary connections, or other orchestration on top. + +## Action Middleware + +Both `useActor()` and `createReactiveActor()` accept an `actionDefaults` option that wraps every proxied action call with built-in middleware — timeout, error capture, loading tracking, and connection guard. No manual wrapping needed. + +### Quick Start + +```ts +const rivet = createRivetKit("http://localhost:3000", { + actionDefaults: { timeout: 30_000 }, +}); + +const actor = rivet.createReactiveActor({ + name: "counter", + key: ["main"], +}); + +actor.mount(); + +// Direct action call — errors captured, loading tracked, timeout enforced +await actor.increment(5); +``` + +### Reactive State In Templates + +```svelte + + + + +{#if counter.lastActionError} +

{counter.lastActionError.message}

+ +{/if} +``` + +### Cascade Configuration + +Client-level defaults are shallow-merged with actor-level overrides. Actor-level wins. + +```ts +const rivet = createRivetKit("http://localhost:3000", { + // Every actor gets these defaults + actionDefaults: { + timeout: 30_000, + onActionError: (err, name) => telemetry.captureError(name, err), + }, +}); + +// This actor overrides timeout but inherits onActionError +const actor = rivet.createReactiveActor({ + name: "chatRoom", + key: ["room-1"], + actionDefaults: { timeout: 60_000 }, +}); +``` + +### ViewModel Pattern (Direct Action Calls) + +With `actionDefaults` wired in the base class, ViewModel methods call actor actions directly. No wrapping needed. + +```ts +class NotificationsVM extends BaseActorViewModel { + // Before — every action required callAction wrapping: + // async markAsRead(ids: string[]) { + // const result = await this.callAction( + // () => this.actor.markAsRead({ ids }), + // "Failed to mark as read", + // ); + // if (result) this.toastSuccess("Marked as read"); + // return result !== null; + // } + + // After — direct call, package handles the rest: + async markAsRead(ids: string[]): Promise { + const result = await this.actor.markAsRead({ ids }); + if (result != null) { + this.toastSuccess("Marked as read"); + return true; + } + return false; + } +} +``` + +### Optimistic UI With Rollback + +Optimistic updates work naturally. The `undefined` return signals failure for rollback. + +```ts +async togglePin(conversationId: string): Promise { + // Optimistic update + const prev = this.conversations.find((c) => c.id === conversationId); + if (prev) prev.pinned = !prev.pinned; + + const result = await this.actor.togglePin({ conversationId }); + + // Rollback on failure (result is undefined when the interceptor catches an error) + if (result == null && prev) { + prev.pinned = !prev.pinned; + } +} +``` + +### Concurrent Action Tracking + +`pendingActions` tracks how many actions are in-flight simultaneously. + +```svelte + + +{#if actor.isMutating} +

Processing {actor.pendingActions} items...

+{/if} +``` + +### Lifecycle Callbacks + +Callbacks fire at the definition level — useful for telemetry, logging, and global error handling. + +```ts +const actor = rivet.createReactiveActor({ + name: "user", + key: ["user", userId], + actionDefaults: { + timeout: 30_000, + + onActionStart: (name, args) => { + console.log(`[${name}] started`, args); + }, + + onActionSuccess: (name, data) => { + console.log(`[${name}] completed`, data); + }, + + onActionError: (err, name) => { + // Send to error tracking service + errorReporter.capture(err, { action: name, actor: "user" }); + }, + + onActionSettled: (name) => { + // Always fires — useful for cleanup + console.log(`[${name}] settled`); + }, + }, +}); +``` + +### Connection Guard + +By default, actions called while disconnected fail immediately instead of hanging. The error is captured to `lastActionError`. + +```ts +// guardConnection: true (default) — immediate failure +const actor = rivet.createReactiveActor({ + name: "counter", + key: ["main"], + actionDefaults: { guardConnection: true }, +}); + +// If disconnected, resolves to undefined immediately +// actor.lastActionError.message === 'Action "increment" called while disconnected' +await actor.increment(5); + +// Disable guard — let the action attempt even when disconnected +// (useful if you want the WebSocket queue to handle it) +const actor2 = rivet.createReactiveActor({ + name: "counter", + key: ["main"], + actionDefaults: { guardConnection: false }, +}); +``` + +### `throwOnError` Modes + +Control whether errors reject the promise or only land in reactive state. + +```ts +// Mode 1: false (default) — errors captured, not thrown +const actor = rivet.createReactiveActor({ + name: "counter", + key: ["main"], + actionDefaults: { throwOnError: false }, +}); + +const result = await actor.riskyAction(); // resolves to undefined on error +// actor.lastActionError has the Error object + +// Mode 2: true — errors captured AND re-thrown +const actor2 = rivet.createReactiveActor({ + name: "counter", + key: ["main"], + actionDefaults: { throwOnError: true }, +}); + +try { + await actor2.riskyAction(); +} catch (err) { + // err is the original Error + // actor2.lastActionError also has it +} + +// Mode 3: function — decide per error +const actor3 = rivet.createReactiveActor({ + name: "counter", + key: ["main"], + actionDefaults: { + throwOnError: (err, actionName) => { + // Only throw for auth errors — swallow everything else + return err.message.includes("AUTH_"); + }, + }, +}); +``` + +### Without `actionDefaults` — Zero Behavior Change + +When `actionDefaults` is not set, everything works exactly as before. Actions are plain pass-through calls on the Proxy with no interception. + +```ts +// No actionDefaults — same behavior as before the feature existed +const actor = rivet.createReactiveActor({ + name: "counter", + key: ["main"], +}); + +// isMutating/lastActionError exist but stay at defaults (false/null) +// Actions throw on error, no timeout, no tracking +await actor.increment(5); // raw pass-through +``` + +### `ActionDefaults` Reference + +| Option | Type | Default | Description | +| ----------------- | ----------------------------------- | ------- | ---------------------------------------- | +| `timeout` | `number` | none | Action timeout in milliseconds | +| `throwOnError` | `boolean \| (err, name) => boolean` | `false` | Whether to re-throw captured errors | +| `guardConnection` | `boolean` | `true` | Reject immediately if disconnected | +| `onActionStart` | `(name, args) => void` | — | Fires when an action call starts | +| `onActionSuccess` | `(name, data) => void` | — | Fires on successful completion | +| `onActionError` | `(error, name) => void` | — | Fires on failure (timeout, network, etc) | +| `onActionSettled` | `(name) => void` | — | Fires after success or failure | + +### Reactive State Reference + +| Property | Type | Description | +| ------------------ | ---------------- | ---------------------------------------------------------------- | +| `isMutating` | `boolean` | `true` when any action is in-flight | +| `pendingActions` | `number` | Count of concurrent in-flight actions | +| `lastActionError` | `Error \| null` | Most recent action error (cleared on next success or reset) | +| `lastAction` | `string \| null` | Name of the last action called | +| `resetActionState` | `() => void` | Clear `lastActionError` and `lastAction` (return to clean state) | + +## Auth And Params Guidance + +Keep framework-specific auth rules in your app, not in the package. + +```ts +import { withActorParams } from "@rivetkit/svelte"; + +const getChatActorOptions = withActorParams( + { + name: "chatRoom", + key: ["room-123"], + }, + () => ({ + token: actorToken.current, + orgId: activeOrgId.current, + }), +); + +const chat = rivet.createReactiveActor(getChatActorOptions()); +``` + +That pattern stays flexible whether your token came from Better Auth, a custom server session, or another auth system entirely. + +## Connection Sharing And Performance + +`@rivetkit/svelte` is optimized for the common “one shared transport, many actor consumers” shape: + +- multiple `useActor()` calls with the same actor identity share the underlying connection through framework-base +- `createSharedRivetKit()` prevents duplicate wrapper creation when the app already centralizes a raw client +- proxied actor methods are cached per connection instance, so repeated reads like `actor.sendMessage` do not allocate a fresh bound function every time +- `lastError` and `hasEverConnected` make reconnect UX easier without forcing app code to track extra flags + +## SSR Safety + +- `useActor()` is SSR-safe by default because `$effect` is the browser lifecycle boundary +- `createReactiveActor()` can be created anywhere, but `mount()` should still happen in a browser lifecycle +- prefer app-local typed context over mutable request-time globals in SvelteKit code that can run during SSR + +## Testing + +Test helpers live under `@rivetkit/svelte/testing`: + +```ts +import { describe, expect } from "vitest"; +import { testWithEffect } from "@rivetkit/svelte/testing"; + +describe("runes", () => { + testWithEffect("runs inside an effect root", () => { + let count = $state(0); + expect(count).toBe(0); + }); +}); +``` + +## Familiar Mental Models + +The package does not depend on these libraries, but its DX intentionally lines up with patterns Svelte teams already know: + +- TanStack Query: shared-client/provider setup for app-level ownership +- Runed: `Getter` and `MaybeGetter` ergonomics for reactive inputs +- Bits UI: composable primitives instead of rigid framework wrappers +- Better Auth: auth stays app-owned, while the package only consumes resolved params + +## Requirements + +- Svelte 5+ +- RivetKit 2.1+ + +## License + +Apache-2.0 diff --git a/rivetkit-typescript/packages/svelte/package.json b/rivetkit-typescript/packages/svelte/package.json new file mode 100644 index 0000000000..f938b647c5 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/package.json @@ -0,0 +1,54 @@ +{ + "name": "@rivetkit/svelte", + "version": "0.1.0", + "description": "Svelte 5 runes integration for RivetKit actors", + "license": "Apache-2.0", + "type": "module", + "svelte": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "svelte": "./dist/index.js", + "default": "./dist/index.js" + }, + "./testing": { + "types": "./dist/testing/index.d.ts", + "svelte": "./dist/testing/index.js", + "default": "./dist/testing/index.js" + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "svelte-package -i src/lib", + "check-types": "svelte-check --tsconfig ./tsconfig.json", + "test": "vitest run --environment jsdom src/lib/__tests__/*.test.ts" + }, + "peerDependencies": { + "svelte": "^5.0.0" + }, + "dependencies": { + "@rivetkit/framework-base": "2.1.10", + "esm-env": "^1.2.2", + "rivetkit": "2.1.10" + }, + "devDependencies": { + "@sveltejs/package": "^2.5.7", + "jsdom": "^28.0.0", + "svelte": "^5.0.0", + "svelte-check": "^4.4.3", + "typescript": "^5.5.0", + "vitest": "^4.0.0" + }, + "keywords": [ + "rivetkit", + "svelte", + "svelte5", + "runes", + "actors", + "realtime", + "websocket" + ] +} diff --git a/rivetkit-typescript/packages/svelte/src/check-types/noop.svelte b/rivetkit-typescript/packages/svelte/src/check-types/noop.svelte new file mode 100644 index 0000000000..223bca9a6b --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/check-types/noop.svelte @@ -0,0 +1,5 @@ + + +
{message}
diff --git a/rivetkit-typescript/packages/svelte/src/lib/__tests__/action-middleware.test.ts b/rivetkit-typescript/packages/svelte/src/lib/__tests__/action-middleware.test.ts new file mode 100644 index 0000000000..f98735fe41 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/__tests__/action-middleware.test.ts @@ -0,0 +1,392 @@ +import "./runes-shim.js"; +import type { ActorConnStatus } from "rivetkit/client"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; + +// --------------------------------------------------------------------------- +// Mock — identical shape to reactive-actor.test.ts, but with async actions +// --------------------------------------------------------------------------- + +const frameworkMock = vi.hoisted(() => { + type Listener = (...args: unknown[]) => void; + type Subscriber = (value: { currentVal: MockActorState }) => void; + type MockConnection = { + id: string; + ping: () => string; + increment: (amount: number) => Promise; + failAction: () => Promise; + slowAction: () => Promise; + on: (eventName: string, handler: Listener) => () => void; + emit: (eventName: string, ...args: unknown[]) => void; + }; + type MockActorState = { + connection: MockConnection; + handle: { id: string }; + connStatus: ActorConnStatus; + error: Error | null; + hash: string; + }; + + const subscribers = new Set(); + + function createConnection(id: string): MockConnection { + const listeners = new Map>(); + + return { + id, + ping: () => `pong:${id}`, + increment: vi.fn(async (amount: number) => amount + 1), + failAction: vi.fn(async () => { + throw new Error("action failed"); + }), + slowAction: vi.fn( + () => + new Promise((resolve) => + setTimeout(() => resolve("done"), 5_000), + ), + ), + on(eventName: string, handler: Listener) { + let eventListeners = listeners.get(eventName); + if (!eventListeners) { + eventListeners = new Set(); + listeners.set(eventName, eventListeners); + } + eventListeners.add(handler); + return () => eventListeners?.delete(handler); + }, + emit(eventName: string, ...args: unknown[]) { + for (const listener of listeners.get(eventName) ?? []) { + listener(...args); + } + }, + }; + } + + let currentState: MockActorState; + + const getOrCreateActor = vi.fn(() => ({ + mount: vi.fn(() => vi.fn()), + state: { + get state() { + return currentState; + }, + subscribe(callback: Subscriber) { + subscribers.add(callback); + return () => subscribers.delete(callback); + }, + }, + })); + + function push(next: Partial): void { + currentState = { ...currentState, ...next }; + for (const subscriber of subscribers) { + subscriber({ currentVal: currentState }); + } + } + + function reset(): void { + subscribers.clear(); + currentState = { + connection: createConnection("one"), + handle: { id: "handle-one" }, + connStatus: "connected", + error: null, + hash: "hash-one", + }; + getOrCreateActor.mockClear(); + } + + reset(); + + return { + getOrCreateActor, + currentState: () => currentState, + push, + reset, + createConnection, + }; +}); + +vi.mock("@rivetkit/framework-base", () => ({ + createRivetKit: vi.fn(() => ({ + getOrCreateActor: frameworkMock.getOrCreateActor, + })), +})); + +import { createRivetKitWithClient } from "../rivetkit.svelte.js"; + +// --------------------------------------------------------------------------- +// Tests — action middleware via actionDefaults +// --------------------------------------------------------------------------- + +describe("action middleware (createReactiveActor)", () => { + beforeEach(() => { + frameworkMock.reset(); + vi.useFakeTimers(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + test("without actionDefaults, actions are plain pass-through (no tracking)", async () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + }); + + // Action tracking state has defaults but no interceptor + expect(actor.isMutating).toBe(false); + expect(actor.pendingActions).toBe(0); + expect(actor.lastActionError).toBe(null); + expect(actor.lastAction).toBe(null); + + // Actions pass through directly — no interception + const result = await actor.increment(5); + expect(result).toBe(6); + + // No tracking occurred (no actionDefaults configured) + expect(actor.isMutating).toBe(false); + expect(actor.lastAction).toBe(null); + }); + + test("with actionDefaults, tracks isMutating and pendingActions", async () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: {}, + }); + + expect(actor.isMutating).toBe(false); + expect(actor.pendingActions).toBe(0); + + const promise = actor.increment(5); + // Synchronously after calling, state is updated + expect(actor.isMutating).toBe(true); + expect(actor.pendingActions).toBe(1); + expect(actor.lastAction).toBe("increment"); + + await promise; + + expect(actor.isMutating).toBe(false); + expect(actor.pendingActions).toBe(0); + }); + + test("captures errors to lastActionError (throwOnError: false default)", async () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: {}, + }); + + // Call an action that throws + const result = await actor.failAction(); + + // Error captured reactively, not thrown + expect(result).toBeUndefined(); + expect(actor.lastActionError).toBeInstanceOf(Error); + expect(actor.lastActionError?.message).toBe("action failed"); + expect(actor.lastAction).toBe("failAction"); + expect(actor.isMutating).toBe(false); + }); + + test("clears lastActionError on next successful action", async () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: {}, + }); + + await actor.failAction(); + expect(actor.lastActionError).not.toBe(null); + + await actor.increment(1); + expect(actor.lastActionError).toBe(null); + }); + + test("throwOnError: true re-throws the error", async () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: { throwOnError: true }, + }); + + await expect(actor.failAction()).rejects.toThrow("action failed"); + // Error is still captured reactively even when thrown + expect(actor.lastActionError?.message).toBe("action failed"); + }); + + test("throwOnError as function — called per error to decide", async () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: { + throwOnError: (_err: Error, actionName: string) => + actionName === "failAction", + }, + }); + + // failAction should throw (function returns true for it) + await expect(actor.failAction()).rejects.toThrow("action failed"); + }); + + test("timeout causes action to fail", async () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: { timeout: 100 }, + }); + + const promise = actor.slowAction(); + + // Advance past the timeout + vi.advanceTimersByTime(150); + + const result = await promise; + expect(result).toBeUndefined(); + expect(actor.lastActionError?.message).toContain("timed out"); + expect(actor.isMutating).toBe(false); + }); + + test("resetActionState clears error and lastAction", async () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: {}, + }); + + await actor.failAction(); + expect(actor.lastActionError).not.toBe(null); + expect(actor.lastAction).toBe("failAction"); + + actor.resetActionState(); + expect(actor.lastActionError).toBe(null); + expect(actor.lastAction).toBe(null); + }); + + test("lifecycle callbacks fire in order", async () => { + const log: string[] = []; + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: { + onActionStart: (name: string) => log.push(`start:${name}`), + onActionSuccess: (name: string) => log.push(`success:${name}`), + onActionError: (_err: Error, name: string) => + log.push(`error:${name}`), + onActionSettled: (name: string) => log.push(`settled:${name}`), + }, + }); + + await actor.increment(5); + expect(log).toEqual([ + "start:increment", + "success:increment", + "settled:increment", + ]); + + log.length = 0; + await actor.failAction(); + expect(log).toEqual([ + "start:failAction", + "error:failAction", + "settled:failAction", + ]); + }); + + test("connection guard rejects when disconnected", async () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: { guardConnection: true }, + }); + + // Simulate disconnection + frameworkMock.push({ + connection: null as never, + connStatus: "disconnected", + }); + + const result = await actor.increment(5); + expect(result).toBeUndefined(); + expect(actor.lastActionError?.message).toContain("disconnected"); + }); + + test("client-level actionDefaults cascade to actor-level", async () => { + const clientLog: string[] = []; + const rivet = createRivetKitWithClient({} as never, { + actionDefaults: { + onActionStart: (name: string) => + clientLog.push(`client:${name}`), + timeout: 60_000, + }, + }); + + const actorLog: string[] = []; + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: { + // Override onActionStart (actor-level wins) + onActionStart: (name: string) => actorLog.push(`actor:${name}`), + }, + }); + + await actor.increment(5); + + // Actor-level overrode onActionStart + expect(clientLog).toEqual([]); + expect(actorLog).toEqual(["actor:increment"]); + }); + + test("concurrent actions track pendingActions correctly", async () => { + const rivet = createRivetKitWithClient({} as never); + + // Replace increment with a delayed mock + const conn = frameworkMock.currentState().connection; + let resolveFirst: ((v: number) => void) | undefined; + let resolveSecond: ((v: number) => void) | undefined; + let callCount = 0; + + conn.increment = vi.fn( + () => + new Promise((resolve) => { + callCount++; + if (callCount === 1) resolveFirst = resolve; + else resolveSecond = resolve; + }), + ); + + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + actionDefaults: {}, + }); + + const p1 = actor.increment(1); + expect(actor.pendingActions).toBe(1); + + const p2 = actor.increment(2); + expect(actor.pendingActions).toBe(2); + expect(actor.isMutating).toBe(true); + + resolveFirst?.(2); + await p1; + expect(actor.pendingActions).toBe(1); + expect(actor.isMutating).toBe(true); + + resolveSecond?.(3); + await p2; + expect(actor.pendingActions).toBe(0); + expect(actor.isMutating).toBe(false); + }); +}); diff --git a/rivetkit-typescript/packages/svelte/src/lib/__tests__/context.test.ts b/rivetkit-typescript/packages/svelte/src/lib/__tests__/context.test.ts new file mode 100644 index 0000000000..c69def8c54 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/__tests__/context.test.ts @@ -0,0 +1,62 @@ +import { beforeEach, describe, expect, test, vi } from "vitest"; + +const svelteMock = vi.hoisted(() => { + const markerContexts = new Map(); + const valueContexts = new Map(); + + return { + markerContexts, + valueContexts, + reset() { + markerContexts.clear(); + valueContexts.clear(); + }, + }; +}); + +vi.mock("svelte", () => ({ + createContext: () => { + const key = Symbol("rivet-context"); + return [ + () => svelteMock.valueContexts.get(key), + (value: unknown) => { + svelteMock.valueContexts.set(key, value); + return value; + }, + ] as const; + }, + hasContext: (key: symbol) => svelteMock.markerContexts.has(key), + setContext: (key: symbol, value: unknown) => { + svelteMock.markerContexts.set(key, value); + return value; + }, +})); + +import { createRivetContext } from "../context.js"; + +describe("createRivetContext", () => { + beforeEach(() => { + svelteMock.reset(); + }); + + test("supports set/get/has for typed contexts", () => { + const context = createRivetContext("TestRivet"); + const rivet = { + useActor: vi.fn(), + createReactiveActor: vi.fn(), + } as never; + + expect(context.has()).toBe(false); + expect(context.set(rivet)).toBe(rivet); + expect(context.has()).toBe(true); + expect(context.get()).toBe(rivet); + }); + + test("reports missing context with a descriptive error", () => { + const context = createRivetContext("TestRivet"); + + expect(() => context.get()).toThrow( + 'Context "TestRivet" not found. Create an app-local Rivet context and call TestRivet.set(...) or TestRivet.setup(...) in a parent layout.', + ); + }); +}); diff --git a/rivetkit-typescript/packages/svelte/src/lib/__tests__/helpers.ts b/rivetkit-typescript/packages/svelte/src/lib/__tests__/helpers.ts new file mode 100644 index 0000000000..c85303ee99 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/__tests__/helpers.ts @@ -0,0 +1,63 @@ +import type { ActorConn, AnyActorDefinition } from "rivetkit/client"; + +export type Status = "idle" | "connecting" | "connected" | "disconnected"; + +export function createMockConnection() { + let status: Status = "idle"; + const statusListeners = new Set<(status: Status) => void>(); + const errorListeners = new Set<(error: Error) => void>(); + const eventListeners = new Map void>>(); + + const connection = { + get connStatus() { + return status; + }, + onStatusChange(callback: (next: Status) => void) { + statusListeners.add(callback); + return () => statusListeners.delete(callback); + }, + onError(callback: (error: Error) => void) { + errorListeners.add(callback); + return () => errorListeners.delete(callback); + }, + on(eventName: string, callback: (...args: unknown[]) => void) { + let listeners = eventListeners.get(eventName); + if (!listeners) { + listeners = new Set(); + eventListeners.set(eventName, listeners); + } + listeners.add(callback); + return () => listeners?.delete(callback); + }, + async dispose() { + status = "disconnected"; + for (const listener of statusListeners) { + listener(status); + } + }, + ping() { + return "pong"; + }, + } as unknown as ActorConn & { ping(): string }; + + return { + connection, + setStatus(next: Status) { + status = next; + for (const listener of statusListeners) { + listener(status); + } + }, + emitError(message: string) { + const error = new Error(message); + for (const listener of errorListeners) { + listener(error); + } + }, + emit(eventName: string, ...args: unknown[]) { + for (const listener of eventListeners.get(eventName) ?? []) { + listener(...args); + } + }, + }; +} diff --git a/rivetkit-typescript/packages/svelte/src/lib/__tests__/reactive-actor.test.ts b/rivetkit-typescript/packages/svelte/src/lib/__tests__/reactive-actor.test.ts new file mode 100644 index 0000000000..c9f7ed39e2 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/__tests__/reactive-actor.test.ts @@ -0,0 +1,195 @@ +import "./runes-shim.js"; +import type { ActorConnStatus } from "rivetkit/client"; +import { beforeEach, describe, expect, test, vi } from "vitest"; + +const frameworkMock = vi.hoisted(() => { + type Listener = (...args: unknown[]) => void; + type Subscriber = (value: { currentVal: MockActorState }) => void; + type MockConnection = { + id: string; + ping: () => string; + on: (eventName: string, handler: Listener) => () => void; + emit: (eventName: string, ...args: unknown[]) => void; + }; + type MockActorState = { + connection: MockConnection; + handle: { id: string }; + connStatus: ActorConnStatus; + error: Error | null; + hash: string; + }; + + const subscribers = new Set(); + + function createConnection(id: string): MockConnection { + const listeners = new Map>(); + + return { + id, + ping: () => `pong:${id}`, + on(eventName: string, handler: Listener) { + let eventListeners = listeners.get(eventName); + if (!eventListeners) { + eventListeners = new Set(); + listeners.set(eventName, eventListeners); + } + + eventListeners.add(handler); + return () => eventListeners?.delete(handler); + }, + emit(eventName: string, ...args: unknown[]) { + for (const listener of listeners.get(eventName) ?? []) { + listener(...args); + } + }, + }; + } + + let currentState: MockActorState; + + const getOrCreateActor = vi.fn(() => ({ + mount: vi.fn(() => vi.fn()), + state: { + get state() { + return currentState; + }, + subscribe(callback: Subscriber) { + subscribers.add(callback); + return () => subscribers.delete(callback); + }, + }, + })); + + function push(next: Partial) { + currentState = { ...currentState, ...next }; + for (const subscriber of subscribers) { + subscriber({ currentVal: currentState }); + } + } + + function reset() { + subscribers.clear(); + currentState = { + connection: createConnection("one"), + handle: { id: "handle-one" }, + connStatus: "idle", + error: null, + hash: "hash-one", + }; + getOrCreateActor.mockClear(); + } + + reset(); + + return { + getOrCreateActor, + currentState: () => currentState, + push, + replaceConnection(id: string) { + const connection = createConnection(id); + push({ + connection, + handle: { id: `handle-${id}` }, + hash: `hash-${id}`, + }); + return connection; + }, + reset, + }; +}); + +vi.mock("@rivetkit/framework-base", () => ({ + createRivetKit: vi.fn(() => ({ + getOrCreateActor: frameworkMock.getOrCreateActor, + })), +})); + +import { createRivetKitWithClient } from "../rivetkit.svelte.js"; + +describe("createReactiveActor", () => { + beforeEach(() => { + frameworkMock.reset(); + }); + + test("caches proxied actor methods until the connection changes", () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + }); + + const firstPing = actor.ping; + const secondPing = actor.ping; + + expect(firstPing).toBe(secondPing); + expect(firstPing()).toBe("pong:one"); + + frameworkMock.replaceConnection("two"); + + const thirdPing = actor.ping; + expect(thirdPing).not.toBe(firstPing); + expect(thirdPing()).toBe("pong:two"); + }); + + test("preserves lastError and tracks hasEverConnected", () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + }); + + expect(actor.lastError).toBe(null); + expect(actor.hasEverConnected).toBe(false); + + frameworkMock.push({ + connStatus: "disconnected", + error: new Error("boom"), + }); + + expect(actor.error?.message).toBe("boom"); + expect(actor.lastError?.message).toBe("boom"); + expect(actor.hasEverConnected).toBe(false); + + frameworkMock.push({ + connStatus: "connected", + error: null, + }); + + expect(actor.isConnected).toBe(true); + expect(actor.hasEverConnected).toBe(true); + expect(actor.lastError?.message).toBe("boom"); + + frameworkMock.push({ + connStatus: "disconnected", + error: null, + }); + + expect(actor.error).toBe(null); + expect(actor.lastError?.message).toBe("boom"); + }); + + test("rebinds event listeners when the connection changes", () => { + const rivet = createRivetKitWithClient({} as never); + const actor = rivet.createReactiveActor({ + name: "chat" as never, + key: ["room-1"], + }); + + const firstConnection = frameworkMock.currentState().connection; + const received: string[] = []; + + actor.onEvent("message", (payload: unknown) => { + received.push(String(payload)); + }); + + firstConnection.emit("message", "one"); + expect(received).toEqual(["one"]); + + const secondConnection = frameworkMock.replaceConnection("two"); + + firstConnection.emit("message", "stale"); + secondConnection.emit("message", "two"); + + expect(received).toEqual(["one", "two"]); + }); +}); diff --git a/rivetkit-typescript/packages/svelte/src/lib/__tests__/runes-shim.ts b/rivetkit-typescript/packages/svelte/src/lib/__tests__/runes-shim.ts new file mode 100644 index 0000000000..2159790c17 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/__tests__/runes-shim.ts @@ -0,0 +1,12 @@ +const effect = ((fn?: () => unknown) => fn?.()) as unknown as { + (fn?: () => unknown): unknown; + root: (fn: () => undefined | (() => void)) => () => void; +}; + +effect.root = (fn) => { + const cleanup = fn(); + return typeof cleanup === "function" ? cleanup : () => {}; +}; + +(globalThis as Record).$state = (value: T) => value; +(globalThis as Record).$effect = effect; diff --git a/rivetkit-typescript/packages/svelte/src/lib/__tests__/shared.test.ts b/rivetkit-typescript/packages/svelte/src/lib/__tests__/shared.test.ts new file mode 100644 index 0000000000..505fa43fb5 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/__tests__/shared.test.ts @@ -0,0 +1,101 @@ +import "./runes-shim.js"; +import { describe, expect, test } from "vitest"; +import type { AnyActorRegistry } from "../index.js"; +import { + createReactiveConnection, + createSharedRivetKit, + withActorParams, +} from "../index.js"; +import { createMockConnection } from "./helpers.js"; + +describe("shared helpers", () => { + test("createSharedRivetKit reuses a single wrapper", () => { + const client = { id: "client" } as never; + let clientCalls = 0; + + const getRivet = createSharedRivetKit(() => { + clientCalls += 1; + return client; + }); + + const a = getRivet(); + const b = getRivet(); + + expect(a).toBe(b); + expect(clientCalls).toBe(1); + }); + + test("withActorParams merges static and getter params", () => { + let token = "first"; + + const getOpts = withActorParams( + { + name: "chat" as never, + key: ["room-1"], + params: { organizationId: "org-1" }, + }, + () => ({ token }), + ); + + expect(getOpts()).toEqual({ + name: "chat", + key: ["room-1"], + params: { organizationId: "org-1", token: "first" }, + }); + + token = "second"; + + expect(getOpts().params).toEqual({ + organizationId: "org-1", + token: "second", + }); + }); + + test("withActorParams omits params when both inputs are undefined", () => { + const getOpts = withActorParams( + { + name: "chat" as never, + key: ["room-1"], + }, + () => undefined, + ); + + expect(getOpts()).toEqual({ + name: "chat", + key: ["room-1"], + }); + }); + + test("createReactiveConnection reflects status, errors, and events", async () => { + const mock = createMockConnection(); + const reactive = createReactiveConnection({ + connect: () => mock.connection, + }); + + expect(reactive.connStatus).toBe("idle"); + expect(reactive.isConnected).toBe(false); + + reactive.connect(); + mock.setStatus("connected"); + + expect(reactive.connStatus).toBe("connected"); + expect(reactive.isConnected).toBe(true); + + let payload: string | null = null; + const unsubscribe = reactive.onEvent("message", (value) => { + payload = value as string; + }); + + mock.emit("message", "hello"); + expect(payload).toBe("hello"); + + mock.emitError("boom"); + expect(reactive.error?.message).toBe("boom"); + + unsubscribe(); + await reactive.dispose(); + + expect(reactive.connStatus).toBe("disconnected"); + expect(reactive.connection).toBe(null); + }); +}); diff --git a/rivetkit-typescript/packages/svelte/src/lib/connection-health.svelte.ts b/rivetkit-typescript/packages/svelte/src/lib/connection-health.svelte.ts new file mode 100644 index 0000000000..5b4bebf7be --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/connection-health.svelte.ts @@ -0,0 +1,186 @@ +/** + * Connection Health — Reactive aggregate health for multiple actor connections. + * + * Watches N named actor connections and derives an overall health status: + * - `"connected"` — all actors connected + * - `"degraded"` — some actors connected, some not + * - `"offline"` — no actors connected (and none are connecting) + * - `"connecting"` — no actors connected yet, but at least one is connecting/initializing + * + * Works with any object exposing `connStatus` and `error` getters — + * compatible with both `ReactiveActorHandle` and app-level ViewModels. + * + * @example + * ```typescript + * const health = createConnectionHealth(() => ({ + * user: { connStatus: userVM.connectionStatus, error: userVM.error }, + * notifications: { connStatus: notifsVM.connectionStatus, error: notifsVM.error }, + * })); + * + * // Reactive reads + * health.status // "connected" | "degraded" | "offline" | "connecting" + * health.connected // 2 + * health.total // 2 + * health.actors // { user: { status: "connected", error: null }, ... } + * ``` + * + * @module + */ + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +/** + * Minimal interface for an actor connection source. + * + * Accepts any connection status string — compatible with both + * `ActorConnStatus` (`"idle" | "connecting" | "connected" | "disconnected"`) + * and app-level ViewModel status (`"disconnected" | "connecting" | "connected" | "reconnecting" | "error"`). + * + * The health aggregator treats `"connected"` as healthy. Status values + * `"connecting"` and `"reconnecting"` are treated as "in-progress" (suppresses + * the `"offline"` state). All other values are treated as unhealthy. + */ +export interface ConnectionSource { + /** Current connection status string. */ + readonly connStatus: string; + /** Current error, or `null`. */ + readonly error: string | null; +} + +/** Aggregate health status across all monitored actors. */ +export type HealthStatus = "connected" | "degraded" | "offline" | "connecting"; + +/** Per-actor health snapshot. */ +export interface ActorHealth { + /** Whether this specific actor is connected. */ + readonly connected: boolean; + /** The raw connection status string from the source. */ + readonly status: string; + /** Current error message, or `null`. */ + readonly error: string | null; +} + +/** The reactive health object returned by {@link createConnectionHealth}. */ +export interface ConnectionHealth { + /** Aggregate status: all connected, some, none, or still connecting. */ + readonly status: HealthStatus; + /** Number of actors currently connected. */ + readonly connected: number; + /** Total number of monitored actors. */ + readonly total: number; + /** Per-actor health breakdown, keyed by the names you provided. */ + readonly actors: Readonly>; + /** Names of actors that are currently disconnected or errored. */ + readonly unhealthy: readonly K[]; +} + +// --------------------------------------------------------------------------- +// Factory +// --------------------------------------------------------------------------- + +/** + * Create a reactive connection health aggregator. + * + * Accepts a getter function that returns a record of named connection sources. + * The getter is re-evaluated reactively — when any source's `connStatus` or + * `error` changes, the derived health updates automatically. + * + * @param getSources - A getter returning `Record`. + * Must be a function (not a static object) so that reactive reads on each + * source's `connStatus` and `error` happen inside `$derived.by()`, where + * Svelte 5 can track them as dependencies. + * + * @returns A {@link ConnectionHealth} object with reactive getters. + * + * @example + * ```typescript + * // With ReactiveActorHandle (from createReactiveActor) + * const health = createConnectionHealth(() => ({ + * counter: myReactiveActor, // has connStatus + error getters + * chat: chatReactiveActor, + * })); + * + * // With app-level ViewModels (map to ConnectionSource shape) + * const health = createConnectionHealth(() => ({ + * user: { connStatus: userVM.connectionStatus, error: userVM.error }, + * org: { connStatus: orgVM.connectionStatus, error: orgVM.error }, + * })); + * ``` + */ +export function createConnectionHealth( + getSources: () => Record, +): ConnectionHealth { + // $derived.by() is required here because the computation is a multi-statement + // block (loop, conditionals). $derived only accepts a single expression. + // Svelte tracks all reactive reads inside the callback — connStatus and error + // on each source are read here, so any change re-runs this derivation. + const _health = $derived.by(() => { + const sources = getSources(); + // Object.keys() returns string[] — the cast to K[] is safe as long as + // getSources() returns exactly the keys declared in K. + const keys = Object.keys(sources) as K[]; + const total = keys.length; + + const actors = {} as Record; + const unhealthy: K[] = []; + let connectedCount = 0; + let connectingCount = 0; + + for (const key of keys) { + const src = sources[key]; + const isConnected = src.connStatus === "connected"; + const isConnecting = + src.connStatus === "connecting" || + src.connStatus === "reconnecting"; + + actors[key] = { + connected: isConnected, + status: src.connStatus, + error: src.error, + }; + + if (isConnected) { + connectedCount++; + } else { + unhealthy.push(key); + if (isConnecting) connectingCount++; + } + } + + let status: HealthStatus; + if (connectedCount === total && total > 0) { + status = "connected"; + } else if (connectedCount > 0) { + status = "degraded"; + } else if (connectingCount > 0 || total === 0) { + // No actors connected yet but some are in-progress, or no sources + // registered at all (treat empty registry as "not ready yet"). + status = "connecting"; + } else { + status = "offline"; + } + + return { status, connected: connectedCount, total, actors, unhealthy }; + }); + + // Return an object with getters so destructuring preserves reactivity. + return { + get status() { + return _health.status; + }, + get connected() { + return _health.connected; + }, + get total() { + return _health.total; + }, + get actors() { + return _health.actors; + }, + get unhealthy() { + return _health.unhealthy; + }, + }; +} diff --git a/rivetkit-typescript/packages/svelte/src/lib/context.ts b/rivetkit-typescript/packages/svelte/src/lib/context.ts new file mode 100644 index 0000000000..e156cf7f78 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/context.ts @@ -0,0 +1,84 @@ +/** + * Svelte context helpers for sharing a RivetKit instance through the + * component tree. + * + * Follows the type-safe context pattern established by runed and bits-ui. + * + * @module + */ + +import type { + AnyActorRegistry, + CreateRivetKitOptions, +} from "@rivetkit/framework-base"; +import type { Client } from "rivetkit/client"; +import { createContext, hasContext, setContext } from "svelte"; +import { + type createClient, + createRivetKit, + createRivetKitWithClient, + type RivetKit, +} from "./rivetkit.svelte.js"; + +export interface RivetContext { + set(rivet: RivetKit): RivetKit; + get(): RivetKit; + has(): boolean; + setup( + clientInput?: Parameters>[0], + opts?: CreateRivetKitOptions, + ): RivetKit; + setupWithClient( + client: Client, + opts?: CreateRivetKitOptions, + ): RivetKit; +} + +export function createRivetContext( + name = "RivetKit", +): RivetContext { + const markerKey = Symbol(name); + const [unsafeGetContext, unsafeSetContext] = + createContext>(); + + function has(): boolean { + return hasContext(markerKey); + } + + function get(): RivetKit { + if (!has()) { + throw new Error( + `Context "${name}" not found. Create an app-local Rivet context and call ${name}.set(...) or ${name}.setup(...) in a parent layout.`, + ); + } + + return unsafeGetContext(); + } + + function set(rivet: RivetKit): RivetKit { + setContext(markerKey, true); + return unsafeSetContext(rivet); + } + + function setup( + clientInput?: Parameters>[0], + opts?: CreateRivetKitOptions, + ): RivetKit { + return set(createRivetKit(clientInput, opts)); + } + + function setupWithClient( + client: Client, + opts?: CreateRivetKitOptions, + ): RivetKit { + return set(createRivetKitWithClient(client, opts)); + } + + return { + set, + get, + has, + setup, + setupWithClient, + }; +} diff --git a/rivetkit-typescript/packages/svelte/src/lib/index.ts b/rivetkit-typescript/packages/svelte/src/lib/index.ts new file mode 100644 index 0000000000..92b2224ede --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/index.ts @@ -0,0 +1,38 @@ +// Core API + +// Connection health +export { + type ActorHealth, + type ConnectionHealth, + type ConnectionSource, + createConnectionHealth, + type HealthStatus, +} from "./connection-health.svelte.js"; + +// Context helpers +export { createRivetContext, type RivetContext } from "./context.js"; +export { extract } from "./internal/extract.js"; +// Ecosystem-standard types (runed / melt-ui / bits-ui convention) +export type { Getter, MaybeGetter } from "./internal/types.js"; +export { + type ActionDefaults, + type ActorConnStatus, + type ActorOptions, + type ActorState, + type AnyActorRegistry, + createClient, + createRivetKit, + createRivetKitWithClient, + type PreloadActorOptions, + type ReactiveActorHandle, + type RivetKit, + type SvelteRivetKitOptions, +} from "./rivetkit.svelte.js"; +// Shared client / mixed-mode helpers +export { + createReactiveConnection, + createSharedRivetKit, + type ReactiveConnection, + type ReactiveConnectionSource, + withActorParams, +} from "./shared.svelte.js"; diff --git a/rivetkit-typescript/packages/svelte/src/lib/internal/extract.ts b/rivetkit-typescript/packages/svelte/src/lib/internal/extract.ts new file mode 100644 index 0000000000..448f6a99a9 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/internal/extract.ts @@ -0,0 +1,23 @@ +/** + * Resolve a {@link MaybeGetter} to its underlying value. + * + * If `value` is a function, it is invoked and its return value is used. + * If the resolved value is `undefined`, the optional `defaultValue` is + * returned instead. + * + * @param value - A value or a getter function returning the value. + * @param defaultValue - Fallback if the resolved value is `undefined`. + * @returns The resolved value, or the default. + */ +import type { MaybeGetter } from "./types.js"; + +export function extract(value: MaybeGetter): T; +export function extract( + value: MaybeGetter, + defaultValue: T, +): T; +export function extract(value: unknown, defaultValue?: unknown): unknown { + const resolved = + typeof value === "function" ? (value as () => unknown)() : value; + return resolved === undefined ? defaultValue : resolved; +} diff --git a/rivetkit-typescript/packages/svelte/src/lib/internal/index.ts b/rivetkit-typescript/packages/svelte/src/lib/internal/index.ts new file mode 100644 index 0000000000..733153f33b --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/internal/index.ts @@ -0,0 +1,2 @@ +export { extract } from "./extract.js"; +export type { Getter, MaybeGetter } from "./types.js"; diff --git a/rivetkit-typescript/packages/svelte/src/lib/internal/types.ts b/rivetkit-typescript/packages/svelte/src/lib/internal/types.ts new file mode 100644 index 0000000000..b60633b441 --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/internal/types.ts @@ -0,0 +1,12 @@ +/** + * Core utility types following the Svelte 5 ecosystem convention + * established by runed, melt-ui, and bits-ui. + * + * @module + */ + +/** A function that returns a value of type `T`. */ +export type Getter = () => T; + +/** A value of type `T`, or a getter function returning `T`. */ +export type MaybeGetter = T | Getter; diff --git a/rivetkit-typescript/packages/svelte/src/lib/rivetkit.svelte.ts b/rivetkit-typescript/packages/svelte/src/lib/rivetkit.svelte.ts new file mode 100644 index 0000000000..e32f191fef --- /dev/null +++ b/rivetkit-typescript/packages/svelte/src/lib/rivetkit.svelte.ts @@ -0,0 +1,1050 @@ +/** + * @rivetkit/svelte — Svelte 5 runes integration for RivetKit actors. + * + * Thin adapter over `@rivetkit/framework-base` that bridges actor state + * into Svelte 5 reactive primitives (`$state`, `$effect`). + * + * @module + */ + +import { + type ActorOptions, + type AnyActorRegistry, + type CreateRivetKitOptions, + createRivetKit as createVanillaRivetKit, +} from "@rivetkit/framework-base"; +import { BROWSER } from "esm-env"; +import { + type ActorConn, + type ActorConnStatus, + type ActorHandle, + type AnyActorDefinition, + type Client, + createClient, + type ExtractActorsFromRegistry, +} from "rivetkit/client"; +import { extract } from "./internal/extract.js"; +import type { MaybeGetter } from "./internal/types.js"; + +export type { + ActorConnStatus, + ActorOptions, + AnyActorRegistry, +} from "@rivetkit/framework-base"; +export { createClient } from "rivetkit/client"; + +// --------------------------------------------------------------------------- +// Preload types +// --------------------------------------------------------------------------- + +/** + * Options for preloading (warming) an actor without establishing a WebSocket + * connection. + * + * Only `name` and `key` are required — these identify the actor instance. + * `createWithInput` is optional and only needed if the actor may not exist yet + * and requires initialization data. + * + * @typeParam Registry - The actor registry type. + * @typeParam ActorName - The specific actor name within the registry. + */ +export interface PreloadActorOptions< + Registry extends AnyActorRegistry = AnyActorRegistry, + ActorName extends keyof ExtractActorsFromRegistry & + string = keyof ExtractActorsFromRegistry & string, +> { + /** Actor name in the registry. */ + name: ActorName; + /** Compound key identifying the actor instance. */ + key: string | string[]; + /** Optional initialization input (only used if actor doesn't exist yet). */ + createWithInput?: unknown; +} + +// --------------------------------------------------------------------------- +// Action middleware types +// --------------------------------------------------------------------------- + +/** + * Configuration for action call middleware. + * + * When provided to `useActor` or `createReactiveActor` (via `actionDefaults`), + * every proxied action call is wrapped with timeout, error capture, and + * reactive loading state tracking. + * + * Inspired by TanStack Query's mutation options and Zod's safeParse pattern: + * - Errors are captured to `lastActionError` reactive state by default + * - `throwOnError` controls whether the promise also rejects (default: `false`) + * - Lifecycle callbacks (`onActionStart`, `onActionSuccess`, etc.) fire + * at the definition level — always, regardless of component mount state + */ +export interface ActionDefaults { + /** + * Timeout in milliseconds for action calls. + * + * When an action exceeds this duration, the promise resolves to `undefined` + * (or rejects if `throwOnError` is enabled) and `lastActionError` is set + * to a timeout error. + * + * Default: none (actions run until the actor responds or the connection + * drops — Rivet's server-side `actionTimeout` is the ultimate backstop). + */ + timeout?: number; + + /** + * Controls whether action errors reject the returned promise. + * + * - `false` (default): Errors are captured to `lastActionError` reactive + * state. The promise resolves to `undefined`. This is the "safe" mode — + * no try/catch needed at the call site. + * - `true`: Errors are captured to `lastActionError` AND re-thrown. + * The caller must handle the rejection. + * - `(error, actionName) => boolean`: Called per-error to decide. + * + * Follows TanStack Query's mutation convention where reactive error state + * is the primary error channel in UI frameworks. + */ + throwOnError?: boolean | ((error: Error, actionName: string) => boolean); + + /** + * Guard against calling actions while disconnected. + * + * When `true` (default), actions called while the WebSocket connection is + * not established will immediately fail with a connection error instead of + * queuing or hanging. + */ + guardConnection?: boolean; + + /** Called when any action call starts. */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onActionStart?: (actionName: string, args: any[]) => void; + /** Called when an action completes successfully. */ + onActionSuccess?: (actionName: string, data: unknown) => void; + /** Called when an action fails (timeout, network, or actor error). */ + onActionError?: (error: Error, actionName: string) => void; + /** Called after an action completes (success or failure). */ + onActionSettled?: (actionName: string) => void; +} + +/** + * Internal interceptor function type. Built from {@link ActionDefaults} + * and passed to {@link proxyWithConnection}. + * + * @param actionName - The name of the actor action being called. + * @param args - Arguments passed to the action. + * @param call - The original action call (delegates to the live connection). + * @returns The action result, or `undefined` if the error was swallowed. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type ActionInterceptor = ( + actionName: string, + args: any[], + call: () => Promise, +) => Promise; + +// --------------------------------------------------------------------------- +// Shared types +// --------------------------------------------------------------------------- + +/** + * Proxied actor methods forwarded from the underlying connection at runtime. + * + * rivetkit 2.1.10 introduced deeply nested conditional types inside + * `ActorConn` that exceed TypeScript's instantiation depth limit when + * wrapped in `Omit`. This permissive index signature preserves the + * "call any actor action on the object" DX while avoiding TS2589. + * All reactive state properties above remain fully typed. + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type ProxiedActorMethods = Record any>; + +/** + * Reactive action tracking state, available when `actionDefaults` is configured. + * + * These properties are `$state`-backed — reads in `$derived`, `$effect`, + * or template expressions are automatically tracked by Svelte 5. + */ +interface ActionTrackingState { + /** `true` when any action call is in-flight. */ + readonly isMutating: boolean; + /** Number of concurrent in-flight action calls. */ + readonly pendingActions: number; + /** Most recent action error. Cleared on next successful action or {@link resetActionState}. */ + readonly lastActionError: Error | null; + /** Name of the last action that was called. */ + readonly lastAction: string | null; + /** Clear `lastActionError` and `lastAction` (return to clean state). */ + resetActionState(): void; +} + +/** + * Reactive actor state returned by {@link RivetKit.useActor | useActor}. + * + * All actor actions (e.g. `sendMessage`, `getState`) are available directly + * on the object via Proxy forwarding to the underlying connection. + * + * Every property is backed by Svelte 5 `$state` — reads inside + * `$derived` / `$effect` / template expressions are automatically tracked. + * + * @typeParam Registry - The actor registry type. + * @typeParam ActorName - The specific actor name within the registry. + */ +export type ActorState< + Registry extends AnyActorRegistry = AnyActorRegistry, + _ActorName extends keyof ExtractActorsFromRegistry & + string = keyof ExtractActorsFromRegistry & string, +> = { + /** The active WebSocket connection, or `null` when not connected. */ + readonly connection: ActorConn | null; + /** The actor handle used to create the connection. */ + readonly handle: ActorHandle | null; + /** Current connection lifecycle status (`"idle"` | `"connecting"` | `"connected"` | `"reconnecting"` | `"disconnected"`). */ + readonly connStatus: ActorConnStatus; + /** Last connection error, or `null`. */ + readonly error: Error | null; + /** Most recent non-null connection error observed for this actor. */ + readonly lastError: Error | null; + /** `true` when `connStatus === "connected"`. */ + readonly isConnected: boolean; + /** `true` once this actor has connected successfully at least once. */ + readonly hasEverConnected: boolean; + /** Internal hash identifying this actor instance. */ + readonly hash: string; + /** + * Subscribe to a named event broadcast by the actor. + * + * The subscription is automatically cleaned up when the component unmounts. + * Must be called during component initialization (alongside `useActor`). + * + * @param eventName - The event name to listen for. + * @param handler - Callback invoked when the event fires. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onEvent: (eventName: string, handler: (...args: any[]) => void) => void; +} & ActionTrackingState & + ProxiedActorMethods; + +/** + * Reactive actor handle returned by {@link RivetKit.createReactiveActor | createReactiveActor}. + * + * All actor actions are automatically available as methods via Proxy + * forwarding to the underlying connection. + * + * @typeParam Registry - The actor registry type. + * @typeParam ActorName - The specific actor name within the registry. + */ +export type ReactiveActorHandle< + Registry extends AnyActorRegistry, + _ActorName extends keyof ExtractActorsFromRegistry & string, +> = { + /** The active WebSocket connection, or `null` when not connected. */ + readonly connection: ActorConn | null; + /** The actor handle used to create the connection. */ + readonly handle: ActorHandle | null; + /** Current connection lifecycle status. */ + readonly connStatus: ActorConnStatus; + /** Last connection error, or `null`. */ + readonly error: Error | null; + /** Most recent non-null connection error observed for this actor. */ + readonly lastError: Error | null; + /** `true` when `connStatus === "connected"`. */ + readonly isConnected: boolean; + /** `true` once this actor has connected successfully at least once. */ + readonly hasEverConnected: boolean; + /** Internal hash identifying this actor instance. */ + readonly hash: string; + /** + * Start the connection lifecycle. + * + * Framework-base handles ref counting internally — multiple mounts + * to the same actor share one WebSocket. + * + * @returns An unmount function to decrement the ref count. + */ + mount(): () => void; + /** + * Clean up all event subscriptions and the framework-base state subscription. + * Call this when the reactive actor is no longer needed. + */ + dispose(): void; + /** + * Subscribe to an actor broadcast event. + * + * Automatically re-binds when the connection changes (e.g. after reconnect). + * + * @param eventName - The event name to listen for. + * @param handler - Callback invoked when the event fires. + * @returns An unsubscribe function. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onEvent(eventName: string, handler: (...args: any[]) => void): () => void; +} & ActionTrackingState & + ProxiedActorMethods; + +// --------------------------------------------------------------------------- +// Proxy helper — wraps a getter-based inner object so unknown props +// forward to the live actor connection. Used by both useActor and +// createReactiveActor. Closure-based $state avoids the Proxy + private +// field incompatibility that exists with Svelte 5 class-field $state. +// +// When an interceptAction function is provided (built from actionDefaults), +// every proxied method call is wrapped with it — enabling timeout, error +// capture, and reactive loading state tracking without manual wrapping. +// --------------------------------------------------------------------------- + +function proxyWithConnection( + inner: T, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + getConnection: () => ActorConn | null, + interceptAction?: ActionInterceptor, +): T { + const methodCache = new WeakMap>(); + + return new Proxy(inner, { + get(target, prop, receiver) { + if (Reflect.has(target, prop)) { + return Reflect.get(target, prop, receiver); + } + const conn = getConnection(); + if (conn && typeof prop === "string") { + const val = conn[prop as keyof typeof conn]; + if (typeof val === "function") { + let connMethods = methodCache.get(conn); + if (!connMethods) { + connMethods = new Map(); + methodCache.set(conn, connMethods); + } + + const cached = connMethods.get(prop); + if (cached) return cached; + + // When an interceptor is configured, wrap the call through it + // so action middleware (timeout, error capture, loading tracking) + // applies automatically to every proxied action call. + const bound = interceptAction + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + (...args: any[]) => + interceptAction(prop, args, () => + // biome-ignore lint/complexity/noBannedTypes: val is guaranteed to be a function here since it's proxied from the connection methods + (val as Function).apply(conn, args), + ) + : // eslint-disable-next-line @typescript-eslint/no-explicit-any + (...args: any[]) => + // biome-ignore lint/complexity/noBannedTypes: val is guaranteed to be a function here since it's proxied from the connection methods + (val as Function).apply(conn, args); + connMethods.set(prop, bound); + return bound; + } + + return val; + } + + // When an interceptor is configured and the connection is null, + // return a function that routes through the interceptor so the + // connection guard can fire and capture the error reactively. + // Without this, calling actor.someAction() when disconnected + // would throw TypeError: undefined is not a function. + if (interceptAction && !conn && typeof prop === "string") { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (...args: any[]) => + interceptAction(prop, args, () => + Promise.reject( + new Error( + `Action "${prop}" called while disconnected`, + ), + ), + ); + } + + return undefined; + }, + }); +} + +// --------------------------------------------------------------------------- +// Action defaults merge helper +// --------------------------------------------------------------------------- + +/** + * Shallow-merge client-level and actor-level action defaults. + * Actor-level values override client-level. `undefined` at actor level + * does NOT clear a client-level value (use explicit `null` convention + * if clearing is needed in the future). + */ +function mergeActionDefaults( + clientLevel: ActionDefaults | undefined, + actorLevel: ActionDefaults | undefined, +): ActionDefaults | undefined { + if (!clientLevel && !actorLevel) return undefined; + if (!clientLevel) return actorLevel; + if (!actorLevel) return clientLevel; + return { ...clientLevel, ...actorLevel }; +} + +// --------------------------------------------------------------------------- +// Public interface +// --------------------------------------------------------------------------- + +/** + * The main RivetKit instance — returned by {@link createRivetKit} and + * {@link createRivetKitWithClient}. + * + * Provides two APIs for connecting to actors: + * - {@link RivetKit.useActor | useActor} — component-scoped, `$effect`-managed lifecycle. + * - {@link RivetKit.createReactiveActor | createReactiveActor} — manual lifecycle for singletons and ViewModels. + * + * @typeParam Registry - The actor registry type. + */ +export interface RivetKit { + /** + * Connect to an actor and receive reactive state with auto-proxied methods. + * + * Must be called during component initialization (inside `