diff --git a/docs/docs/00-Ask AI/01-ask-ai.mdx b/docs/docs/00-ask-ai/01-ask-ai.mdx similarity index 100% rename from docs/docs/00-Ask AI/01-ask-ai.mdx rename to docs/docs/00-ask-ai/01-ask-ai.mdx diff --git a/docs/docs/00-Ask AI/_category_.json b/docs/docs/00-ask-ai/_category_.json similarity index 100% rename from docs/docs/00-Ask AI/_category_.json rename to docs/docs/00-ask-ai/_category_.json diff --git a/docs/docs/01-Intro/01-overview.md b/docs/docs/01-intro/01-overview.md similarity index 91% rename from docs/docs/01-Intro/01-overview.md rename to docs/docs/01-intro/01-overview.md index 35bfb5d0966..2e6c90ab9d9 100644 --- a/docs/docs/01-Intro/01-overview.md +++ b/docs/docs/01-intro/01-overview.md @@ -1,20 +1,30 @@ --- title: Overview +id: overview slug: / --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +import { InstallCardLink } from "@site/src/components/InstallCardLink"; +import { CardLink } from "@site/src/components/CardLink"; +import { CardLinkGrid } from "@site/src/components/CardLinkGrid"; +import { QuickstartLinks } from "@site/src/components/QuickstartLinks"; +import DocsList from "@site/src/components/DocsList"; # SpacetimeDB Documentation ## Installation -You can run SpacetimeDB as a standalone database server via the `spacetime` CLI tool. +You can get started by first installing the `spacetime` CLI tool. The `spacetime` CLI tool makes it extremely easy to manage your databases and deployments. -You can find the instructions to install the CLI tool for your platform [here](https://spacetimedb.com/install). + -To get started running your own standalone instance of SpacetimeDB check out our [Getting Started Guide](/getting-started). +## Quickstart Guides + +Choose your favorite language and follow one of our quickstart guides to get started building your first app with SpacetimeDB. + + ## What is SpacetimeDB? @@ -82,20 +92,20 @@ You write SQL queries specifying what information a client is interested in -- f Every SpacetimeDB database contains a collection of [stored procedures](https://en.wikipedia.org/wiki/Stored_procedure) and schema definitions. Such a collection is called a **module**, which can be written in C# or Rust. They specify a database schema and the business logic that responds to client requests. Modules are administered using the `spacetime` CLI tool. -- [Rust](/modules/rust) - [(Quickstart)](/modules/rust/quickstart) -- [C#](/modules/c-sharp) - [(Quickstart)](/modules/c-sharp/quickstart) +- [Rust](/modules/rust) - [(Quickstart)](/docs/quickstarts/rust) +- [C#](/modules/c-sharp) - [(Quickstart)](/docs/quickstarts/c-sharp) ### Client-side SDKs **Clients** are applications that connect to SpacetimeDB databases. The `spacetime` CLI tool supports automatically generating interface code that makes it easy to interact with a particular database. -- [Rust](/sdks/rust) - [(Quickstart)](/sdks/rust/quickstart) -- [C#](/sdks/c-sharp) - [(Quickstart)](/sdks/c-sharp/quickstart) -- [TypeScript](/sdks/typescript) - [(Quickstart)](/sdks/typescript/quickstart) +- [Rust](/sdks/rust) - [(Quickstart)](/docs/quickstarts/rust) +- [C#](/sdks/c-sharp) - [(Quickstart)](/docs/quickstarts/c-sharp) +- [TypeScript](/sdks/typescript) - [(Quickstart)](/docs/quickstarts/typescript) ### Unity -SpacetimeDB was designed first and foremost as the backend for multiplayer Unity games. To learn more about using SpacetimeDB with Unity, jump on over to the [SpacetimeDB Unity Tutorial](/unity/part-1). +SpacetimeDB was designed first and foremost as the backend for multiplayer Unity games. To learn more about using SpacetimeDB with Unity, jump on over to the [SpacetimeDB Unity Tutorial](/docs/tutorials/unity/part-1). ## Key architectural concepts @@ -111,7 +121,7 @@ A database exports [tables](#table), which store data, and [reducers](#reducer), A database's schema and business logic is specified by a piece of software called a **module**. Modules can be written in C# or Rust. -(Technically, a SpacetimeDB module is a [WebAssembly module](https://developer.mozilla.org/en-US/docs/WebAssembly) that imports a specific low-level [WebAssembly ABI](/webassembly-abi) and exports a small number of special functions. However, the SpacetimeDB [server-side libraries](#module-libraries) hide these low-level details. As a developer, writing a module is mostly like writing any other C# or Rust application, except for the fact that a [special CLI tool](https://spacetimedb.com/install) is used to deploy the application.) +(Technically, a SpacetimeDB module is a [WebAssembly module](https://developer.mozilla.org/en-US/docs/WebAssembly) that imports a specific low-level [WebAssembly ABI](/webassembly-abi) and exports a small number of special functions. However, the SpacetimeDB [server-side libraries](#module-libraries) hide these low-level details. As a developer, writing a module is mostly like writing any other C# or Rust application, except for the fact that a [special CLI tool](pathname:///install) is used to deploy the application.) ### Table @@ -346,4 +356,4 @@ A user has a single [`Identity`](#identity), but may open multiple connections t Follow our [Quick Start](/getting-started) guide! 1. How do I create a Unity game with SpacetimeDB? - Follow our [Unity Tutorial](/unity) guide! + Follow our [Unity Tutorial](/docs/tutorials/unity) guide! diff --git a/docs/docs/01-Intro/02-getting-started.md b/docs/docs/01-intro/02-getting-started.md similarity index 78% rename from docs/docs/01-Intro/02-getting-started.md rename to docs/docs/01-intro/02-getting-started.md index 12e74637800..15226b37096 100644 --- a/docs/docs/01-Intro/02-getting-started.md +++ b/docs/docs/01-intro/02-getting-started.md @@ -5,7 +5,7 @@ slug: /getting-started To develop SpacetimeDB databases locally, you will need to run the Standalone version of the server. -1. [Install](https://spacetimedb.com/install) the SpacetimeDB CLI (Command Line Interface) +1. [Install](pathname:///install) the SpacetimeDB CLI (Command Line Interface) 2. Run the start command: ```bash @@ -33,14 +33,14 @@ You are now ready to start developing SpacetimeDB modules. See below for a quick ### Server (Module) -- [Rust](/modules/rust/quickstart) -- [C#](/modules/c-sharp/quickstart) +- [Rust](/docs/quickstarts/rust) +- [C#](/docs/quickstarts/c-sharp) ⚡**Note:** Rust is [roughly 2x faster](https://faun.dev/c/links/faun/c-vs-rust-vs-go-a-performance-benchmarking-in-kubernetes/) than C# ### Client -- [Rust](/sdks/rust/quickstart) -- [C# (Standalone)](/sdks/c-sharp/quickstart) -- [C# (Unity)](/unity/part-1) -- [Typescript](/sdks/typescript/quickstart) +- [Rust](/docs/quickstarts/rust) +- [C# (Standalone)](/docs/quickstarts/c-sharp) +- [C# (Unity)](/docs/tutorials/unity/part-1) +- [Typescript](/docs/quickstarts/typescript) diff --git a/docs/docs/07-Client SDK Languages/06-typescript-quickstart.md b/docs/docs/02-quickstarts/01-typescript.md similarity index 74% rename from docs/docs/07-Client SDK Languages/06-typescript-quickstart.md rename to docs/docs/02-quickstarts/01-typescript.md index 558dd02b429..b3bc5d36fa8 100644 --- a/docs/docs/07-Client SDK Languages/06-typescript-quickstart.md +++ b/docs/docs/02-quickstarts/01-typescript.md @@ -1,22 +1,256 @@ --- -title: TypeScript Quickstart -slug: /sdks/typescript/quickstart +title: TypeScript +slug: /quickstarts/typescript +id: typescript --- -# TypeScript Client SDK Quickstart +import { InstallCardLink } from "@site/src/components/InstallCardLink"; -In this guide, you'll learn how to use TypeScript to create a SpacetimeDB client application. +# Quickstart Chat App -Please note that TypeScript is supported as a client language only. **Before you get started on this guide**, you should complete one of the quickstart guides for creating a SpacetimeDB server module listed below. +In this tutorial, we'll implement a simple chat server as a SpacetimeDB **TypeScript** module. -- [Rust](/modules/rust/quickstart) -- [C#](/modules/c-sharp/quickstart) +A SpacetimeDB module is code that gets bundled to a single JavaScript artifact and uploaded to SpacetimeDB. This code becomes server-side logic that interfaces directly with SpacetimeDB’s relational database. -By the end of this introduction, you will have created a basic single page web app which connects to the `quickstart-chat` database created in the above module quickstart guides. +Each SpacetimeDB module defines a set of **tables** and a set of **reducers**. + +- Tables are declared with `table({ ...opts }, { ...columns })`. Each inserted object is a row; each field is a column. +- Tables are **private** by default (readable only by the owner and your module code). Set `{ public: true }` to make them readable by everyone; writes still happen only via reducers. +- A **reducer** is a function that reads/writes the database. Each reducer runs in its own transaction; its writes commit only if it completes without throwing. In TypeScript, reducers are registered with `spacetimedb.reducer(name, argTypes, handler)` and throw `new SenderError("...")` for user-visible errors. + +:::note +SpacetimeDB runs your module inside the database host (not Node.js). There’s no direct filesystem or network access from reducers. +::: + +## Install SpacetimeDB + +If you haven’t already, start by [installing SpacetimeDB](pathname:///install). This installs the `spacetime` CLI used to build, publish, and interact with your database. + + + +## Project structure + +Let's start by running `spacetime init` to initialize our project's directory structure: + +```bash +spacetime init --lang typescript quickstart-chat +``` + +`spacetime init` will ask you for a project path in which to put your project. By default this will be `./quickstart-chat`. This basic project will have a few helper files like Cursor rules for SpacetimeDB and a `spacetimedb` directory which is where your SpacetimeDB module code will go. + +Inside the `spacetimedb/` directory will be a `src/index.ts` entrypoint (required for publishing). + +## Declare imports + +Open `spacetimedb/src/index.ts`. Replace its contents with the following imports to start building a bare-bones real-time chat server: + +```ts +import { schema, t, table, SenderError } from 'spacetimedb/server'; +``` + +From `spacetimedb/server`, we import: + +- `table` to define SpacetimeDB tables. +- `t` for column/type builders. +- `schema` to compose our database schema and register reducers. +- `SenderError` to signal user-visible (transaction-aborting) errors. + +## Define tables + +We’ll store two kinds of data: information about each user, and the messages that have been sent. + +For each `User`, we’ll store their `identity` (the caller’s unique identifier), an optional display `name`, and whether they’re currently `online`. We’ll use `identity` as the primary key (unique and indexed). + +Add to `spacetimedb/src/index.ts`: + +```ts +const User = table( + { name: 'user', public: true }, + { + identity: t.identity().primaryKey(), + name: t.string().optional(), + online: t.bool(), + } +); + +const Message = table( + { name: 'message', public: true }, + { + sender: t.identity(), + sent: t.timestamp(), + text: t.string(), + } +); + +// Compose the schema (gives us ctx.db.user and ctx.db.message, etc.) +const spacetimedb = schema(User, Message); +``` + +## Set users’ names + +We’ll allow users to set a display name, since raw identities aren’t user-friendly. Define a reducer `set_name` that validates input, looks up the caller’s `User` row by primary key, and updates it. If there’s no user row (e.g., the caller invoked via CLI without a connection and hasn’t connected before), we’ll return an error. + +Add: + +```ts +function validateName(name: string) { + if (!name) { + throw new SenderError('Names must not be empty'); + } +} + +spacetimedb.reducer('set_name', { name: t.string() }, (ctx, { name }) => { + validateName(name); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user) { + throw new SenderError('Cannot set name for unknown user'); + } + ctx.db.user.identity.update({ ...user, name }); +}); +``` + +You can extend `validateName` with moderation checks, Unicode normalization, printable-character filtering, max length checks, or duplicate-name rejection. + +## Send messages + +Define a reducer `send_message` to insert a new `Message` with the caller’s identity and the call timestamp. As with names, we’ll validate that text isn’t empty. + +Add: + +```ts +function validateMessage(text: string) { + if (!text) { + throw new SenderError('Messages must not be empty'); + } +} + +spacetimedb.reducer('send_message', { text: t.string() }, (ctx, { text }) => { + validateMessage(text); + console.info(`User ${ctx.sender}: ${text}`); + ctx.db.message.insert({ + sender: ctx.sender, + text, + sent: ctx.timestamp, + }); +}); +``` + +Possible extensions: + +- Reject messages from users who haven’t set a name. +- Rate-limit messages per user. + +## Set users’ online status + +SpacetimeDB can invoke lifecycle reducers when clients connect/disconnect. We’ll create or update a `User` row to mark the caller online on connect, and mark them offline on disconnect. + +Add: + +```ts +// Called once when the module bundle is installed / updated. +// We'll keep it empty for this quickstart. +spacetimedb.init(_ctx => {}); + +spacetimedb.clientConnected(ctx => { + const user = ctx.db.user.identity.find(ctx.sender); + if (user) { + // Returning user: set online=true, keep identity/name. + ctx.db.user.identity.update({ ...user, online: true }); + } else { + // New user: create a User row with no name yet. + ctx.db.user.insert({ + identity: ctx.sender, + name: undefined, + online: true, + }); + } +}); + +spacetimedb.clientDisconnected(ctx => { + const user = ctx.db.user.identity.find(ctx.sender); + if (user) { + ctx.db.user.identity.update({ ...user, online: false }); + } else { + // Shouldn't happen (disconnect without prior connect) + console.warn( + `Disconnect event for unknown user with identity ${ctx.sender}` + ); + } +}); +``` + +## Start the server + +If you haven’t already started the SpacetimeDB host on your machine, run this in a **separate terminal** and leave it running: + +```bash +spacetime start +``` + +(If it’s already running, you can skip this step.) + +## Publish the module + +From the `quickstart-chat` directory (the parent of `spacetimedb/`): + +```bash +spacetime publish --server local --project-path spacetimedb quickstart-chat +``` + +You can choose any unique, URL-safe database name in place of `quickstart-chat`. The CLI will show the database **Identity** (a hex string) as well; you can use either the name or identity with CLI commands. + +## Call reducers + +Use the CLI to call reducers. Arguments are passed as JSON (strings may be given bare for single string parameters). + +Send a message: + +```bash +spacetime call --server local quickstart-chat send_message "Hello, World!" +``` + +Check that it ran by viewing logs (owner-only): + +```bash +spacetime logs --server local quickstart-chat +``` + +You should see output similar to: + +```text + INFO: spacetimedb: Creating table `message` + INFO: spacetimedb: Creating table `user` + INFO: spacetimedb: Database initialized + INFO: console: User 0x...: Hello, World! +``` + +## SQL queries + +SpacetimeDB supports a subset of SQL so you can query your data: + +```bash +spacetime sql --server local quickstart-chat "SELECT * FROM message" +``` + +Output will resemble: + +```text + sender | sent | text +--------------------------------------------------------------------+----------------------------------+----------------- + 0x93dda09db9a56d8fa6c024d843e805d8262191db3b4ba84c5efcd1ad451fed4e | 2025-04-08T15:47:46.935402+00:00 | "Hello, World!" +``` + +You've just set up your first TypeScript module in SpacetimeDB! You can find the full code for this client [TypeScript server module example](https://github.com/clockworklabs/SpacetimeDB/tree/master/modules/quickstart-chat-ts). + +# Creating the client + +Next, you'll learn how to use TypeScript to create a SpacetimeDB client application. + +By the end of this introduction, you will have created a basic single page web app which connects to the `quickstart-chat` database you just created. ## Project structure -Enter the directory `quickstart-chat` you created in the [Rust Module Quickstart](/modules/rust/quickstart) or [C# Module Quickstart](/modules/c-sharp/quickstart) guides: +Enter the directory `quickstart-chat` you created in the [Rust Module Quickstart](/docs/quickstarts/rust) or [C# Module Quickstart](/docs/quickstarts/c-sharp) guides: ```bash cd quickstart-chat @@ -467,7 +701,7 @@ spacetime generate --lang typescript --out-dir client/src/module_bindings --proj :::note -This command assumes you've already created a server module in `quickstart-chat/server`. If you haven't completed one of the server module quickstart guides, you can follow either the [Rust](/modules/rust/quickstart) or [C#](/modules/c-sharp/quickstart) module quickstart to create one and then return here. +This command assumes you've already created a server module in `quickstart-chat/server`. If you haven't completed one of the server module quickstart guides, you can follow either the [Rust](/docs/quickstarts/rust) or [C#](/docs/quickstarts/c-sharp) module quickstart to create one and then return here. ::: diff --git a/docs/docs/07-Client SDK Languages/02-csharp-quickstart.md b/docs/docs/02-quickstarts/02-c-sharp.md similarity index 62% rename from docs/docs/07-Client SDK Languages/02-csharp-quickstart.md rename to docs/docs/02-quickstarts/02-c-sharp.md index ab382f91924..f3bfff6bdca 100644 --- a/docs/docs/07-Client SDK Languages/02-csharp-quickstart.md +++ b/docs/docs/02-quickstarts/02-c-sharp.md @@ -1,17 +1,324 @@ --- -title: C# Quickstart -slug: /sdks/c-sharp/quickstart +title: C# +slug: /quickstarts/c-sharp +id: c-sharp --- -# C# Client SDK Quick Start +import { InstallCardLink } from "@site/src/components/InstallCardLink"; -In this guide we'll show you how to get up and running with a simple SpacetimeDB app with a client written in C#. +# Quickstart Chat App -We'll implement a command-line client for the module created in our [Rust](../../modules/rust/quickstart) or [C# Module](../../modules/c-sharp/quickstart) Quickstart guides. Ensure you followed one of these guides before continuing. +In this tutorial, we'll implement a simple chat server as a SpacetimeDB module. + +A SpacetimeDB module is code that gets compiled to WebAssembly and is uploaded to SpacetimeDB. This code becomes server-side logic that interfaces directly with the Spacetime relational database. + +Each SpacetimeDB module defines a set of tables and a set of reducers. + +Each table is defined as a C# `class` annotated with `[SpacetimeDB.Table]`, where an instance represents a row, and each field represents a column. +By default, tables are **private**. This means that they are only readable by the table owner, and by server module code. +The `[SpacetimeDB.Table(Public = true))]` annotation makes a table public. **Public** tables are readable by all users, but can still only be modified by your server module code. + +A reducer is a function which traverses and updates the database. Each reducer call runs in its own transaction, and its updates to the database are only committed if the reducer returns successfully. In C#, reducers are defined as functions annotated with `[SpacetimeDB.Reducer]`. If an exception is thrown, the reducer call fails, the database is not updated, and a failed message is reported to the client. + +## Install SpacetimeDB + +If you haven't already, start by [installing SpacetimeDB](pathname:///install). This will install the `spacetime` command line interface (CLI), which contains all the functionality for interacting with SpacetimeDB. + + + +## Install .NET 8 + +Next we need to [install .NET 8 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) so that we can build and publish our module. + +You may already have .NET 8 and can be checked: + +```bash +dotnet --list-sdks +``` + +.NET 8.0 is the earliest to have the `wasi-experimental` workload that we rely on, but requires manual activation: + +```bash +dotnet workload install wasi-experimental +``` + +## Project structure + +Let's start by running `spacetime init` to initialize our project's directory structure: + +```bash +spacetime init --lang csharp quickstart-chat +``` + +`spacetime init` will ask you for a project path in which to put your project. By default this will be `./quickstart-chat`. This basic project will have a few helper files like Cursor rules for SpacetimeDB and a `spacetimedb` directory which is where your SpacetimeDB module code will go. + +## Declare imports + +`spacetime init` generated a few files: + +1. Open `spacetimedb/StdbModule.csproj` to generate a .sln file for intellisense/validation support. +2. Open `spacetimedb/Lib.cs`, a trivial module. +3. Clear it out, so we can write a new module that's still pretty simple: a bare-bones chat server. + +To start, we'll need to add `SpacetimeDB` to our using statements. This will give us access to everything we need to author our SpacetimeDB server module. + +To the top of `spacetimedb/Lib.cs`, add some imports we'll be using: + +```csharp +using SpacetimeDB; +``` + +We also need to create our static module class which all of the module code will live in. In `spacetimedb/Lib.cs`, add: + +```csharp +public static partial class Module +{ +} +``` + +## Define tables + +To get our chat server running, we'll need to store two kinds of data: information about each user, and records of all the messages that have been sent. + +For each `User`, we'll store their `Identity`, an optional name they can set to identify themselves to other users, and whether they're online or not. We'll designate the `Identity` as our primary key, which enforces that it must be unique, indexes it for faster lookup, and allows clients to track updates. + +In `spacetimedb/Lib.cs`, add the definition of the table `User` to the `Module` class: + +```csharp +[Table(Name = "user", Public = true)] +public partial class User +{ + [PrimaryKey] + public Identity Identity; + public string? Name; + public bool Online; +} +``` + +For each `Message`, we'll store the `Identity` of the user who sent it, the `Timestamp` when it was sent, and the text of the message. + +In `spacetimedb/Lib.cs`, add the definition of the table `Message` to the `Module` class: + +```csharp +[Table(Name = "message", Public = true)] +public partial class Message +{ + public Identity Sender; + public Timestamp Sent; + public string Text = ""; +} +``` + +## Set users' names + +We want to allow users to set their names, because `Identity` is not a terribly user-friendly identifier. To that effect, we define a reducer `SetName` which clients can invoke to set their `User.Name`. It will validate the caller's chosen name, using a function `ValidateName` which we'll define next, then look up the `User` record for the caller and update it to store the validated name. If the name fails the validation, the reducer will fail. + +Each reducer must accept as its first argument a `ReducerContext`, which includes contextual data such as the `Sender` which contains the Identity of the client that called the reducer, and the `Timestamp` when it was invoked. For now, we only need the `Sender`. + +It's also possible to call `SetName` via the SpacetimeDB CLI's `spacetime call` command without a connection, in which case no `User` record will exist for the caller. We'll return an error in this case, but you could alter the reducer to insert a `User` row for the module owner. You'll have to decide whether the module owner is always online or always offline, though. + +In `spacetimedb/Lib.cs`, add to the `Module` class: + +```csharp +[Reducer] +public static void SetName(ReducerContext ctx, string name) +{ + name = ValidateName(name); + + if (ctx.Db.user.Identity.Find(ctx.Sender) is User user) + { + user.Name = name; + ctx.Db.user.Identity.Update(user); + } +} +``` + +For now, we'll just do a bare minimum of validation, rejecting the empty name. You could extend this in various ways, like: + +- Comparing against a blacklist for moderation purposes. +- Unicode-normalizing names. +- Rejecting names that contain non-printable characters, or removing characters or replacing them with a placeholder. +- Rejecting or truncating long names. +- Rejecting duplicate names. + +In `spacetimedb/Lib.cs`, add to the `Module` class: + +```csharp +/// Takes a name and checks if it's acceptable as a user's name. +private static string ValidateName(string name) +{ + if (string.IsNullOrEmpty(name)) + { + throw new Exception("Names must not be empty"); + } + return name; +} +``` + +## Send messages + +We define a reducer `SendMessage`, which clients will call to send messages. It will validate the message's text, then insert a new `Message` record using `Message.Insert`, with the `Sender` identity and `Time` timestamp taken from the `ReducerContext`. + +In `spacetimedb/Lib.cs`, add to the `Module` class: + +```csharp +[Reducer] +public static void SendMessage(ReducerContext ctx, string text) +{ + text = ValidateMessage(text); + Log.Info(text); + ctx.Db.message.Insert( + new Message + { + Sender = ctx.Sender, + Text = text, + Sent = ctx.Timestamp, + } + ); +} +``` + +We'll want to validate messages' texts in much the same way we validate users' chosen names. As above, we'll do the bare minimum, rejecting only empty messages. + +In `spacetimedb/Lib.cs`, add to the `Module` class: + +```csharp +/// Takes a message's text and checks if it's acceptable to send. +private static string ValidateMessage(string text) +{ + if (string.IsNullOrEmpty(text)) + { + throw new ArgumentException("Messages must not be empty"); + } + return text; +} +``` + +You could extend the validation in `ValidateMessage` in similar ways to `ValidateName`, or add additional checks to `SendMessage`, like: + +- Rejecting messages from senders who haven't set their names. +- Rate-limiting users so they can't send new messages too quickly. + +## Set users' online status + +In C# modules, you can register for `Connect` and `Disconnect` events by using a special `ReducerKind`. We'll use the `Connect` event to create a `User` record for the client if it doesn't yet exist, and to set its online status. + +We'll use `reducerContext.Db.User.Identity.Find` to look up a `User` row for `ctx.Sender`, if one exists. If we find one, we'll use `reducerContext.Db.User.Identity.Update` to overwrite it with a row that has `Online: true`. If not, we'll use `User.Insert` to insert a new row for our new user. All three of these methods are generated by the `[SpacetimeDB.Table]` attribute, with rows and behavior based on the row attributes. `User.Identity.Find` returns a nullable `User`, because the unique constraint from the `[PrimaryKey]` attribute means there will be either zero or one matching rows. `Insert` will throw an exception if the insert violates this constraint; if we want to overwrite a `User` row, we need to do so explicitly using `User.Identity.Update`. + +In `spacetimedb/Lib.cs`, add the definition of the connect reducer to the `Module` class: + +```csharp +[Reducer(ReducerKind.ClientConnected)] +public static void ClientConnected(ReducerContext ctx) +{ + Log.Info($"Connect {ctx.Sender}"); + + if (ctx.Db.user.Identity.Find(ctx.Sender) is User user) + { + // If this is a returning user, i.e., we already have a `User` with this `Identity`, + // set `Online: true`, but leave `Name` and `Identity` unchanged. + user.Online = true; + ctx.Db.user.Identity.Update(user); + } + else + { + // If this is a new user, create a `User` object for the `Identity`, + // which is online, but hasn't set a name. + ctx.Db.user.Insert( + new User + { + Name = null, + Identity = ctx.Sender, + Online = true, + } + ); + } +} +``` + +Similarly, whenever a client disconnects, the database will execute the `OnDisconnect` event if it's registered with `ReducerKind.ClientDisconnected`. We'll use it to un-set the `Online` status of the `User` for the disconnected client. + +Add the following code after the `OnConnect` handler: + +```csharp +[Reducer(ReducerKind.ClientDisconnected)] +public static void ClientDisconnected(ReducerContext ctx) +{ + if (ctx.Db.user.Identity.Find(ctx.Sender) is User user) + { + // This user should exist, so set `Online: false`. + user.Online = false; + ctx.Db.user.Identity.Update(user); + } + else + { + // User does not exist, log warning + Log.Warn("Warning: No user found for disconnected client."); + } +} +``` + +## Start the Server + +If you haven't already started the SpacetimeDB server, run the `spacetime start` command in a _separate_ terminal and leave it running while you continue following along. + +## Publish the module + +And that's all of our module code! We'll run `spacetime publish` to compile our module and publish it on SpacetimeDB. `spacetime publish` takes an optional name which will map to the database's unique address. Clients can connect either by name or by address, but names are much more pleasant. In this example, we'll be using `quickstart-chat`. Feel free to come up with a unique name, and in the CLI commands, replace where we've written `quickstart-chat` with the name you chose. + +From the `quickstart-chat` directory, run: + +```bash +spacetime publish --server local --project-path spacetimedb quickstart-chat +``` + +Note: If the WebAssembly optimizer `wasm-opt` is installed, `spacetime publish` will automatically optimize the Web Assembly output of the published module. Instruction for installing the `wasm-opt` binary can be found in [Rust's wasm-opt documentation](https://docs.rs/wasm-opt/latest/wasm_opt/). + +## Call Reducers + +You can use the CLI (command line interface) to run reducers. The arguments to the reducer are passed in JSON format. + +```bash +spacetime call --server local quickstart-chat SendMessage "Hello, World!" +``` + +Once we've called our `SendMessage` reducer, we can check to make sure it ran by running the `logs` command. + +```bash +spacetime logs --server local quickstart-chat +``` + +You should now see the output that your module printed in the database. + +```bash +info: Hello, World! +``` + +## SQL Queries + +SpacetimeDB supports a subset of the SQL syntax so that you can easily query the data of your database. We can run a query using the `sql` command. + +```bash +spacetime sql --server local quickstart-chat "SELECT * FROM message" +``` + +```bash + sender | sent | text +--------------------------------------------------------------------+----------------------------------+----------------- + 0x93dda09db9a56d8fa6c024d843e805d8262191db3b4ba84c5efcd1ad451fed4e | 2025-04-08T15:47:46.935402+00:00 | "Hello, world!" +``` + +You've just set up your first database in SpacetimeDB! You can find the full code for this module [in the C# server module example](https://github.com/clockworklabs/SpacetimeDB/tree/master/sdks/csharp/examples~/quickstart-chat/server). + + +# Creating the client +Next, we'll show you how to get up and running with a simple SpacetimeDB app with a client written in C#. + +We'll implement a command-line client for the module created in our [Rust](/docs/quickstarts/rust) or [C# Module](/docs/quickstarts/c-sharp) Quickstart guides. Ensure you followed one of these guides before continuing. ## Project structure -Enter the directory `quickstart-chat` you created in the [Rust Module Quickstart](/modules/rust/quickstart) or [C# Module Quickstart](/modules/c-sharp/quickstart) guides: +Enter the directory `quickstart-chat` you created in the [Rust Module Quickstart](/docs/quickstarts/rust) or [C# Module Quickstart](/docs/quickstarts/c-sharp) guides: ```bash cd quickstart-chat @@ -565,4 +872,4 @@ You can find the full code for this client [in the C# client SDK's examples](htt Check out the [C# client SDK Reference](/sdks/c-sharp) for a more comprehensive view of the SpacetimeDB C# client SDK. -If you are interested in developing in the Unity game engine, check out our [Unity Comprehensive Tutorial](/unity) and [Blackholio](https://github.com/clockworklabs/SpacetimeDB/tree/master/demo/Blackholio) game example. +If you are interested in developing in the Unity game engine, check out our [Unity Comprehensive Tutorial](/docs/tutorials/unity) and [Blackholio](https://github.com/clockworklabs/SpacetimeDB/tree/master/demo/Blackholio) game example. diff --git a/docs/docs/07-Client SDK Languages/04-rust-quickstart.md b/docs/docs/02-quickstarts/03-rust.md similarity index 62% rename from docs/docs/07-Client SDK Languages/04-rust-quickstart.md rename to docs/docs/02-quickstarts/03-rust.md index bf3b50616da..d853723c75d 100644 --- a/docs/docs/07-Client SDK Languages/04-rust-quickstart.md +++ b/docs/docs/02-quickstarts/03-rust.md @@ -1,17 +1,306 @@ --- -title: Rust Quickstart -slug: /sdks/rust/quickstart +title: Rust +slug: /quickstarts/rust +id: rust --- -# Rust Client SDK Quick Start +import { InstallCardLink } from "@site/src/components/InstallCardLink"; -In this guide we'll show you how to get up and running with a simple SpacetimeDB app with a client written in Rust. +# Quickstart Chat App + +In this tutorial, we'll implement a simple chat server as a SpacetimeDB module. + +A SpacetimeDB module is code that gets compiled to a WebAssembly binary and is uploaded to SpacetimeDB. This code becomes server-side logic that interfaces directly with the SpacetimeDB relational database. + +Each SpacetimeDB module defines a set of tables and a set of reducers. + +Each table is defined as a Rust struct annotated with `#[table(name = table_name)]`. An instance of the struct represents a row, and each field represents a column. + +By default, tables are **private**. This means that they are only readable by the table owner, and by server module code. +The `#[table(name = table_name, public)]` macro makes a table public. **Public** tables are readable by all users but can still only be modified by your server module code. + +A reducer is a function that traverses and updates the database. Each reducer call runs in its own transaction, and its updates to the database are only committed if the reducer returns successfully. In Rust, reducers are defined as functions annotated with `#[reducer]`, and may return a `Result<()>`, with an `Err` return aborting the transaction. + +## Install SpacetimeDB + +If you haven't already, start by [installing SpacetimeDB](pathname:///install). This will install the `spacetime` command line interface (CLI), which provides all the functionality needed to interact with SpacetimeDB. + + + +## Install Rust + +Next we need to [install Rust](https://www.rust-lang.org/tools/install) so that we can create our database module. + +On macOS and Linux run this command to install the Rust compiler: + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +If you're on Windows, go [here](https://learn.microsoft.com/en-us/windows/dev-environment/rust/setup). + +## Project structure + +Let's start by running `spacetime init` to initialize our project's directory structure: + +```bash +spacetime init --lang rust quickstart-chat +``` + +`spacetime init` will ask you for a project path in which to put your project. By default this will be `./quickstart-chat`. This basic project will have a few helper files like Cursor rules for SpacetimeDB and a `spacetimedb` directory which is where your SpacetimeDB module code will go. + +## How to Compile + +> [!IMPORTANT] +> While it is possible to use the traditional `cargo build` to build SpacetimeDB server modules, `spacetime build` makes this process easier. Keep this in mind when using an IDE that assumes using _cargo_ for building. + +```bash +cd spacetimedb +spacetime build +``` + +## Declare imports + +`spacetime init` should have pre-populated `spacetimedb/src/lib.rs` with a trivial module. Clear it out so we can write a new, simple module: a bare-bones chat server. + +To the top of `spacetimedb/src/lib.rs`, add some imports we'll be using: + +```rust +use spacetimedb::{table, reducer, Table, ReducerContext, Identity, Timestamp}; +``` + +From `spacetimedb`, we import: + +- `table`, a macro used to define SpacetimeDB tables. +- `reducer`, a macro used to define SpacetimeDB reducers. +- `Table`, a rust trait which allows us to interact with tables. +- `ReducerContext`, a special argument passed to each reducer. +- `Identity`, a unique identifier for each user. +- `Timestamp`, a point in time. Specifically, an unsigned 64-bit count of milliseconds since the UNIX epoch. + +## Define tables + +To get our chat server running, we'll need to store two kinds of data: information about each user, and records of all the messages that have been sent. + +For each `User`, we'll store their `Identity`, an optional name they can set to identify themselves to other users, and whether they're online or not. We'll designate the `Identity` as our primary key, which enforces that it must be unique, indexes it for faster lookup, and allows clients to track updates. + +To `spacetimedb/src/lib.rs`, add the definition of the table `User`: + +```rust +#[table(name = user, public)] +pub struct User { + #[primary_key] + identity: Identity, + name: Option, + online: bool, +} +``` + +For each `Message`, we'll store the `Identity` of the user who sent it, the `Timestamp` when it was sent, and the text of the message. + +To `spacetimedb/src/lib.rs`, add the definition of the table `Message`: + +```rust +#[table(name = message, public)] +pub struct Message { + sender: Identity, + sent: Timestamp, + text: String, +} +``` + +## Set users' names + +We want to allow users to set their names, because `Identity` is not a terribly user-friendly identifier. To that effect, we define a reducer `set_name` which clients can invoke to set their `User.name`. It will validate the caller's chosen name, using a function `validate_name` which we'll define next, then look up the `User` record for the caller and update it to store the validated name. If the name fails the validation, the reducer will fail. + +Each reducer must accept as its first argument a `ReducerContext`, which includes the `Identity` and `ConnectionId` of the client that called the reducer, and the `Timestamp` when it was invoked. It also allows us access to the `db`, which is used to read and manipulate rows in our tables. For now, we only need the `db`, `Identity`, and `ctx.sender`. + +It's also possible to call `set_name` via the SpacetimeDB CLI's `spacetime call` command without a connection, in which case no `User` record will exist for the caller. We'll return an error in this case, but you could alter the reducer to insert a `User` row for the module owner. You'll have to decide whether the module owner is always online or always offline, though. + +To `spacetimedb/src/lib.rs`, add: + +```rust +#[reducer] +/// Clients invoke this reducer to set their user names. +pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { + let name = validate_name(name)?; + if let Some(user) = ctx.db.user().identity().find(ctx.sender) { + ctx.db.user().identity().update(User { name: Some(name), ..user }); + Ok(()) + } else { + Err("Cannot set name for unknown user".to_string()) + } +} +``` + +For now, we'll just do a bare minimum of validation, rejecting the empty name. You could extend this in various ways, like: + +- Comparing against a blacklist for moderation purposes. +- Unicode-normalizing names. +- Rejecting names that contain non-printable characters, or removing characters or replacing them with a placeholder. +- Rejecting or truncating long names. +- Rejecting duplicate names. + +To `spacetimedb/src/lib.rs`, add: + +```rust +/// Takes a name and checks if it's acceptable as a user's name. +fn validate_name(name: String) -> Result { + if name.is_empty() { + Err("Names must not be empty".to_string()) + } else { + Ok(name) + } +} +``` + +## Send messages + +We define a reducer `send_message`, which clients will call to send messages. It will validate the message's text, then insert a new `Message` record using `ctx.db.message().insert(..)`, with the `sender` identity and `sent` timestamp taken from the `ReducerContext`. Because the `Message` table does not have any columns with a unique constraint, `ctx.db.message().insert()` is infallible and does not return a `Result`. + +To `spacetimedb/src/lib.rs`, add: + +```rust +#[reducer] +/// Clients invoke this reducer to send messages. +pub fn send_message(ctx: &ReducerContext, text: String) -> Result<(), String> { + let text = validate_message(text)?; + log::info!("{}", text); + ctx.db.message().insert(Message { + sender: ctx.sender, + text, + sent: ctx.timestamp, + }); + Ok(()) +} +``` + +We'll want to validate messages' texts in much the same way we validate users' chosen names. As above, we'll do the bare minimum, rejecting only empty messages. + +To `spacetimedb/src/lib.rs`, add: + +```rust +/// Takes a message's text and checks if it's acceptable to send. +fn validate_message(text: String) -> Result { + if text.is_empty() { + Err("Messages must not be empty".to_string()) + } else { + Ok(text) + } +} +``` + +You could extend the validation in `validate_message` in similar ways to `validate_name`, or add additional checks to `send_message`, like: + +- Rejecting messages from senders who haven't set their names. +- Rate-limiting users so they can't send new messages too quickly. + +## Set users' online status + +Whenever a client connects, the database will run a special reducer, annotated with `#[reducer(client_connected)]`, if it's defined. By convention, it's named `client_connected`. We'll use it to create a `User` record for the client if it doesn't yet exist, and to set its online status. + +We'll use `ctx.db.user().identity().find(ctx.sender)` to look up a `User` row for `ctx.sender`, if one exists. If we find one, we'll use `ctx.db.user().identity().update(..)` to overwrite it with a row that has `online: true`. If not, we'll use `ctx.db.user().insert(..)` to insert a new row for our new user. All three of these methods are generated by the `#[table(..)]` macro, with rows and behavior based on the row attributes. `ctx.db.user().find(..)` returns an `Option`, because of the unique constraint from the `#[primary_key]` attribute. This means there will be either zero or one matching rows. If we used `try_insert` here it would return a `Result<(), UniqueConstraintViolation>` because of the same unique constraint. However, because we're already checking if there is a user with the given sender identity we know that inserting into this table will not fail. Therefore, we use `insert`, which automatically unwraps the result, simplifying the code. If we want to overwrite a `User` row, we need to do so explicitly using `ctx.db.user().identity().update(..)`. + +To `spacetimedb/src/lib.rs`, add the definition of the connect reducer: + +```rust +#[reducer(client_connected)] +// Called when a client connects to a SpacetimeDB database +pub fn client_connected(ctx: &ReducerContext) { + if let Some(user) = ctx.db.user().identity().find(ctx.sender) { + // If this is a returning user, i.e. we already have a `User` with this `Identity`, + // set `online: true`, but leave `name` and `identity` unchanged. + ctx.db.user().identity().update(User { online: true, ..user }); + } else { + // If this is a new user, create a `User` row for the `Identity`, + // which is online, but hasn't set a name. + ctx.db.user().insert(User { + name: None, + identity: ctx.sender, + online: true, + }); + } +} +``` + +Similarly, whenever a client disconnects, the database will run the `#[reducer(client_disconnected)]` reducer if it's defined. By convention, it's named `client_disconnected`. We'll use it to un-set the `online` status of the `User` for the disconnected client. + +```rust +#[reducer(client_disconnected)] +// Called when a client disconnects from SpacetimeDB database +pub fn identity_disconnected(ctx: &ReducerContext) { + if let Some(user) = ctx.db.user().identity().find(ctx.sender) { + ctx.db.user().identity().update(User { online: false, ..user }); + } else { + // This branch should be unreachable, + // as it doesn't make sense for a client to disconnect without connecting first. + log::warn!("Disconnect event for unknown user with identity {:?}", ctx.sender); + } +} +``` + +## Start the Server + +If you haven't already started the SpacetimeDB server, run the `spacetime start` command in a _separate_ terminal and leave it running while you continue following along. + +## Publish the module + +And that's all of our module code! We'll run `spacetime publish` to compile our module and publish it on SpacetimeDB. `spacetime publish` takes an optional name which will map to the database's unique `Identity`. Clients can connect either by name or by `Identity`, but names are much more user-friendly. If you'd like, come up with a unique name that contains only URL-safe characters (letters, numbers, hyphens and underscores), and fill it in where we've written `quickstart-chat`. + +From the `quickstart-chat` directory, run in another tab: + +```bash +spacetime publish --server local --project-path spacetimedb quickstart-chat +``` + +## Call Reducers + +You can use the CLI (command line interface) to run reducers. The arguments to the reducer are passed in JSON format. + +```bash +spacetime call --server local quickstart-chat send_message "Hello, World!" +``` + +Once we've called our `send_message` reducer, we can check to make sure it ran by running the `logs` command. + +```bash +spacetime logs --server local quickstart-chat +``` + +You should now see the output that your module printed in the database. + +```bash + INFO: spacetimedb: Creating table `message` + INFO: spacetimedb: Creating table `user` + INFO: spacetimedb: Database initialized + INFO: src/lib.rs:43: Hello, world! +``` + +## SQL Queries + +SpacetimeDB supports a subset of the SQL syntax so that you can easily query the data of your database. We can run a query using the `sql` command. + +```bash +spacetime sql --server local quickstart-chat "SELECT * FROM message" +``` + +```bash + sender | sent | text +--------------------------------------------------------------------+----------------------------------+----------------- + 0x93dda09db9a56d8fa6c024d843e805d8262191db3b4ba84c5efcd1ad451fed4e | 2025-04-08T15:47:46.935402+00:00 | "Hello, world!" +``` + +You've just set up your first Rust module in SpacetimeDB! You can find the full code for this module [in the SpacetimeDB module examples](https://github.com/clockworklabs/SpacetimeDB/tree/master/modules/quickstart-chat). + +# Creating the client + +Next, we'll show you how to get up and running with a simple SpacetimeDB app with a client written in Rust. We'll implement a command-line client for the module created in our Rust or C# Module Quickstart guides. Make sure you follow one of these guides before you start on this one. ## Project structure -Enter the directory `quickstart-chat` you created in the [Rust Module Quickstart](/modules/rust/quickstart) or [C# Module Quickstart](/modules/c-sharp/quickstart) guides: +Enter the directory `quickstart-chat` you created in the [Rust Module Quickstart](/docs/quickstarts/rust) or [C# Module Quickstart](/docs/quickstarts/c-sharp) guides: ```bash cd quickstart-chat diff --git a/docs/docs/04-Unreal Tutorial/01-overview.md b/docs/docs/02-unreal-tutorial/01-overview.md similarity index 91% rename from docs/docs/04-Unreal Tutorial/01-overview.md rename to docs/docs/02-unreal-tutorial/01-overview.md index 9c6121d0881..e8a5fb8de45 100644 --- a/docs/docs/04-Unreal Tutorial/01-overview.md +++ b/docs/docs/02-unreal-tutorial/01-overview.md @@ -1,6 +1,6 @@ --- title: Overview -slug: /unreal +slug: /tutorials/unreal --- # Unreal Tutorial - Overview @@ -29,10 +29,10 @@ Please file an issue [here](https://github.com/clockworklabs/SpacetimeDB/issues) First you'll get started with the core client/server setup. For part 2, you'll be able to choose between [Rust](/modules/rust) or [C#](/modules/c-sharp) for your server module language: -- [Part 1 - Setup](/unreal/part-1) -- [Part 2 - Connecting to SpacetimeDB](/unreal/part-2) -- [Part 3 - Gameplay](/unreal/part-3) -- [Part 4 - Moving and Colliding](/unreal/part-4) +- [Part 1 - Setup](/docs/tutorials/unreal/part-1) +- [Part 2 - Connecting to SpacetimeDB](/docs/tutorials/unreal/part-2) +- [Part 3 - Gameplay](/docs/tutorials/unreal/part-3) +- [Part 4 - Moving and Colliding](/docs/tutorials/unreal/part-4) ## Blackhol.io Tutorial - Advanced diff --git a/docs/docs/04-Unreal Tutorial/02-part-1.md b/docs/docs/02-unreal-tutorial/02-part-1.md similarity index 99% rename from docs/docs/04-Unreal Tutorial/02-part-1.md rename to docs/docs/02-unreal-tutorial/02-part-1.md index f31ffdc6013..e2c84e65e48 100644 --- a/docs/docs/04-Unreal Tutorial/02-part-1.md +++ b/docs/docs/02-unreal-tutorial/02-part-1.md @@ -1,6 +1,6 @@ --- title: 1 - Setup -slug: /unreal/part-1 +slug: /tutorials/unreal/part-1 --- import Tabs from '@theme/Tabs'; diff --git a/docs/docs/04-Unreal Tutorial/03-part-2.md b/docs/docs/02-unreal-tutorial/03-part-2.md similarity index 99% rename from docs/docs/04-Unreal Tutorial/03-part-2.md rename to docs/docs/02-unreal-tutorial/03-part-2.md index 46e54c95282..0776efec7cd 100644 --- a/docs/docs/04-Unreal Tutorial/03-part-2.md +++ b/docs/docs/02-unreal-tutorial/03-part-2.md @@ -1,6 +1,6 @@ --- title: 2 - Connecting to SpacetimeDB -slug: /unreal/part-2 +slug: /tutorials/unreal/part-2 --- import Tabs from '@theme/Tabs'; @@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem'; Need help with the tutorial? [Join our Discord server](https://discord.gg/spacetimedb)! -This progressive tutorial is continued from [part 1](/unreal/part-1). +This progressive tutorial is continued from [part 1](/docs/tutorials/unreal/part-1). ## Project Structure @@ -845,4 +845,4 @@ spacetime logs --server local blackholio You've learned how to setup a Unreal project with the SpacetimeDB SDK, write a basic SpacetimeDB server module, and how to connect your Unreal client to SpacetimeDB. That's pretty much all there is to the setup. You're now ready to start building the game. -In the [next part](/unreal/part-3), we'll build out the functionality of the game and you'll learn how to access your table data and call reducers in Unreal. +In the [next part](/docs/tutorials/unreal/part-3), we'll build out the functionality of the game and you'll learn how to access your table data and call reducers in Unreal. diff --git a/docs/docs/04-Unreal Tutorial/04-part-3.md b/docs/docs/02-unreal-tutorial/04-part-3.md similarity index 99% rename from docs/docs/04-Unreal Tutorial/04-part-3.md rename to docs/docs/02-unreal-tutorial/04-part-3.md index 7952f1a01d4..2c662f8c87d 100644 --- a/docs/docs/04-Unreal Tutorial/04-part-3.md +++ b/docs/docs/02-unreal-tutorial/04-part-3.md @@ -1,6 +1,6 @@ --- title: 3 - Gameplay -slug: /unreal/part-3 +slug: /tutorials/unreal/part-3 --- import Tabs from '@theme/Tabs'; @@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem'; Need help with the tutorial? [Join our Discord server](https://discord.gg/spacetimedb)! -This progressive tutorial is continued from [part 2](/unreal/part-2). +This progressive tutorial is continued from [part 2](/docs/tutorials/unreal/part-2). ### Spawning Food diff --git a/docs/docs/04-Unreal Tutorial/05-part-4.md b/docs/docs/02-unreal-tutorial/05-part-4.md similarity index 99% rename from docs/docs/04-Unreal Tutorial/05-part-4.md rename to docs/docs/02-unreal-tutorial/05-part-4.md index 3340f004076..4407186db55 100644 --- a/docs/docs/04-Unreal Tutorial/05-part-4.md +++ b/docs/docs/02-unreal-tutorial/05-part-4.md @@ -1,6 +1,6 @@ --- title: 4 - Moving and Colliding -slug: /unreal/part-4 +slug: /tutorials/unreal/part-4 --- import Tabs from '@theme/Tabs'; @@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem'; Need help with the tutorial? [Join our Discord server](https://discord.gg/spacetimedb)! -This progressive tutorial is continued from [part 3](/unreal/part-3). +This progressive tutorial is continued from [part 3](/docs/tutorials/unreal/part-3). ### Moving the player diff --git a/docs/docs/02-unreal-tutorial/_category_.json b/docs/docs/02-unreal-tutorial/_category_.json new file mode 100644 index 00000000000..d9dbcbbfb8e --- /dev/null +++ b/docs/docs/02-unreal-tutorial/_category_.json @@ -0,0 +1,3 @@ +{ + "label": "Unreal Engine Tutorial" +} \ No newline at end of file diff --git a/docs/docs/03-Unity Tutorial/01-overview.md b/docs/docs/03-unity-tutorial/01-overview.md similarity index 90% rename from docs/docs/03-Unity Tutorial/01-overview.md rename to docs/docs/03-unity-tutorial/01-overview.md index f3e02915f00..54663fb0f22 100644 --- a/docs/docs/03-Unity Tutorial/01-overview.md +++ b/docs/docs/03-unity-tutorial/01-overview.md @@ -1,6 +1,6 @@ --- title: Overview -slug: /unity +slug: /tutorials/unity --- # Unity Tutorial - Overview @@ -28,10 +28,10 @@ Please file an issue [here](https://github.com/clockworklabs/SpacetimeDB/issues) First you'll get started with the core client/server setup. For part 2, you'll be able to choose between [Rust](/modules/rust) or [C#](/modules/c-sharp) for your server module language: -- [Part 1 - Setup](/unity/part-1) -- [Part 2 - Connecting to SpacetimeDB](/unity/part-2) -- [Part 3 - Gameplay](/unity/part-3) -- [Part 4 - Moving and Colliding](/unity/part-4) +- [Part 1 - Setup](/docs/tutorials/unity/part-1) +- [Part 2 - Connecting to SpacetimeDB](/docs/tutorials/unity/part-2) +- [Part 3 - Gameplay](/docs/tutorials/unity/part-3) +- [Part 4 - Moving and Colliding](/docs/tutorials/unity/part-4) ## Blackhol.io Tutorial - Advanced diff --git a/docs/docs/03-Unity Tutorial/02-part-1.md b/docs/docs/03-unity-tutorial/02-part-1.md similarity index 99% rename from docs/docs/03-Unity Tutorial/02-part-1.md rename to docs/docs/03-unity-tutorial/02-part-1.md index 65d9baeb7b7..7980e8d9a4c 100644 --- a/docs/docs/03-Unity Tutorial/02-part-1.md +++ b/docs/docs/03-unity-tutorial/02-part-1.md @@ -1,6 +1,6 @@ --- title: 1 - Setup -slug: /unity/part-1 +slug: /tutorials/unity/part-1 --- import Tabs from '@theme/Tabs'; diff --git a/docs/docs/03-Unity Tutorial/03-part-2.md b/docs/docs/03-unity-tutorial/03-part-2.md similarity index 98% rename from docs/docs/03-Unity Tutorial/03-part-2.md rename to docs/docs/03-unity-tutorial/03-part-2.md index 4dca41cfc4b..4eb9527de10 100644 --- a/docs/docs/03-Unity Tutorial/03-part-2.md +++ b/docs/docs/03-unity-tutorial/03-part-2.md @@ -1,6 +1,6 @@ --- title: 2 - Connecting to SpacetimeDB -slug: /unity/part-2 +slug: /tutorials/unity/part-2 --- import Tabs from '@theme/Tabs'; @@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem'; Need help with the tutorial? [Join our Discord server](https://discord.gg/spacetimedb)! -This progressive tutorial is continued from [part 1](/unity/part-1). +This progressive tutorial is continued from [part 1](/docs/tutorials/unity/part-1). ## Project Structure @@ -688,4 +688,4 @@ spacetime logs --server local blackholio You've learned how to setup a Unity project with the SpacetimeDB SDK, write a basic SpacetimeDB server module, and how to connect your Unity client to SpacetimeDB. That's pretty much all there is to the setup. You're now ready to start building the game. -In the [next part](/unity/part-3), we'll build out the functionality of the game and you'll learn how to access your table data and call reducers in Unity. +In the [next part](/docs/tutorials/unity/part-3), we'll build out the functionality of the game and you'll learn how to access your table data and call reducers in Unity. diff --git a/docs/docs/03-Unity Tutorial/04-part-3.md b/docs/docs/03-unity-tutorial/04-part-3.md similarity index 99% rename from docs/docs/03-Unity Tutorial/04-part-3.md rename to docs/docs/03-unity-tutorial/04-part-3.md index 7d8ef993131..81083bc521f 100644 --- a/docs/docs/03-Unity Tutorial/04-part-3.md +++ b/docs/docs/03-unity-tutorial/04-part-3.md @@ -1,6 +1,6 @@ --- title: 3 - Gameplay -slug: /unity/part-3 +slug: /tutorials/unity/part-3 --- import Tabs from '@theme/Tabs'; @@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem'; Need help with the tutorial? [Join our Discord server](https://discord.gg/spacetimedb)! -This progressive tutorial is continued from [part 2](/unity/part-2). +This progressive tutorial is continued from [part 2](/docs/tutorials/unity/part-2). ### Spawning Food diff --git a/docs/docs/03-Unity Tutorial/05-part-4.md b/docs/docs/03-unity-tutorial/05-part-4.md similarity index 99% rename from docs/docs/03-Unity Tutorial/05-part-4.md rename to docs/docs/03-unity-tutorial/05-part-4.md index 83f38992a85..705c48e931c 100644 --- a/docs/docs/03-Unity Tutorial/05-part-4.md +++ b/docs/docs/03-unity-tutorial/05-part-4.md @@ -1,6 +1,6 @@ --- title: 4 - Moving and Colliding -slug: /unity/part-4 +slug: /tutorials/unity/part-4 --- import Tabs from '@theme/Tabs'; @@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem'; Need help with the tutorial? [Join our Discord server](https://discord.gg/spacetimedb)! -This progressive tutorial is continued from [part 3](/unity/part-3). +This progressive tutorial is continued from [part 3](/docs/tutorials/unity/part-3). ### Moving the player diff --git a/docs/docs/03-unity-tutorial/_category_.json b/docs/docs/03-unity-tutorial/_category_.json new file mode 100644 index 00000000000..1529c54abac --- /dev/null +++ b/docs/docs/03-unity-tutorial/_category_.json @@ -0,0 +1,3 @@ +{ + "label": "Unity Tutorial" +} \ No newline at end of file diff --git a/docs/docs/02-Deploying/01-maincloud.md b/docs/docs/04-deploying/01-maincloud.md similarity index 84% rename from docs/docs/02-Deploying/01-maincloud.md rename to docs/docs/04-deploying/01-maincloud.md index 9460f5cfc1e..6a3f5c3696a 100644 --- a/docs/docs/02-Deploying/01-maincloud.md +++ b/docs/docs/04-deploying/01-maincloud.md @@ -10,7 +10,7 @@ Maincloud is a managed cloud service that provides developers an easy way to dep ## Deploy via CLI -1. Install the SpacetimeDB CLI for your platform: [Install SpacetimeDB](https://spacetimedb.com/install) +1. Install the SpacetimeDB CLI for your platform: [Install SpacetimeDB](pathname:///install) 1. Create your module (see [Getting Started](/getting-started)) 1. Publish to Maincloud: @@ -30,7 +30,7 @@ spacetime login ``` 1. Open the SpacetimeDB website and log in using your GitHub login. -1. You should now be able to see your published modules [https://spacetimedb.com/profile](https://spacetimedb.com/profile), or you can navigate to your database directly at [https://spacetimedb.com/my-cool-module](https://spacetimedb.com/my-cool-module). +1. You should now be able to see your published modules [pathname:///profile](pathname:///profile), or you can navigate to your database directly at [pathname:///my-cool-module](pathname:///my-cool-module). --- diff --git a/docs/docs/02-Deploying/02-self-hosting.md b/docs/docs/04-deploying/02-self-hosting.md similarity index 100% rename from docs/docs/02-Deploying/02-self-hosting.md rename to docs/docs/04-deploying/02-self-hosting.md diff --git a/docs/docs/05-CLI Reference/01-cli-reference.md b/docs/docs/05-cli-reference/01-cli-reference.md similarity index 100% rename from docs/docs/05-CLI Reference/01-cli-reference.md rename to docs/docs/05-cli-reference/01-cli-reference.md diff --git a/docs/docs/05-CLI Reference/02-standalone-config.md b/docs/docs/05-cli-reference/02-standalone-config.md similarity index 100% rename from docs/docs/05-CLI Reference/02-standalone-config.md rename to docs/docs/05-cli-reference/02-standalone-config.md diff --git a/docs/docs/05-cli-reference/_category_.json b/docs/docs/05-cli-reference/_category_.json new file mode 100644 index 00000000000..aab0fa7b65e --- /dev/null +++ b/docs/docs/05-cli-reference/_category_.json @@ -0,0 +1,3 @@ +{ + "label": "CLI Reference" +} \ No newline at end of file diff --git a/docs/docs/06-Server Module Languages/02-rust-quickstart.md b/docs/docs/06-Server Module Languages/02-rust-quickstart.md deleted file mode 100644 index 87e921032e8..00000000000 --- a/docs/docs/06-Server Module Languages/02-rust-quickstart.md +++ /dev/null @@ -1,294 +0,0 @@ ---- -title: Rust Quickstart -slug: /modules/rust/quickstart ---- - -# Rust Module Quickstart - -In this tutorial, we'll implement a simple chat server as a SpacetimeDB module. - -A SpacetimeDB module is code that gets compiled to a WebAssembly binary and is uploaded to SpacetimeDB. This code becomes server-side logic that interfaces directly with the SpacetimeDB relational database. - -Each SpacetimeDB module defines a set of tables and a set of reducers. - -Each table is defined as a Rust struct annotated with `#[table(name = table_name)]`. An instance of the struct represents a row, and each field represents a column. - -By default, tables are **private**. This means that they are only readable by the table owner, and by server module code. -The `#[table(name = table_name, public)]` macro makes a table public. **Public** tables are readable by all users but can still only be modified by your server module code. - -A reducer is a function that traverses and updates the database. Each reducer call runs in its own transaction, and its updates to the database are only committed if the reducer returns successfully. In Rust, reducers are defined as functions annotated with `#[reducer]`, and may return a `Result<()>`, with an `Err` return aborting the transaction. - -## Install SpacetimeDB - -If you haven't already, start by [installing SpacetimeDB](https://spacetimedb.com/install). This will install the `spacetime` command line interface (CLI), which provides all the functionality needed to interact with SpacetimeDB. - -## Install Rust - -Next we need to [install Rust](https://www.rust-lang.org/tools/install) so that we can create our database module. - -On macOS and Linux run this command to install the Rust compiler: - -```bash -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` - -If you're on Windows, go [here](https://learn.microsoft.com/en-us/windows/dev-environment/rust/setup). - -## Project structure - -Let's start by running `spacetime init` to initialize our project's directory structure: - -```bash -spacetime init --lang rust quickstart-chat -``` - -`spacetime init` will ask you for a project path in which to put your project. By default this will be `./quickstart-chat`. This basic project will have a few helper files like Cursor rules for SpacetimeDB and a `spacetimedb` directory which is where your SpacetimeDB module code will go. - -## How to Compile - -> [!IMPORTANT] -> While it is possible to use the traditional `cargo build` to build SpacetimeDB server modules, `spacetime build` makes this process easier. Keep this in mind when using an IDE that assumes using _cargo_ for building. - -```bash -cd spacetimedb -spacetime build -``` - -## Declare imports - -`spacetime init` should have pre-populated `spacetimedb/src/lib.rs` with a trivial module. Clear it out so we can write a new, simple module: a bare-bones chat server. - -To the top of `spacetimedb/src/lib.rs`, add some imports we'll be using: - -```rust -use spacetimedb::{table, reducer, Table, ReducerContext, Identity, Timestamp}; -``` - -From `spacetimedb`, we import: - -- `table`, a macro used to define SpacetimeDB tables. -- `reducer`, a macro used to define SpacetimeDB reducers. -- `Table`, a rust trait which allows us to interact with tables. -- `ReducerContext`, a special argument passed to each reducer. -- `Identity`, a unique identifier for each user. -- `Timestamp`, a point in time. Specifically, an unsigned 64-bit count of milliseconds since the UNIX epoch. - -## Define tables - -To get our chat server running, we'll need to store two kinds of data: information about each user, and records of all the messages that have been sent. - -For each `User`, we'll store their `Identity`, an optional name they can set to identify themselves to other users, and whether they're online or not. We'll designate the `Identity` as our primary key, which enforces that it must be unique, indexes it for faster lookup, and allows clients to track updates. - -To `spacetimedb/src/lib.rs`, add the definition of the table `User`: - -```rust -#[table(name = user, public)] -pub struct User { - #[primary_key] - identity: Identity, - name: Option, - online: bool, -} -``` - -For each `Message`, we'll store the `Identity` of the user who sent it, the `Timestamp` when it was sent, and the text of the message. - -To `spacetimedb/src/lib.rs`, add the definition of the table `Message`: - -```rust -#[table(name = message, public)] -pub struct Message { - sender: Identity, - sent: Timestamp, - text: String, -} -``` - -## Set users' names - -We want to allow users to set their names, because `Identity` is not a terribly user-friendly identifier. To that effect, we define a reducer `set_name` which clients can invoke to set their `User.name`. It will validate the caller's chosen name, using a function `validate_name` which we'll define next, then look up the `User` record for the caller and update it to store the validated name. If the name fails the validation, the reducer will fail. - -Each reducer must accept as its first argument a `ReducerContext`, which includes the `Identity` and `ConnectionId` of the client that called the reducer, and the `Timestamp` when it was invoked. It also allows us access to the `db`, which is used to read and manipulate rows in our tables. For now, we only need the `db`, `Identity`, and `ctx.sender`. - -It's also possible to call `set_name` via the SpacetimeDB CLI's `spacetime call` command without a connection, in which case no `User` record will exist for the caller. We'll return an error in this case, but you could alter the reducer to insert a `User` row for the module owner. You'll have to decide whether the module owner is always online or always offline, though. - -To `spacetimedb/src/lib.rs`, add: - -```rust -#[reducer] -/// Clients invoke this reducer to set their user names. -pub fn set_name(ctx: &ReducerContext, name: String) -> Result<(), String> { - let name = validate_name(name)?; - if let Some(user) = ctx.db.user().identity().find(ctx.sender) { - ctx.db.user().identity().update(User { name: Some(name), ..user }); - Ok(()) - } else { - Err("Cannot set name for unknown user".to_string()) - } -} -``` - -For now, we'll just do a bare minimum of validation, rejecting the empty name. You could extend this in various ways, like: - -- Comparing against a blacklist for moderation purposes. -- Unicode-normalizing names. -- Rejecting names that contain non-printable characters, or removing characters or replacing them with a placeholder. -- Rejecting or truncating long names. -- Rejecting duplicate names. - -To `spacetimedb/src/lib.rs`, add: - -```rust -/// Takes a name and checks if it's acceptable as a user's name. -fn validate_name(name: String) -> Result { - if name.is_empty() { - Err("Names must not be empty".to_string()) - } else { - Ok(name) - } -} -``` - -## Send messages - -We define a reducer `send_message`, which clients will call to send messages. It will validate the message's text, then insert a new `Message` record using `ctx.db.message().insert(..)`, with the `sender` identity and `sent` timestamp taken from the `ReducerContext`. Because the `Message` table does not have any columns with a unique constraint, `ctx.db.message().insert()` is infallible and does not return a `Result`. - -To `spacetimedb/src/lib.rs`, add: - -```rust -#[reducer] -/// Clients invoke this reducer to send messages. -pub fn send_message(ctx: &ReducerContext, text: String) -> Result<(), String> { - let text = validate_message(text)?; - log::info!("{}", text); - ctx.db.message().insert(Message { - sender: ctx.sender, - text, - sent: ctx.timestamp, - }); - Ok(()) -} -``` - -We'll want to validate messages' texts in much the same way we validate users' chosen names. As above, we'll do the bare minimum, rejecting only empty messages. - -To `spacetimedb/src/lib.rs`, add: - -```rust -/// Takes a message's text and checks if it's acceptable to send. -fn validate_message(text: String) -> Result { - if text.is_empty() { - Err("Messages must not be empty".to_string()) - } else { - Ok(text) - } -} -``` - -You could extend the validation in `validate_message` in similar ways to `validate_name`, or add additional checks to `send_message`, like: - -- Rejecting messages from senders who haven't set their names. -- Rate-limiting users so they can't send new messages too quickly. - -## Set users' online status - -Whenever a client connects, the database will run a special reducer, annotated with `#[reducer(client_connected)]`, if it's defined. By convention, it's named `client_connected`. We'll use it to create a `User` record for the client if it doesn't yet exist, and to set its online status. - -We'll use `ctx.db.user().identity().find(ctx.sender)` to look up a `User` row for `ctx.sender`, if one exists. If we find one, we'll use `ctx.db.user().identity().update(..)` to overwrite it with a row that has `online: true`. If not, we'll use `ctx.db.user().insert(..)` to insert a new row for our new user. All three of these methods are generated by the `#[table(..)]` macro, with rows and behavior based on the row attributes. `ctx.db.user().find(..)` returns an `Option`, because of the unique constraint from the `#[primary_key]` attribute. This means there will be either zero or one matching rows. If we used `try_insert` here it would return a `Result<(), UniqueConstraintViolation>` because of the same unique constraint. However, because we're already checking if there is a user with the given sender identity we know that inserting into this table will not fail. Therefore, we use `insert`, which automatically unwraps the result, simplifying the code. If we want to overwrite a `User` row, we need to do so explicitly using `ctx.db.user().identity().update(..)`. - -To `spacetimedb/src/lib.rs`, add the definition of the connect reducer: - -```rust -#[reducer(client_connected)] -// Called when a client connects to a SpacetimeDB database -pub fn client_connected(ctx: &ReducerContext) { - if let Some(user) = ctx.db.user().identity().find(ctx.sender) { - // If this is a returning user, i.e. we already have a `User` with this `Identity`, - // set `online: true`, but leave `name` and `identity` unchanged. - ctx.db.user().identity().update(User { online: true, ..user }); - } else { - // If this is a new user, create a `User` row for the `Identity`, - // which is online, but hasn't set a name. - ctx.db.user().insert(User { - name: None, - identity: ctx.sender, - online: true, - }); - } -} -``` - -Similarly, whenever a client disconnects, the database will run the `#[reducer(client_disconnected)]` reducer if it's defined. By convention, it's named `client_disconnected`. We'll use it to un-set the `online` status of the `User` for the disconnected client. - -```rust -#[reducer(client_disconnected)] -// Called when a client disconnects from SpacetimeDB database -pub fn identity_disconnected(ctx: &ReducerContext) { - if let Some(user) = ctx.db.user().identity().find(ctx.sender) { - ctx.db.user().identity().update(User { online: false, ..user }); - } else { - // This branch should be unreachable, - // as it doesn't make sense for a client to disconnect without connecting first. - log::warn!("Disconnect event for unknown user with identity {:?}", ctx.sender); - } -} -``` - -## Start the Server - -If you haven't already started the SpacetimeDB , run the `spacetime start` command in a _separate_ terminal and leave it running while you continue following along. - -## Publish the module - -And that's all of our module code! We'll run `spacetime publish` to compile our module and publish it on SpacetimeDB. `spacetime publish` takes an optional name which will map to the database's unique `Identity`. Clients can connect either by name or by `Identity`, but names are much more user-friendly. If you'd like, come up with a unique name that contains only URL-safe characters (letters, numbers, hyphens and underscores), and fill it in where we've written `quickstart-chat`. - -From the `quickstart-chat` directory, run in another tab: - -```bash -spacetime publish --server local --project-path spacetimedb quickstart-chat -``` - -## Call Reducers - -You can use the CLI (command line interface) to run reducers. The arguments to the reducer are passed in JSON format. - -```bash -spacetime call --server local quickstart-chat send_message "Hello, World!" -``` - -Once we've called our `send_message` reducer, we can check to make sure it ran by running the `logs` command. - -```bash -spacetime logs --server local quickstart-chat -``` - -You should now see the output that your module printed in the database. - -```bash - INFO: spacetimedb: Creating table `message` - INFO: spacetimedb: Creating table `user` - INFO: spacetimedb: Database initialized - INFO: src/lib.rs:43: Hello, world! -``` - -## SQL Queries - -SpacetimeDB supports a subset of the SQL syntax so that you can easily query the data of your database. We can run a query using the `sql` command. - -```bash -spacetime sql --server local quickstart-chat "SELECT * FROM message" -``` - -```bash - sender | sent | text ---------------------------------------------------------------------+----------------------------------+----------------- - 0x93dda09db9a56d8fa6c024d843e805d8262191db3b4ba84c5efcd1ad451fed4e | 2025-04-08T15:47:46.935402+00:00 | "Hello, world!" -``` - -## What's next? - -You can find the full code for this module [in the SpacetimeDB module examples](https://github.com/clockworklabs/SpacetimeDB/tree/master/modules/quickstart-chat). - -You've just set up your first database in SpacetimeDB! The next step would be to create a client that interacts with this module. You can use any of SpacetimeDB's supported client languages to do this. Take a look at the quickstart guide for your client language of choice: [Rust](/sdks/rust/quickstart), [C#](/sdks/c-sharp/quickstart), or [TypeScript](/sdks/typescript/quickstart). - -If you are planning to use SpacetimeDB with the Unity game engine, you can skip right to the [Unity Comprehensive Tutorial](/unity/part-1). diff --git a/docs/docs/06-Server Module Languages/04-csharp-quickstart.md b/docs/docs/06-Server Module Languages/04-csharp-quickstart.md deleted file mode 100644 index 0097d22eb99..00000000000 --- a/docs/docs/06-Server Module Languages/04-csharp-quickstart.md +++ /dev/null @@ -1,312 +0,0 @@ ---- -title: C# Quickstart -slug: /modules/c-sharp/quickstart ---- - -# C# Module Quickstart - -In this tutorial, we'll implement a simple chat server as a SpacetimeDB module. - -A SpacetimeDB module is code that gets compiled to WebAssembly and is uploaded to SpacetimeDB. This code becomes server-side logic that interfaces directly with the Spacetime relational database. - -Each SpacetimeDB module defines a set of tables and a set of reducers. - -Each table is defined as a C# `class` annotated with `[SpacetimeDB.Table]`, where an instance represents a row, and each field represents a column. -By default, tables are **private**. This means that they are only readable by the table owner, and by server module code. -The `[SpacetimeDB.Table(Public = true))]` annotation makes a table public. **Public** tables are readable by all users, but can still only be modified by your server module code. - -A reducer is a function which traverses and updates the database. Each reducer call runs in its own transaction, and its updates to the database are only committed if the reducer returns successfully. In C#, reducers are defined as functions annotated with `[SpacetimeDB.Reducer]`. If an exception is thrown, the reducer call fails, the database is not updated, and a failed message is reported to the client. - -## Install SpacetimeDB - -If you haven't already, start by [installing SpacetimeDB](https://spacetimedb.com/install). This will install the `spacetime` command line interface (CLI), which contains all the functionality for interacting with SpacetimeDB. - -## Install .NET 8 - -Next we need to [install .NET 8 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) so that we can build and publish our module. - -You may already have .NET 8 and can be checked: - -```bash -dotnet --list-sdks -``` - -.NET 8.0 is the earliest to have the `wasi-experimental` workload that we rely on, but requires manual activation: - -```bash -dotnet workload install wasi-experimental -``` - -## Project structure - -Let's start by running `spacetime init` to initialize our project's directory structure: - -```bash -spacetime init --lang csharp quickstart-chat -``` - -`spacetime init` will ask you for a project path in which to put your project. By default this will be `./quickstart-chat`. This basic project will have a few helper files like Cursor rules for SpacetimeDB and a `spacetimedb` directory which is where your SpacetimeDB module code will go. - -## Declare imports - -`spacetime init` generated a few files: - -1. Open `spacetimedb/StdbModule.csproj` to generate a .sln file for intellisense/validation support. -2. Open `spacetimedb/Lib.cs`, a trivial module. -3. Clear it out, so we can write a new module that's still pretty simple: a bare-bones chat server. - -To start, we'll need to add `SpacetimeDB` to our using statements. This will give us access to everything we need to author our SpacetimeDB server module. - -To the top of `spacetimedb/Lib.cs`, add some imports we'll be using: - -```csharp -using SpacetimeDB; -``` - -We also need to create our static module class which all of the module code will live in. In `spacetimedb/Lib.cs`, add: - -```csharp -public static partial class Module -{ -} -``` - -## Define tables - -To get our chat server running, we'll need to store two kinds of data: information about each user, and records of all the messages that have been sent. - -For each `User`, we'll store their `Identity`, an optional name they can set to identify themselves to other users, and whether they're online or not. We'll designate the `Identity` as our primary key, which enforces that it must be unique, indexes it for faster lookup, and allows clients to track updates. - -In `spacetimedb/Lib.cs`, add the definition of the table `User` to the `Module` class: - -```csharp -[Table(Name = "user", Public = true)] -public partial class User -{ - [PrimaryKey] - public Identity Identity; - public string? Name; - public bool Online; -} -``` - -For each `Message`, we'll store the `Identity` of the user who sent it, the `Timestamp` when it was sent, and the text of the message. - -In `spacetimedb/Lib.cs`, add the definition of the table `Message` to the `Module` class: - -```csharp -[Table(Name = "message", Public = true)] -public partial class Message -{ - public Identity Sender; - public Timestamp Sent; - public string Text = ""; -} -``` - -## Set users' names - -We want to allow users to set their names, because `Identity` is not a terribly user-friendly identifier. To that effect, we define a reducer `SetName` which clients can invoke to set their `User.Name`. It will validate the caller's chosen name, using a function `ValidateName` which we'll define next, then look up the `User` record for the caller and update it to store the validated name. If the name fails the validation, the reducer will fail. - -Each reducer must accept as its first argument a `ReducerContext`, which includes contextual data such as the `Sender` which contains the Identity of the client that called the reducer, and the `Timestamp` when it was invoked. For now, we only need the `Sender`. - -It's also possible to call `SetName` via the SpacetimeDB CLI's `spacetime call` command without a connection, in which case no `User` record will exist for the caller. We'll return an error in this case, but you could alter the reducer to insert a `User` row for the module owner. You'll have to decide whether the module owner is always online or always offline, though. - -In `spacetimedb/Lib.cs`, add to the `Module` class: - -```csharp -[Reducer] -public static void SetName(ReducerContext ctx, string name) -{ - name = ValidateName(name); - - if (ctx.Db.user.Identity.Find(ctx.Sender) is User user) - { - user.Name = name; - ctx.Db.user.Identity.Update(user); - } -} -``` - -For now, we'll just do a bare minimum of validation, rejecting the empty name. You could extend this in various ways, like: - -- Comparing against a blacklist for moderation purposes. -- Unicode-normalizing names. -- Rejecting names that contain non-printable characters, or removing characters or replacing them with a placeholder. -- Rejecting or truncating long names. -- Rejecting duplicate names. - -In `spacetimedb/Lib.cs`, add to the `Module` class: - -```csharp -/// Takes a name and checks if it's acceptable as a user's name. -private static string ValidateName(string name) -{ - if (string.IsNullOrEmpty(name)) - { - throw new Exception("Names must not be empty"); - } - return name; -} -``` - -## Send messages - -We define a reducer `SendMessage`, which clients will call to send messages. It will validate the message's text, then insert a new `Message` record using `Message.Insert`, with the `Sender` identity and `Time` timestamp taken from the `ReducerContext`. - -In `spacetimedb/Lib.cs`, add to the `Module` class: - -```csharp -[Reducer] -public static void SendMessage(ReducerContext ctx, string text) -{ - text = ValidateMessage(text); - Log.Info(text); - ctx.Db.message.Insert( - new Message - { - Sender = ctx.Sender, - Text = text, - Sent = ctx.Timestamp, - } - ); -} -``` - -We'll want to validate messages' texts in much the same way we validate users' chosen names. As above, we'll do the bare minimum, rejecting only empty messages. - -In `spacetimedb/Lib.cs`, add to the `Module` class: - -```csharp -/// Takes a message's text and checks if it's acceptable to send. -private static string ValidateMessage(string text) -{ - if (string.IsNullOrEmpty(text)) - { - throw new ArgumentException("Messages must not be empty"); - } - return text; -} -``` - -You could extend the validation in `ValidateMessage` in similar ways to `ValidateName`, or add additional checks to `SendMessage`, like: - -- Rejecting messages from senders who haven't set their names. -- Rate-limiting users so they can't send new messages too quickly. - -## Set users' online status - -In C# modules, you can register for `Connect` and `Disconnect` events by using a special `ReducerKind`. We'll use the `Connect` event to create a `User` record for the client if it doesn't yet exist, and to set its online status. - -We'll use `reducerContext.Db.User.Identity.Find` to look up a `User` row for `ctx.Sender`, if one exists. If we find one, we'll use `reducerContext.Db.User.Identity.Update` to overwrite it with a row that has `Online: true`. If not, we'll use `User.Insert` to insert a new row for our new user. All three of these methods are generated by the `[SpacetimeDB.Table]` attribute, with rows and behavior based on the row attributes. `User.Identity.Find` returns a nullable `User`, because the unique constraint from the `[PrimaryKey]` attribute means there will be either zero or one matching rows. `Insert` will throw an exception if the insert violates this constraint; if we want to overwrite a `User` row, we need to do so explicitly using `User.Identity.Update`. - -In `spacetimedb/Lib.cs`, add the definition of the connect reducer to the `Module` class: - -```csharp -[Reducer(ReducerKind.ClientConnected)] -public static void ClientConnected(ReducerContext ctx) -{ - Log.Info($"Connect {ctx.Sender}"); - - if (ctx.Db.user.Identity.Find(ctx.Sender) is User user) - { - // If this is a returning user, i.e., we already have a `User` with this `Identity`, - // set `Online: true`, but leave `Name` and `Identity` unchanged. - user.Online = true; - ctx.Db.user.Identity.Update(user); - } - else - { - // If this is a new user, create a `User` object for the `Identity`, - // which is online, but hasn't set a name. - ctx.Db.user.Insert( - new User - { - Name = null, - Identity = ctx.Sender, - Online = true, - } - ); - } -} -``` - -Similarly, whenever a client disconnects, the database will execute the `OnDisconnect` event if it's registered with `ReducerKind.ClientDisconnected`. We'll use it to un-set the `Online` status of the `User` for the disconnected client. - -Add the following code after the `OnConnect` handler: - -```csharp -[Reducer(ReducerKind.ClientDisconnected)] -public static void ClientDisconnected(ReducerContext ctx) -{ - if (ctx.Db.user.Identity.Find(ctx.Sender) is User user) - { - // This user should exist, so set `Online: false`. - user.Online = false; - ctx.Db.user.Identity.Update(user); - } - else - { - // User does not exist, log warning - Log.Warn("Warning: No user found for disconnected client."); - } -} -``` - -## Start the Server - -If you haven't already started the SpacetimeDB server, run the `spacetime start` command in a _separate_ terminal and leave it running while you continue following along. - -## Publish the module - -And that's all of our module code! We'll run `spacetime publish` to compile our module and publish it on SpacetimeDB. `spacetime publish` takes an optional name which will map to the database's unique address. Clients can connect either by name or by address, but names are much more pleasant. In this example, we'll be using `quickstart-chat`. Feel free to come up with a unique name, and in the CLI commands, replace where we've written `quickstart-chat` with the name you chose. - -From the `quickstart-chat` directory, run: - -```bash -spacetime publish --server local --project-path spacetimedb quickstart-chat -``` - -Note: If the WebAssembly optimizer `wasm-opt` is installed, `spacetime publish` will automatically optimize the Web Assembly output of the published module. Instruction for installing the `wasm-opt` binary can be found in [Rust's wasm-opt documentation](https://docs.rs/wasm-opt/latest/wasm_opt/). - -## Call Reducers - -You can use the CLI (command line interface) to run reducers. The arguments to the reducer are passed in JSON format. - -```bash -spacetime call --server local quickstart-chat SendMessage "Hello, World!" -``` - -Once we've called our `SendMessage` reducer, we can check to make sure it ran by running the `logs` command. - -```bash -spacetime logs --server local quickstart-chat -``` - -You should now see the output that your module printed in the database. - -```bash -info: Hello, World! -``` - -## SQL Queries - -SpacetimeDB supports a subset of the SQL syntax so that you can easily query the data of your database. We can run a query using the `sql` command. - -```bash -spacetime sql --server local quickstart-chat "SELECT * FROM message" -``` - -```bash - sender | sent | text ---------------------------------------------------------------------+----------------------------------+----------------- - 0x93dda09db9a56d8fa6c024d843e805d8262191db3b4ba84c5efcd1ad451fed4e | 2025-04-08T15:47:46.935402+00:00 | "Hello, world!" -``` - -## What's next? - -You've just set up your first database in SpacetimeDB! You can find the full code for this client [in the C# server module example](https://github.com/clockworklabs/SpacetimeDB/tree/master/sdks/csharp/examples~/quickstart-chat/server). - -The next step would be to create a client that interacts with this module. You can use any of SpacetimeDB's supported client languages to do this. Take a look at the quick start guide for your client language of choice: [Rust](/sdks/rust/quickstart), [C#](/sdks/c-sharp/quickstart), or [TypeScript](/sdks/typescript/quickstart). - -If you are planning to use SpacetimeDB with the Unity game engine, you can skip right to the [Unity Comprehensive Tutorial](/unity/part-1). diff --git a/docs/docs/06-Server Module Languages/05-typescript-quickstart.md b/docs/docs/06-Server Module Languages/05-typescript-quickstart.md deleted file mode 100644 index 1331a92e2a7..00000000000 --- a/docs/docs/06-Server Module Languages/05-typescript-quickstart.md +++ /dev/null @@ -1,254 +0,0 @@ ---- -title: TypeScript Quickstart -slug: /modules/typescript/quickstart ---- - -# TypeScript Module Quickstart - -In this tutorial, we'll implement a simple chat server as a SpacetimeDB **TypeScript** module. - -A SpacetimeDB module is code that gets bundled to a single JavaScript artifact and uploaded to SpacetimeDB. This code becomes server-side logic that interfaces directly with SpacetimeDB’s relational database. - -Each SpacetimeDB module defines a set of **tables** and a set of **reducers**. - -- Tables are declared with `table({ ...opts }, { ...columns })`. Each inserted object is a row; each field is a column. -- Tables are **private** by default (readable only by the owner and your module code). Set `{ public: true }` to make them readable by everyone; writes still happen only via reducers. -- A **reducer** is a function that reads/writes the database. Each reducer runs in its own transaction; its writes commit only if it completes without throwing. In TypeScript, reducers are registered with `spacetimedb.reducer(name, argTypes, handler)` and throw `new SenderError("...")` for user-visible errors. - -:::note -SpacetimeDB runs your module inside the database host (not Node.js). There’s no direct filesystem or network access from reducers. -::: - -## Install SpacetimeDB - -If you haven’t already, start by [installing SpacetimeDB](https://spacetimedb.com/install). This installs the `spacetime` CLI used to build, publish, and interact with your database. - -## Project structure - -Let's start by running `spacetime init` to initialize our project's directory structure: - -```bash -spacetime init --lang typescript quickstart-chat -``` - -`spacetime init` will ask you for a project path in which to put your project. By default this will be `./quickstart-chat`. This basic project will have a few helper files like Cursor rules for SpacetimeDB and a `spacetimedb` directory which is where your SpacetimeDB module code will go. - -Inside the `spacetimedb/` directory will be a `src/index.ts` entrypoint (required for publishing). - -## Declare imports - -Open `spacetimedb/src/index.ts`. Replace its contents with the following imports to start building a bare-bones real-time chat server: - -```ts -import { schema, t, table, SenderError } from 'spacetimedb/server'; -``` - -From `spacetimedb/server`, we import: - -- `table` to define SpacetimeDB tables. -- `t` for column/type builders. -- `schema` to compose our database schema and register reducers. -- `SenderError` to signal user-visible (transaction-aborting) errors. - -## Define tables - -We’ll store two kinds of data: information about each user, and the messages that have been sent. - -For each `User`, we’ll store their `identity` (the caller’s unique identifier), an optional display `name`, and whether they’re currently `online`. We’ll use `identity` as the primary key (unique and indexed). - -Add to `spacetimedb/src/index.ts`: - -```ts -const User = table( - { name: 'user', public: true }, - { - identity: t.identity().primaryKey(), - name: t.string().optional(), - online: t.bool(), - } -); - -const Message = table( - { name: 'message', public: true }, - { - sender: t.identity(), - sent: t.timestamp(), - text: t.string(), - } -); - -// Compose the schema (gives us ctx.db.user and ctx.db.message, etc.) -const spacetimedb = schema(User, Message); -``` - -## Set users’ names - -We’ll allow users to set a display name, since raw identities aren’t user-friendly. Define a reducer `set_name` that validates input, looks up the caller’s `User` row by primary key, and updates it. If there’s no user row (e.g., the caller invoked via CLI without a connection and hasn’t connected before), we’ll return an error. - -Add: - -```ts -function validateName(name: string) { - if (!name) { - throw new SenderError('Names must not be empty'); - } -} - -spacetimedb.reducer('set_name', { name: t.string() }, (ctx, { name }) => { - validateName(name); - const user = ctx.db.user.identity.find(ctx.sender); - if (!user) { - throw new SenderError('Cannot set name for unknown user'); - } - ctx.db.user.identity.update({ ...user, name }); -}); -``` - -You can extend `validateName` with moderation checks, Unicode normalization, printable-character filtering, max length checks, or duplicate-name rejection. - -## Send messages - -Define a reducer `send_message` to insert a new `Message` with the caller’s identity and the call timestamp. As with names, we’ll validate that text isn’t empty. - -Add: - -```ts -function validateMessage(text: string) { - if (!text) { - throw new SenderError('Messages must not be empty'); - } -} - -spacetimedb.reducer('send_message', { text: t.string() }, (ctx, { text }) => { - validateMessage(text); - console.info(`User ${ctx.sender}: ${text}`); - ctx.db.message.insert({ - sender: ctx.sender, - text, - sent: ctx.timestamp, - }); -}); -``` - -Possible extensions: - -- Reject messages from users who haven’t set a name. -- Rate-limit messages per user. - -## Set users’ online status - -SpacetimeDB can invoke lifecycle reducers when clients connect/disconnect. We’ll create or update a `User` row to mark the caller online on connect, and mark them offline on disconnect. - -Add: - -```ts -// Called once when the module bundle is installed / updated. -// We'll keep it empty for this quickstart. -spacetimedb.init(_ctx => {}); - -spacetimedb.clientConnected(ctx => { - const user = ctx.db.user.identity.find(ctx.sender); - if (user) { - // Returning user: set online=true, keep identity/name. - ctx.db.user.identity.update({ ...user, online: true }); - } else { - // New user: create a User row with no name yet. - ctx.db.user.insert({ - identity: ctx.sender, - name: undefined, - online: true, - }); - } -}); - -spacetimedb.clientDisconnected(ctx => { - const user = ctx.db.user.identity.find(ctx.sender); - if (user) { - ctx.db.user.identity.update({ ...user, online: false }); - } else { - // Shouldn't happen (disconnect without prior connect) - console.warn( - `Disconnect event for unknown user with identity ${ctx.sender}` - ); - } -}); -``` - -## Start the server - -If you haven’t already started the SpacetimeDB host on your machine, run this in a **separate terminal** and leave it running: - -```bash -spacetime start -``` - -(If it’s already running, you can skip this step.) - -## Publish the module - -From the `spacetimedb/` directory you can lint/typecheck locally if you like, but to make the module live you’ll need to publish it to a database. Publishing bundles your TypeScript into a single artifact and installs it into the `quickstart-chat` database. - -> [!IMPORTANT] -> TypeScript modules are built and published with the `spacetime` CLI. `spacetime publish` will transpile and bundle your server module for you starting with the `src/index.ts` entrypoint. If you bundle your js yourself, you can specify `spacetime publish --js-path ` when publishing. - -From the `quickstart-chat` directory (the parent of `spacetimedb/`): - -```bash -spacetime publish --server local --project-path spacetimedb quickstart-chat -``` - -You can choose any unique, URL-safe database name in place of `quickstart-chat`. The CLI will show the database **Identity** (a hex string) as well; you can use either the name or identity with CLI commands. - -## Call reducers - -Use the CLI to call reducers. Arguments are passed as JSON (strings may be given bare for single string parameters). - -Send a message: - -```bash -spacetime call --server local quickstart-chat send_message "Hello, World!" -``` - -Check that it ran by viewing logs (owner-only): - -```bash -spacetime logs --server local quickstart-chat -``` - -You should see output similar to: - -```text - INFO: spacetimedb: Creating table `message` - INFO: spacetimedb: Creating table `user` - INFO: spacetimedb: Database initialized - INFO: console: User 0x...: Hello, World! -``` - -## SQL queries - -SpacetimeDB supports a subset of SQL so you can query your data: - -```bash -spacetime sql --server local quickstart-chat "SELECT * FROM message" -``` - -Output will resemble: - -```text - sender | sent | text ---------------------------------------------------------------------+----------------------------------+----------------- - 0x93dda09db9a56d8fa6c024d843e805d8262191db3b4ba84c5efcd1ad451fed4e | 2025-04-08T15:47:46.935402+00:00 | "Hello, World!" -``` - -## What’s next? - -You can find a complete version of this module in the SpacetimeDB examples. Next, build a client that interacts with your module using your preferred SDK: - -- [TypeScript client quickstart](/sdks/typescript/quickstart) -- [Rust client quickstart](/sdks/rust/quickstart) -- [C# client quickstart](/sdks/c-sharp/quickstart) - -- Using Unity? Jump to the [Unity Comprehensive Tutorial](/unity/part-1). -- Using Unreal Engine? Check out the [Unreal Comprehensive Tutorial](/unreal/part-1). - -You’ve just set up your first TypeScript module in SpacetimeDB—nice work! diff --git a/docs/docs/06-Server Module Languages/01-overview.md b/docs/docs/06-server-module-languages/01-overview.md similarity index 89% rename from docs/docs/06-Server Module Languages/01-overview.md rename to docs/docs/06-server-module-languages/01-overview.md index 3b94a3eee3b..a1b84d2ab0f 100644 --- a/docs/docs/06-Server Module Languages/01-overview.md +++ b/docs/docs/06-server-module-languages/01-overview.md @@ -16,11 +16,11 @@ In the following sections, we'll cover the basics of server modules and how to c Rust is the only fully supported language for server modules. Rust is a great option for server modules because it is fast, safe, and has a small runtime. - [Rust Module Reference](/modules/rust) -- [Rust Module Quickstart Guide](/modules/rust/quickstart) +- [Rust Module Quickstart Guide](/docs/quickstarts/rust) ### C We have C# support available. C# can be a good choice for developers who are already using Unity or .net for their client applications. - [C# Module Reference](/modules/c-sharp) -- [C# Module Quickstart Guide](/modules/c-sharp/quickstart) +- [C# Module Quickstart Guide](/docs/quickstarts/c-sharp) diff --git a/docs/docs/06-Server Module Languages/03-rust-reference.md b/docs/docs/06-server-module-languages/02-rust-reference.md similarity index 100% rename from docs/docs/06-Server Module Languages/03-rust-reference.md rename to docs/docs/06-server-module-languages/02-rust-reference.md diff --git a/docs/docs/06-Server Module Languages/04-csharp-reference.md b/docs/docs/06-server-module-languages/03-csharp-reference.md similarity index 97% rename from docs/docs/06-Server Module Languages/04-csharp-reference.md rename to docs/docs/06-server-module-languages/03-csharp-reference.md index d12e824e711..e8541c9aeea 100644 --- a/docs/docs/06-Server Module Languages/04-csharp-reference.md +++ b/docs/docs/06-server-module-languages/03-csharp-reference.md @@ -6,7 +6,7 @@ toc_max_heading_level: 6 # C# Module Library -[SpacetimeDB](https://spacetimedb.com/) allows using the C# language to write server-side applications called **modules**. Modules, which run inside a relational database, have direct access to database tables, and expose public functions called **reducers** that can be invoked over the network. Clients connect directly to the database to read data. +[SpacetimeDB](pathname:///) allows using the C# language to write server-side applications called **modules**. Modules, which run inside a relational database, have direct access to database tables, and expose public functions called **reducers** that can be invoked over the network. Clients connect directly to the database to read data. ```text Client Application SpacetimeDB @@ -25,11 +25,11 @@ toc_max_heading_level: 6 └───────────────────────┘ └───────────────────────┘ ``` -C# modules are written with the the C# Module Library (this package). They are built using the [dotnet CLI tool](https://learn.microsoft.com/en-us/dotnet/core/tools/) and deployed using the [`spacetime` CLI tool](https://spacetimedb.com/install). C# modules can import any [NuGet package](https://www.nuget.org/packages) that supports being compiled to WebAssembly. +C# modules are written with the the C# Module Library (this package). They are built using the [dotnet CLI tool](https://learn.microsoft.com/en-us/dotnet/core/tools/) and deployed using the [`spacetime` CLI tool](pathname:///install). C# modules can import any [NuGet package](https://www.nuget.org/packages) that supports being compiled to WebAssembly. (Note: C# can also be used to write **clients** of SpacetimeDB databases, but this requires using a different library, the SpacetimeDB C# Client SDK. See the documentation on [clients] for more information.) -This reference assumes you are familiar with the basics of C#. If you aren't, check out the [C# language documentation](https://learn.microsoft.com/en-us/dotnet/csharp/). For a guided introduction to C# Modules, see the [C# Module Quickstart](https://spacetimedb.com/docs/modules/c-sharp/quickstart). +This reference assumes you are familiar with the basics of C#. If you aren't, check out the [C# language documentation](https://learn.microsoft.com/en-us/dotnet/csharp/). For a guided introduction to C# Modules, see the [C# Module Quickstart](/docs/quickstarts/c-sharp). ## Overview @@ -68,7 +68,7 @@ Tables and reducers in C# modules can use any type annotated with [`[SpacetimeDB ## Setup -To create a C# module, install the [`spacetime` CLI tool](https://spacetimedb.com/install) in your preferred shell. Navigate to your work directory and run the following command: +To create a C# module, install the [`spacetime` CLI tool](pathname:///install) in your preferred shell. Navigate to your work directory and run the following command: ```bash spacetime init --lang csharp --project-path my-project-directory my-spacetimedb-project @@ -212,7 +212,7 @@ You can also generate code for clients of your module using the `spacetime gener ## How it works -Under the hood, SpacetimeDB modules are WebAssembly modules that import a [specific WebAssembly ABI](https://spacetimedb.com/docs/webassembly-abi) and export a small number of special functions. This is automatically configured when you add the `SpacetimeDB.Runtime` package as a dependency of your application. +Under the hood, SpacetimeDB modules are WebAssembly modules that import a [specific WebAssembly ABI](pathname:///docs/webassembly-abi) and export a small number of special functions. This is automatically configured when you add the `SpacetimeDB.Runtime` package as a dependency of your application. The SpacetimeDB host is an application that hosts SpacetimeDB databases. [Its source code is available](https://github.com/clockworklabs/SpacetimeDB) under [the Business Source License with an Additional Use Grant](https://github.com/clockworklabs/SpacetimeDB/blob/master/LICENSE.txt). You can run your own host, or you can upload your module to the public SpacetimeDB network. The network will create a database for you and install your module in it to serve client requests. @@ -406,7 +406,7 @@ Using the `[SpacetimeDB.Table(Name = "table_name", Public)]` flag makes a table (Note that, when run by the module owner, the `spacetime sql ` command can also read private tables. This is for debugging convenience. Only the module owner can see these tables. This is determined by the `Identity` stored by the `spacetime login` command. Run `spacetime login show` to print your current logged-in `Identity`.) -To learn how to subscribe to a public table, see the [client SDK documentation](https://spacetimedb.com/docs/sdks). +To learn how to subscribe to a public table, see the [client SDK documentation](pathname:///docs/sdks). ### Unique and Primary Key Columns @@ -1420,9 +1420,9 @@ When a [scheduled reducer](#scheduled-reducers) should execute, either at a spec Stored in reducer-scheduling tables as a column. -[client]: https://spacetimedb.com/docs/#client -[clients]: https://spacetimedb.com/docs/#client -[client SDK documentation]: https://spacetimedb.com/docs/#client +[client]: pathname:///docs/#client +[clients]: pathname:///docs/#client +[client SDK documentation]: pathname:///docs/#client [`DateTimeOffset`]: https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset?view=net-9.0 [`TimeSpan`]: https://learn.microsoft.com/en-us/dotnet/api/system.timespan?view=net-9.0 [unix epoch]: https://en.wikipedia.org/wiki/Unix_time diff --git a/docs/docs/06-Server Module Languages/06-Typescript-reference.md b/docs/docs/06-server-module-languages/04-typescript-reference.md similarity index 97% rename from docs/docs/06-Server Module Languages/06-Typescript-reference.md rename to docs/docs/06-server-module-languages/04-typescript-reference.md index 1cb32e26b5c..c3cd262500b 100644 --- a/docs/docs/06-Server Module Languages/06-Typescript-reference.md +++ b/docs/docs/06-server-module-languages/04-typescript-reference.md @@ -6,7 +6,7 @@ toc_max_heading_level: 6 # SpacetimeDB TypeScript Module Library -[SpacetimeDB](https://spacetimedb.com/) lets you write server-side applications (called **modules**) that run inside a relational database. Modules define **tables** (your data) and **reducers** (your server endpoints). Clients connect directly to the database to read public data via SQL subscriptions and queries, and they invoke reducers to mutate state. +[SpacetimeDB](pathname:///) lets you write server-side applications (called **modules**) that run inside a relational database. Modules define **tables** (your data) and **reducers** (your server endpoints). Clients connect directly to the database to read public data via SQL subscriptions and queries, and they invoke reducers to mutate state. ```text Client Application SpacetimeDB @@ -25,13 +25,13 @@ toc_max_heading_level: 6 └───────────────────────┘ └───────────────────────┘ ``` -TypeScript modules are built with the TypeScript Module Library from [`spacetimedb/server`](https://www.npmjs.com/package/spacetimedb). You define your schema and reducers in TypeScript, and then build and deploy with the [`spacetime` CLI](https://spacetimedb.com/install) using the `spacetime publish` command. Under the hood, SpacetimeDB uses [Rolldown](https://rolldown.rs/) to bundle your application into a single JavaScript artifact before uploading it to the SpacetimeDB host. +TypeScript modules are built with the TypeScript Module Library from [`spacetimedb/server`](https://www.npmjs.com/package/spacetimedb). You define your schema and reducers in TypeScript, and then build and deploy with the [`spacetime` CLI](pathname:///install) using the `spacetime publish` command. Under the hood, SpacetimeDB uses [Rolldown](https://rolldown.rs/) to bundle your application into a single JavaScript artifact before uploading it to the SpacetimeDB host. :::note SpacetimeDB also provides a TypeScript **client** SDK at `spacetimedb/sdk`, as well as integrations for frameworks like `spacetimedb/react`. This guide focuses exclusively on the **server-side module** library. ::: -If you’re new to TypeScript, see the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html). For a guided introduction to modules, see the [TypeScript Module Quickstart](/modules/typescript/quickstart). +If you’re new to TypeScript, see the [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html). For a guided introduction to modules, see the [TypeScript Module Quickstart](/docs/quickstarts/typescript). ## Overview @@ -71,7 +71,7 @@ Tables and reducers can use any types built with `t.*` (e.g., `t.string()`, `t.i ## Setup -1. **[Install the CLI](https://spacetimedb.com/install)** +1. **[Install the CLI](pathname:///install)** 2. **Initialize a TypeScript module project** @@ -115,7 +115,7 @@ spacetime publish where `` is the name of your existing database. -You can also generate client bindings for your schema with `spacetime generate`. See the [client SDK documentation](https://spacetimedb.com/docs/sdks/typescript#generate-module-bindings) for more information. +You can also generate client bindings for your schema with `spacetime generate`. See the [client SDK documentation](pathname:///docs/sdks/typescript#generate-module-bindings) for more information. # How it works diff --git a/docs/docs/06-server-module-languages/_category_.json b/docs/docs/06-server-module-languages/_category_.json new file mode 100644 index 00000000000..ee0ff1903db --- /dev/null +++ b/docs/docs/06-server-module-languages/_category_.json @@ -0,0 +1,3 @@ +{ + "label": "Server Module Languages" +} \ No newline at end of file diff --git a/docs/docs/07-Client SDK Languages/01-overview.md b/docs/docs/07-client-sdk-languages/01-overview.md similarity index 95% rename from docs/docs/07-Client SDK Languages/01-overview.md rename to docs/docs/07-client-sdk-languages/01-overview.md index c2ca56ded46..bb512d98192 100644 --- a/docs/docs/07-Client SDK Languages/01-overview.md +++ b/docs/docs/07-client-sdk-languages/01-overview.md @@ -7,9 +7,9 @@ SpacetimeDB Client SDKs Overview The SpacetimeDB Client SDKs provide a comprehensive interface to interact with the SpacetimeDB server engine from various programming languages. Currently, SDKs are available for -- [Rust](/sdks/rust) - [(Quickstart)](/sdks/rust/quickstart) -- [C#](/sdks/c-sharp) - [(Quickstart)](/sdks/c-sharp/quickstart) -- [TypeScript](/sdks/typescript) - [(Quickstart)](/sdks/typescript/quickstart) +- [Rust](/sdks/rust) - [(Quickstart)](/docs/quickstarts/rust) +- [C#](/sdks/c-sharp) - [(Quickstart)](/docs/quickstarts/c-sharp) +- [TypeScript](/sdks/typescript) - [(Quickstart)](/docs/quickstarts/typescript) ## Key Features diff --git a/docs/docs/07-Client SDK Languages/03-csharp-reference.md b/docs/docs/07-client-sdk-languages/02-csharp-reference.md similarity index 98% rename from docs/docs/07-Client SDK Languages/03-csharp-reference.md rename to docs/docs/07-client-sdk-languages/02-csharp-reference.md index 65fcce2fb06..9bc9bb5f2cf 100644 --- a/docs/docs/07-Client SDK Languages/03-csharp-reference.md +++ b/docs/docs/07-client-sdk-languages/02-csharp-reference.md @@ -32,7 +32,7 @@ If you would like to create a console application using .NET, you can create a n dotnet add package SpacetimeDB.ClientSDK ``` -(See also the [CSharp Quickstart](/modules/c-sharp/quickstart) for an in-depth example of such a console application.) +(See also the [CSharp Quickstart](/docs/quickstarts/c-sharp) for an in-depth example of such a console application.) ### Using Unity @@ -42,7 +42,7 @@ Add the SpacetimeDB Unity Package using the Package Manager. Open the Package Ma https://github.com/clockworklabs/com.clockworklabs.spacetimedbsdk.git ``` -(See also the [Unity Tutorial](/unity/part-1)) +(See also the [Unity Tutorial](/docs/tutorials/unity/part-1)) ## Generate module bindings @@ -819,7 +819,7 @@ class RemoteTableHandle The `OnInsert` callback runs whenever a new row is inserted into the client cache, either when applying a subscription or being notified of a transaction. The passed [`EventContext`](#type-eventcontext) contains an [`Event`](#record-event) which can identify the change which caused the insertion, and also allows the callback to interact with the connection, inspect the client cache and invoke reducers. Newly registered or canceled callbacks do not take effect until the following event. -See [the quickstart](/sdks/c-sharp/quickstart#register-callbacks) for examples of regstering and unregistering row callbacks. +See [the quickstart](/docs/quickstarts/c-sharp#register-callbacks) for examples of regstering and unregistering row callbacks. #### Callback `OnDelete` @@ -833,7 +833,7 @@ class RemoteTableHandle The `OnDelete` callback runs whenever a previously-resident row is deleted from the client cache. Newly registered or canceled callbacks do not take effect until the following event. -See [the quickstart](/sdks/c-sharp/quickstart#register-callbacks) for examples of regstering and unregistering row callbacks. +See [the quickstart](/docs/quickstarts/c-sharp#register-callbacks) for examples of regstering and unregistering row callbacks. #### Callback `OnUpdate` @@ -847,7 +847,7 @@ class RemoteTableHandle The `OnUpdate` callback runs whenever an already-resident row in the client cache is updated, i.e. replaced with a new row that has the same primary key. The table must have a primary key for callbacks to be triggered. Newly registered or canceled callbacks do not take effect until the following event. -See [the quickstart](/sdks/c-sharp/quickstart#register-callbacks) for examples of regstering and unregistering row callbacks. +See [the quickstart](/docs/quickstarts/c-sharp#register-callbacks) for examples of regstering and unregistering row callbacks. ### Unique constraint index access diff --git a/docs/docs/07-Client SDK Languages/05-rust-reference.md b/docs/docs/07-client-sdk-languages/03-rust-reference.md similarity index 100% rename from docs/docs/07-Client SDK Languages/05-rust-reference.md rename to docs/docs/07-client-sdk-languages/03-rust-reference.md diff --git a/docs/docs/07-Client SDK Languages/07-typescript-reference.md b/docs/docs/07-client-sdk-languages/04-typescript-reference.md similarity index 100% rename from docs/docs/07-Client SDK Languages/07-typescript-reference.md rename to docs/docs/07-client-sdk-languages/04-typescript-reference.md diff --git a/docs/docs/07-Client SDK Languages/08-unreal-reference.md b/docs/docs/07-client-sdk-languages/05-unreal-reference.md similarity index 100% rename from docs/docs/07-Client SDK Languages/08-unreal-reference.md rename to docs/docs/07-client-sdk-languages/05-unreal-reference.md diff --git a/docs/docs/07-client-sdk-languages/_category_.json b/docs/docs/07-client-sdk-languages/_category_.json new file mode 100644 index 00000000000..55668099934 --- /dev/null +++ b/docs/docs/07-client-sdk-languages/_category_.json @@ -0,0 +1,3 @@ +{ + "label": "Client SDK Languages" +} \ No newline at end of file diff --git a/docs/docs/08-sql/01-sql-reference.md b/docs/docs/08-sql/01-sql-reference.md new file mode 100644 index 00000000000..9c820a59b71 --- /dev/null +++ b/docs/docs/08-sql/01-sql-reference.md @@ -0,0 +1,664 @@ +--- +title: SQL Reference +slug: /sql +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# SQL Support + +SpacetimeDB supports two subsets of SQL: +One for queries issued through the [cli] or [http] api. +Another for subscriptions issued via the [sdk] or WebSocket api. + +## Subscriptions + +```ebnf +SELECT projection FROM relation [ WHERE predicate ] +``` + +The subscription language is strictly a query language. +Its sole purpose is to replicate a subset of the rows in the database, +and to **automatically** update them in realtime as the database changes. + +There is no context for manually updating this view. +Hence data manipulation commands like `INSERT` and `DELETE` are not supported. + +> NOTE: Because subscriptions are evaluated in realtime, +> performance is critical, and as a result, +> additional restrictions are applied over ad hoc queries. +> These restrictions are highlighted below. + +### SELECT + +```ebnf +SELECT ( '*' | table '.' '*' ) +``` + +The `SELECT` clause determines the table that is being subscribed to. +Since the subscription api is purely a replication api, +a query may only return rows from a single table, +and it must return the entire row. +Individual column projections are not allowed. + +A `*` projection is allowed when the table is unambiguous, +otherwise it must be qualified with the appropriate table name. + +#### Examples + +```sql +-- Subscribe to all rows of a table +SELECT * FROM Inventory + +-- Qualify the `*` projection with the table +SELECT item.* from Inventory item + +-- Subscribe to all customers who have orders totaling more than $1000 +SELECT customer.* +FROM Customers customer JOIN Orders o ON customer.id = o.customer_id +WHERE o.amount > 1000 + +-- INVALID: Must return `Customers` or `Orders`, but not both +SELECT * +FROM Customers customer JOIN Orders o ON customer.id = o.customer_id +WHERE o.amount > 1000 +``` + +### FROM + +```ebnf +FROM table [ [AS] alias ] [ [INNER] JOIN table [ [AS] alias ] ON column '=' column ] +``` + +While you can only subscribe to rows from a single table, +you may reference two tables in the `FROM` clause using a `JOIN`. +A `JOIN` selects all combinations of rows from its input tables, +and `ON` determines which combinations are considered. + +Subscriptions do not support joins of more than two tables. + +For any column referenced in `ON` clause of a `JOIN`, +it must be qualified with the appropriate table name or alias. + +In order for a `JOIN` to be evaluated efficiently, +subscriptions require an index to be defined on both join columns. + +#### Example + +```sql +-- Subscribe to all orders of products with less than 10 items in stock. +-- Must have an index on the `product_id` column of the `Orders` table, +-- as well as the `id` column of the `Product` table. +SELECT o.* +FROM Orders o JOIN Inventory product ON o.product_id = product.id +WHERE product.quantity < 10 + +-- Subscribe to all products that have at least one purchase +SELECT product.* +FROM Orders o JOIN Inventory product ON o.product_id = product.id + +-- INVALID: Must qualify the column names referenced in `ON` +SELECT product.* FROM Orders JOIN Inventory product ON product_id = id +``` + +### WHERE + +```ebnf +predicate + = expr + | predicate AND predicate + | predicate OR predicate + ; + +expr + = literal + | column + | expr op expr + ; + +op + = '=' + | '<' + | '>' + | '<' '=' + | '>' '=' + | '!' '=' + | '<' '>' + ; + +literal + = INTEGER + | STRING + | HEX + | TRUE + | FALSE + ; +``` + +While the `SELECT` clause determines the table, +the `WHERE` clause determines the rows in the subscription. + +Arithmetic expressions are not supported. + +#### Examples + +```sql +-- Find products that sell for more than $X +SELECT * FROM Inventory WHERE price > {X} + +-- Find products that sell for more than $X and have fewer than Y items in stock +SELECT * FROM Inventory WHERE price > {X} AND amount < {Y} +``` + +## Query and DML (Data Manipulation Language) + +### Statements + +- [SELECT](#select-1) +- [INSERT](#insert) +- [DELETE](#delete) +- [UPDATE](#update) +- [SET](#set) +- [SHOW](#show) + +### SELECT + +```ebnf +SELECT projection FROM relation [ WHERE predicate ] [LIMIT NUM] +``` + +The query languge is a strict superset of the subscription language. +The main differences are seen in column projections and [joins](#from-clause). + +The subscription api only supports `*` projections, +but the query api supports both individual column projections, +as well as aggregations in the form of `COUNT`. + +The subscription api limits the number of tables you can join, +and enforces index constraints on the join columns, +but the query language has no such constraints or limitations. + +#### SELECT Clause + +```ebnf +projection + = '*' + | table '.' '*' + | projExpr { ',' projExpr } + | aggExpr + ; + +projExpr + = column [ [ AS ] alias ] + ; + +aggExpr + = COUNT '(' '*' ')' [AS] alias + ; +``` + +The `SELECT` clause determines the columns that are returned. + +##### Examples + +```sql +-- Select the items in my inventory +SELECT * FROM Inventory; + +-- Select the names and prices of the items in my inventory +SELECT item_name, price FROM Inventory +``` + +It also allows for counting the number of input rows via the `COUNT` function. +`COUNT` always returns a single row, even if the input is empty. + +##### Example + +```sql +-- Count the items in my inventory +SELECT COUNT(*) AS n FROM Inventory +``` + +#### FROM Clause + +```ebnf +FROM table [ [AS] alias ] { [INNER] JOIN table [ [AS] alias ] ON predicate } +``` + +Unlike [subscriptions](#from), the query api supports joining more than two tables. + +##### Examples + +```sql +-- Find all customers who ordered a particular product and when they ordered it +SELECT customer.first_name, customer.last_name, o.date +FROM Customers customer +JOIN Orders o ON customer.id = o.customer_id +JOIN Inventory product ON o.product_id = product.id +WHERE product.name = {product_name} +``` + +#### WHERE Clause + +See [Subscriptions](#where). + +#### LIMIT clause + +Limits the number of rows a query returns by specifying an upper bound. +The `LIMIT` may return fewer rows if the query itself returns fewer rows. +`LIMIT` does not order or transform its input in any way. + +##### Examples + +```sql +-- Fetch an example row from my inventory +SELECT * FROM Inventory LIMIT 1 +``` + +### INSERT + +```ebnf +INSERT INTO table [ '(' column { ',' column } ')' ] VALUES '(' literal { ',' literal } ')' +``` + +#### Examples + +```sql +-- Inserting one row +INSERT INTO Inventory (item_id, item_name) VALUES (1, 'health1'); + +-- Inserting two rows +INSERT INTO Inventory (item_id, item_name) VALUES (1, 'health1'), (2, 'health2'); +``` + +### DELETE + +```ebnf +DELETE FROM table [ WHERE predicate ] +``` + +Deletes all rows from a table. +If `WHERE` is specified, only the matching rows are deleted. + +`DELETE` does not support joins. + +#### Examples + +```sql +-- Delete all rows +DELETE FROM Inventory; + +-- Delete all rows with a specific item_id +DELETE FROM Inventory WHERE item_id = 1; +``` + +### UPDATE + +```ebnf +UPDATE table SET [ '(' assignment { ',' assignment } ')' ] [ WHERE predicate ] +``` + +Updates column values of existing rows in a table. +The columns are identified by the `assignment` defined as `column '=' literal`. +The column values are updated for all rows that match the `WHERE` condition. +The rows are updated after the `WHERE` condition is evaluated for all rows. + +`UPDATE` does not support joins. + +#### Examples + +```sql +-- Update the item_name for all rows with a specific item_id +UPDATE Inventory SET item_name = 'new name' WHERE item_id = 1; +``` + +### SET + +> WARNING: The `SET` statement is experimental. +> Compatibility with future versions of SpacetimeDB is not guaranteed. + +```ebnf +SET var ( TO | '=' ) literal +``` + +Updates the value of a system variable. + +### SHOW + +> WARNING: The `SHOW` statement is experimental. +> Compatibility with future versions of SpacetimeDB is not guaranteed. + +```ebnf +SHOW var +``` + +Returns the value of a system variable. + +## System Variables + +> WARNING: System variables are experimental. +> Compatibility with future versions of SpacetimeDB is not guaranteed. + +- `row_limit` + + ```sql + -- Reject queries that scan more than 10K rows + SET row_limit = 10000 + ``` + +## Data types + +The set of data types that SpacetimeDB supports is defined by SATS, +the Spacetime Algebraic Type System. + +Spacetime SQL however does not support all of SATS, +specifically in the way of product and sum types. +The language itself does not provide a way to construct them, +nore does it provide any scalar operators for them. +Nevertheless rows containing them can be returned to clients. + +## Literals + +```ebnf +literal = INTEGER | FLOAT | STRING | HEX | TRUE | FALSE ; +``` + +The following describes how to construct literal values for SATS data types in Spacetime SQL. + +### Booleans + +Booleans are represented using the canonical atoms `true` or `false`. + +### Integers + +```ebnf +INTEGER + = [ '+' | '-' ] NUM + | [ '+' | '-' ] NUM 'E' [ '+' ] NUM + ; + +NUM + = DIGIT { DIGIT } + ; + +DIGIT + = 0..9 + ; +``` + +SATS supports multiple fixed width integer types. +The concrete type of a literal is inferred from the context. + +#### Examples + +```sql +-- All products that sell for more than $1000 +SELECT * FROM Inventory WHERE price > 1000 +SELECT * FROM Inventory WHERE price > 1e3 +SELECT * FROM Inventory WHERE price > 1E3 +``` + +### Floats + +```ebnf +FLOAT + = [ '+' | '-' ] [ NUM ] '.' NUM + | [ '+' | '-' ] [ NUM ] '.' NUM 'E' [ '+' | '-' ] NUM + ; +``` + +SATS supports both 32 and 64 bit floating point types. +The concrete type of a literal is inferred from the context. + +#### Examples + +```sql +-- All measurements where the temperature is greater than 105.3 +SELECT * FROM Measurements WHERE temperature > 105.3 +SELECT * FROM Measurements WHERE temperature > 1053e-1 +SELECT * FROM Measurements WHERE temperature > 1053E-1 +``` + +### Strings + +```ebnf +STRING + = "'" { "''" | CHAR } "'" + ; +``` + +`CHAR` is defined as a `utf-8` encoded unicode character. + +#### Examples + +```sql +SELECT * FROM Customers WHERE first_name = 'John' +``` + +### Hex + +```ebnf +HEX + = 'X' "'" { HEXIT } "'" + | '0' 'x' { HEXIT } + ; + +HEXIT + = DIGIT | a..f | A..F + ; +``` + +Hex literals can represent [Identity], [ConnectionId], or binary types. +The type is ultimately inferred from the context. + +#### Examples + +```sql +SELECT * FROM Program WHERE hash_value = 0xABCD1234 +``` + +## Identifiers + +```ebnf +identifier + = LATIN { LATIN | DIGIT | '_' } + | '"' { '""' | CHAR } '"' + ; + +LATIN + = a..z | A..Z + ; +``` + +Identifiers are tokens that identify database objects like tables or columns. +Spacetime SQL supports both quoted and unquoted identifiers. +Both types of identifiers are case sensitive. +Use quoted identifiers to avoid conflict with reserved SQL keywords, +or if your table or column contains non-alphanumeric characters. + +Because SpacetimeDB uses a postgres compatible parser, identifiers which are +reserved in postgres are automatically reserved in Spacetime SQL. See [SQL Key Words in the PostgreSQL documentation](https://www.postgresql.org/docs/current/sql-keywords-appendix.html). + +### Example + +```sql +-- `ORDER` is a sql keyword and therefore needs to be quoted +SELECT * FROM "Order" + +-- A table containing `$` needs to be quoted as well +SELECT * FROM "Balance$" +``` + +## Best Practices for Performance and Scalability + +When designing your schema or crafting your queries, +consider the following best practices to ensure optimal performance: + +- **Add Primary Key and/or Unique Constraints:** + Constrain columns whose values are guaranteed to be distinct as either unique or primary keys. + The query planner can further optimize joins if it knows the join values to be unique. + +- **Index Filtered Columns:** + Index columns frequently used in a `WHERE` clause. + Indexes reduce the number of rows scanned by the query engine. + +- **Index Join Columns:** + Index columns whose values are frequently used as join keys. + These are columns that are used in the `ON` condition of a `JOIN`. + + Again, this reduces the number of rows that must be scanned to answer a query. + It is also critical for the performance of subscription updates -- + so much so that it is a compiler-enforced requirement, + as mentioned in the [subscription](#from) section. + + If a column that has already been constrained as unique or a primary key, + it is not necessary to explicitly index it as well, + since these constraints automatically index the column in question. + +- **Optimize Join Order:** + Place tables with the most selective filters first in your `FROM` clause. + This minimizes intermediate result sizes and improves query efficiency. + +### Example + +Take the following query that was used in a previous example: + +```sql +-- Find all customers who ordered a particular product and when they ordered it +SELECT customer.first_name, customer.last_name, o.date +FROM Customers customer +JOIN Orders o ON customer.id = o.customer_id +JOIN Inventory product ON o.product_id = product.id +WHERE product.name = {product_name} +``` + +In order to conform with the best practices for optimizing performance and scalability: + +- An index should be defined on `Inventory.name` because we are filtering on that column. +- `Inventory.id` and `Customers.id` should be defined as primary keys. +- Additionally non-unique indexes should be defined on `Orders.product_id` and `Orders.customer_id`. +- `Inventory` should appear first in the `FROM` clause because it is the only table mentioned in the `WHERE` clause. +- `Orders` should come next because it joins directly with `Inventory`. +- `Customers` should come next because it joins directly with `Orders`. + + + + +```rust +#[table( + name = Inventory, + index(name = product_name, btree = [name]), + public +)] +struct Inventory { + #[primary_key] + id: u64, + name: String, + .. +} + +#[table( + name = Customers, + public +)] +struct Customers { + #[primary_key] + id: u64, + first_name: String, + last_name: String, + .. +} + +#[table( + name = Orders, + public +)] +struct Orders { + #[primary_key] + id: u64, + #[unique] + product_id: u64, + #[unique] + customer_id: u64, + .. +} +``` + + + + +```cs +[SpacetimeDB.Table(Name = "Inventory")] +[SpacetimeDB.Index(Name = "product_name", BTree = ["name"])] +public partial struct Inventory +{ + [SpacetimeDB.PrimaryKey] + public long id; + public string name; + .. +} + +[SpacetimeDB.Table(Name = "Customers")] +public partial struct Customers +{ + [SpacetimeDB.PrimaryKey] + public long id; + public string first_name; + public string last_name; + .. +} + +[SpacetimeDB.Table(Name = "Orders")] +public partial struct Orders +{ + [SpacetimeDB.PrimaryKey] + public long id; + [SpacetimeDB.Unique] + public long product_id; + [SpacetimeDB.Unique] + public long customer_id; + .. +} +``` + + + + +```sql +-- Find all customers who ordered a particular product and when they ordered it +SELECT c.first_name, c.last_name, o.date +FROM Inventory product +JOIN Orders o ON product.id = o.product_id +JOIN Customers c ON c.id = o.customer_id +WHERE product.name = {product_name}; +``` + +## Appendix + +Common production rules that have been used throughout this document. + +```ebnf +table + = identifier + ; + +alias + = identifier + ; + +var + = identifier + ; + +column + = identifier + | identifier '.' identifier + ; +``` + +[sdk]: /sdks/rust#subscribe-to-queries +[http]: /http/database#post-v1databasename_or_identitysql +[cli]: /cli-reference#spacetime-sql +[Identity]: /#identity +[ConnectionId]: /#connectionid diff --git a/docs/docs/08-SQL/02-pg-wire.md b/docs/docs/08-sql/02-pg-wire.md similarity index 98% rename from docs/docs/08-SQL/02-pg-wire.md rename to docs/docs/08-sql/02-pg-wire.md index afbd364dfc2..bd2018c5610 100644 --- a/docs/docs/08-SQL/02-pg-wire.md +++ b/docs/docs/08-sql/02-pg-wire.md @@ -1,6 +1,6 @@ --- title: PostgreSQL Wire Protocol (PGWire) -slug: /docs/sql/pg-wire +slug: /sql/pg-wire --- # PostgreSQL Wire Protocol (PGWire) Compatibility @@ -104,7 +104,7 @@ spacetime start --pg-port 5432 [ARGS] ## Examples In the following example, we assume you are using the `quickstart-chat` database created in -the [Rust Module Quickstart](/modules/rust/quickstart) or [C# Module Quickstart](/modules/c-sharp/quickstart), +the [Rust Module Quickstart](/docs/quickstarts/rust) or [C# Module Quickstart](/docs/quickstarts/c-sharp), and have set the `auth token` as shown above. ### Using `psql` diff --git a/docs/docs/09-Subscriptions/01-subscription-reference.md b/docs/docs/09-subscriptions/01-subscription-reference.md similarity index 99% rename from docs/docs/09-Subscriptions/01-subscription-reference.md rename to docs/docs/09-subscriptions/01-subscription-reference.md index 90f499277e7..1a325662ba5 100644 --- a/docs/docs/09-Subscriptions/01-subscription-reference.md +++ b/docs/docs/09-subscriptions/01-subscription-reference.md @@ -91,7 +91,7 @@ public sealed class SubscriptionBuilder /// Data from all the provided queries will be returned at the same time. /// /// See the SpacetimeDB SQL docs for more information on SQL syntax: - /// https://spacetimedb.com/docs/sql + /// pathname:///docs/sql /// public SubscriptionHandle Subscribe( string[] querySqls diff --git a/docs/docs/09-subscriptions/02-subscription-semantics.md b/docs/docs/09-subscriptions/02-subscription-semantics.md new file mode 100644 index 00000000000..689a19b0aaa --- /dev/null +++ b/docs/docs/09-subscriptions/02-subscription-semantics.md @@ -0,0 +1,93 @@ +--- +title: Subscription Semantics +slug: /subscriptions/semantics +--- + + + +# SpacetimeDB Subscription Semantics + +This document describes the subscription semantics maintained by the SpacetimeDB host over WebSocket connections. These semantics outline message ordering guarantees, subscription handling, transaction updates, and client cache consistency. + +## WebSocket Communication Channels + +A single WebSocket connection between a client and the SpacetimeDB host consists of two distinct message channels: + +- **Client → Server:** Sends requests such as reducer invocations and subscription queries. +- **Server → Client:** Sends responses to client requests and database transaction updates. + +### Ordering Guarantees + +The server maintains the following guarantees: + +1. **Sequential Response Ordering:** + - Responses to client requests are always sent back in the same order the requests were received. If request A precedes request B, the response to A will always precede the response to B, even if A takes longer to process. + +2. **Atomic Transaction Updates:** + - Each database transaction (e.g., reducer invocation, INSERT, UPDATE, DELETE queries) generates exactly zero or one update message sent to clients. These updates are atomic and reflect the exact order of committed transactions. + +3. **Atomic Subscription Initialization:** + - When subscriptions are established, clients receive exactly one response containing all initially matching rows from a consistent database state snapshot taken between two transactions. + - The state snapshot reflects a committed database state that includes all previous transaction updates received and excludes all future transaction updates. + +## Subscription Workflow + +When invoking `SubscriptionBuilder::subscribe(QUERIES)` from the client SDK: + +1. **Client SDK → Host:** + - Sends a `Subscribe` message containing the specified QUERIES. + +2. **Host Processing:** + - Captures a snapshot of the committed database state. + - Evaluates the QUERIES against this snapshot to determine matching rows. + +3. **Host → Client SDK:** + - Sends a `SubscribeApplied` message containing the matching rows. + +4. **Client SDK Processing:** + - Receives and processes the message. + - Locks the client cache and inserts all rows atomically. + - Invokes relevant callbacks: + - `on_insert` callback for each row. + - `on_applied` callback for the subscription. + :::note + No relative ordering guarantees are made regarding the invocation order of these callbacks. + ::: + +## Transaction Update Workflow + +Upon committing a database transaction: + +1. **Transaction Results in a State Delta:** + - The result of a transaction is a state delta, i.e. an unordered set of inserted and deleted rows. + +2. **Host Evaluates Queries:** + - Evaluates the QUERIES against the state delta to determine matching altered rows. + +3. **Host → Client SDK:** + - Sends a `TransactionUpdate` message if relevant updates exist, containing affected rows and transaction metadata. + +4. **Client SDK Processing:** + - Receives and processes the message. + - Locks the client cache, applying deletions and insertions atomically. + - Invokes relevant callbacks: + - `on_insert`, `on_delete`, `on_update` callbacks for modified rows. + - Reducer callbacks, if the transaction was the result of a reducer. + :::note + No relative ordering guarantees are made regarding the invocation order of these callbacks. + ::: + +## Multiple Subscription Sets + +If multiple subscription sets are active, updates across these sets are bundled together into a single `TransactionUpdate` message. + +## Client Cache Guarantees + +- The client cache always maintains a consistent and correct subset of the committed database state. +- Callback functions invoked due to events have guaranteed visibility into a fully updated cache state. +- Reads from the client cache are effectively free as they access locally cached data. +- During callback execution, the client cache accurately reflects the database state immediately following the event-triggering transaction. + +### Pending Callbacks and Cache Consistency + +While processing a `TransactionUpdate` message, callbacks are queued within the SDK and deferred until the cache updates (inserts/deletes) from a transaction are fully applied. This ensures all callbacks see the fully consistent state of the cache, preventing callbacks from observing an inconsistent intermediate state. diff --git a/docs/docs/10-Read Permissions/01-row-level-security.md b/docs/docs/10-read-permissions/01-row-level-security.md similarity index 100% rename from docs/docs/10-Read Permissions/01-row-level-security.md rename to docs/docs/10-read-permissions/01-row-level-security.md diff --git a/docs/docs/10-read-permissions/_category_.json b/docs/docs/10-read-permissions/_category_.json new file mode 100644 index 00000000000..691376a0acb --- /dev/null +++ b/docs/docs/10-read-permissions/_category_.json @@ -0,0 +1,3 @@ +{ + "label": "Read Permissions" +} \ No newline at end of file diff --git a/docs/docs/11-How-To/01-incremental-migrations.md b/docs/docs/11-how-to/01-incremental-migrations.md similarity index 100% rename from docs/docs/11-How-To/01-incremental-migrations.md rename to docs/docs/11-how-to/01-incremental-migrations.md diff --git a/docs/docs/11-How-To/02-reject-client-connections.md b/docs/docs/11-how-to/02-reject-client-connections.md similarity index 100% rename from docs/docs/11-How-To/02-reject-client-connections.md rename to docs/docs/11-how-to/02-reject-client-connections.md diff --git a/docs/docs/11-How-To/03-using-auth-claims.md b/docs/docs/11-how-to/03-using-auth-claims.md similarity index 100% rename from docs/docs/11-How-To/03-using-auth-claims.md rename to docs/docs/11-how-to/03-using-auth-claims.md diff --git a/docs/docs/11-how-to/_category_.json b/docs/docs/11-how-to/_category_.json new file mode 100644 index 00000000000..1c65344c281 --- /dev/null +++ b/docs/docs/11-how-to/_category_.json @@ -0,0 +1,3 @@ +{ + "label": "How To" +} \ No newline at end of file diff --git a/docs/docs/12-spacetimeauth/01-overview.md b/docs/docs/12-spacetimeauth/01-overview.md new file mode 100644 index 00000000000..c4a12165a58 --- /dev/null +++ b/docs/docs/12-spacetimeauth/01-overview.md @@ -0,0 +1,111 @@ +--- +title: Overview +slug: /spacetimeauth +--- + +# SpacetimeAuth - Overview + +:::warning + +SpacetimeAuth is currently in beta, some features may not be available yet or may change in the future. You might encounter bugs or issues while using the service. Please report any problems you encounter to help us improve SpacetimeAuth. + +::: + +SpacetimeAuth is a service for managing authentication for your SpacetimeDB +applications. This allows you to authenticate users without needing +an external authentication service or even a hosting server. +SpacetimeAuth is an [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works/) provider, which means it can be used with +any OIDC-compatible client library. + +At the end of the authentication flow, your application receives an ID token +containing identity claims (such as email, username, and roles). Your +application can then use this token with any SpacetimeDB SDK to authenticate and +authorize users with the SpacetimeDB server. + +## Features + +### Authentication methods + +- Magic link +- Github +- Google +- Discord +- Twitch +- Kick + +### User & role management + +- Create, update, and manage users +- Assign roles to users for role-based access control + +### Customization + +- Customizable theme for login pages +- Enable/disable anonymous and magic link authentication + +## Terminology + +Feel free to check out our blog post on OpenID +Connect [Who are you? Who am I to you?](https://spacetimedb.com/blog/who-are-you) +for more information about OpenID Connect and how it works. + +### Projects + +SpacetimeAuth uses the concept of "projects" to manage authentication for +different applications. + +- Each project has its own set of users, roles, and authentication methods. +- Each project has its own configuration for email templates, web pages, and + other settings. +- Each project is independent of a SpacetimeDB database and can be used by one + or many databases. + +Here are some examples of how you might use projects: + +- You have a web application and a mobile application that both use the same + SpacetimeDB database. You can create a single SpacetimeAuth project for both + applications, therefore sharing a single user base. +- You have multiple SpacetimeDB databases for different environments (e.g. dev, + staging, production). You can create a separate SpacetimeAuth project for each + environment, therefore separating your users between environments. +- You have multiple SpacetimeDB databases for different applications. You can + create a separate SpacetimeAuth project for each application, therefore + separating your users between applications. + +### Users + +Users are the individuals who will be authenticating to your application via +SpacetimeAuth. Each user has a unique identifier (user ID) and can have one or +more roles assigned to them. + +### Clients + +:::note +Clients must not be confused with Users. +::: + +Clients, also known as Relying Parties in OpenID Connect terminology, are the +applications that are relying on SpacetimeAuth for authentication. Each client +is associated with a single project and has its own client ID and client +secret. + +Clients are applications that request an OpenID Connect ID token from +SpacetimeAuth, which can then be used to authenticate with the SpacetimeDB +server. + +### Roles + +Roles are used to manage access control within your application. Each role is +represented by a string (e.g. "admin", "user") that can be assigned to one or +more users. + +Roles are included as claims in the ID token that is issued to the user upon +authentication. + +Inside your reducers, you can check the user's roles to determine what +actions they are allowed to perform. + +## Getting Started + +Check out our [Creating a project guide](/spacetimeauth/creating-a-project) to +learn how to create and configure a SpacetimeAuth project. diff --git a/docs/docs/12-spacetimeauth/02-creating-a-project.md b/docs/docs/12-spacetimeauth/02-creating-a-project.md new file mode 100644 index 00000000000..31e012f0c44 --- /dev/null +++ b/docs/docs/12-spacetimeauth/02-creating-a-project.md @@ -0,0 +1,57 @@ +--- +title: Creating a project +slug: /spacetimeauth/creating-a-project +--- + +# Setting up a SpacetimeAuth Project + +:::warning + +SpacetimeAuth is currently in beta, some features may not be available yet or may change in the future. You might encounter bugs or issues while using the service. Please report any problems you encounter to help us improve SpacetimeAuth. + +::: + +## 1. Accessing the SpacetimeAuth Dashboard + +To get started with SpacetimeAuth, log in to the website and navigate to the +SpacetimeAuth dashboard: [https://spacetimedb.com/spacetimeauth](https://spacetimedb.com/spacetimeauth) + +You can also click on your profile icon in the top right corner and select +"SpacetimeAuth" from the dropdown menu. + +![Access the menu](/images/spacetimeauth/menu-access.png) + +## 2. Creating a New Project + +Once you're in the SpacetimeAuth dashboard, you can create a new project by +clicking the "New Project" button. + +![Create project](/images/spacetimeauth/new-project.png) + +## 3. Exploring the Dashboard + +After creating a project, you can access the dashboard by clicking on the project +name in the list of projects. +![Project list](/images/spacetimeauth/projects-list.png) + +The dashboard provides you with multiple tabs to manage different aspects of +your project: + +- **Overview**: A summary of your project, including a table of recent users. +- **Clients**: A list of all clients (applications) that can be used to + authenticate in your applications. + A default client is created for you when you create a new project. +- **Users**: A list of all users in your project, with options to search, filter, + and manage users. +- **Identity Providers**: A list of all identity providers (e.g. Google, GitHub, + etc.) that can be used to authenticate users in your project. +- **Customization**: Live editor to customize colors, logos, and authentication methods. + +![Project overview](/images/spacetimeauth/project-overview.png) + +## 4. Next Steps + +Now that you have created a SpacetimeAuth project, you can start configuring it +to suit your application's needs. Check out our [configuration guide](/spacetimeauth/configuring-a-project) +for more information on setting up identity providers, customizing templates, +and managing users and roles. diff --git a/docs/docs/12-spacetimeauth/03-configuring-a-project.md b/docs/docs/12-spacetimeauth/03-configuring-a-project.md new file mode 100644 index 00000000000..f630bd3f4aa --- /dev/null +++ b/docs/docs/12-spacetimeauth/03-configuring-a-project.md @@ -0,0 +1,141 @@ +--- +title: Configuring your project +slug: /spacetimeauth/configuring-a-project +--- + +# Configuring a SpacetimeAuth Project + +:::warning + +SpacetimeAuth is currently in beta, some features may not be available yet or may change in the future. You might encounter bugs or issues while using the service. Please report any problems you encounter to help us improve SpacetimeAuth. + +::: + +SpacetimeAuth projects can be configured to suit your application's needs. +This guide will walk you through the various configuration options available in the +SpacetimeAuth dashboard and through various common use cases like setting up +third-party identity providers. + +## Managing Clients + +Clients represent applications that will use SpacetimeAuth for authentication. +Each client has its own set of settings, including redirect URIs, +post logout URIs, and name. + +You can manage clients by navigating to the "Clients" tab in your +SpacetimeAuth project dashboard. +![Clients tab](/images/spacetimeauth/clients-tab.png) +Every project comes with a default client that you can use to get started. +You can also create additional clients by clicking the "Create Client" button. + +The majority of projects will only need a single client to authenticate users to +their SpacetimeDB module. You may want to create multiple clients if you have +multiple applications (e.g. a sidecar, admin panel, etc.) and want to use different +authentication flows or settings for each application. + +When creating or editing a client, you can configure the following settings: + +- **Name**: The name of the client (e.g. "My Web App"). +- **Redirect URIs**: The URIs to which SpacetimeAuth allows to redirect + the user after a successful login. These must match the URIs used in your application. +- **Post Logout Redirect URIs**: The URIs to which SpacetimeAuth allows to redirect + the user after a logout. These must match the URIs used in your application. + +:::danger +Remember to keep your client secret secure, **never** expose it in client-side code or public repositories. You can freely share the client ID as it is not sensitive information. Client secrets are only used during the `client_credentials` flow, allowing you to get a token with no user context (the `sub` claim will be set to the client ID).` +::: + +![Edit client](/images/spacetimeauth/edit-client.png) + +### Scopes and Claims + +Scopes are not yet editable and are currently limited to `openid`, `profile`, +and `email`. These scopes are sufficient for most applications, as they provide +all the necessary information about the authenticated user. +Here are the claims (i.e, user information available in the ID token) provided by +each scope: + +| Scope | Claims | +| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| openid (required) | `sub` (unique user identifier) | +| profile | `name`, `family_name`, `given_name`, `middle_name`, `nickname`, `preferred_username`, `picture`, `website`, `gender`, `birthdate`, `zoneinfo`, `locale`, `updated_at` | +| email | `email`, `email_verified` | + +You can request all or a subset of these scopes when initiating the +authentication flow in your application. + +### Redirect URIs + +Redirect URIs are a critical part of the OAuth2 and OpenID Connect flows. +They ensure that after a user authenticates, they are redirected back to a +trusted location in your application. + +When configuring redirect URIs for your client, ensure that they match the URIs +used in your application. This includes the scheme (http or https), domain, +port (if applicable), and path. +For example, if your application is hosted at `https://myapp.com` and you +initiate the authentication flow from `https://myapp.com/login`, you might +set the redirect URI to `https://myapp.com/callback`. + +To find the correct redirect URIs for your application, refer to the +documentation of the authentication library you are using or check out our +integration guides with various frameworks. + +## Setting Up Third-Party Identity Providers + +SpacetimeAuth supports multiple third-party identity providers, allowing users to +authenticate using their existing accounts. Supported providers include: + +- Google +- GitHub +- Discord +- Twitch +- Kick +- More providers will be added in the future + +User's information from third-party identity providers is mapped to the standard +OpenID Connect claims used by SpacetimeAuth. This ensures a consistent user +experience regardless of the identity provider used. +For example the username claim is mapped to the standard `preferred_username` claim. + +You can manage identity providers by navigating to the "Identity Providers" tab +in your SpacetimeAuth project dashboard. + +![Identity Providers tab](/images/spacetimeauth/identity-providers.png) + +Since SpacetimeAuth acts as a client for the external identity provider, +you need to provide the client ID and client secret obtained +from the provider's developer console in order to enable the provider. +You must also configure the redirect URI in the provider's developer console to +point to SpacetimeAuth (see below). +You can also choose to enable or disable the provider. +After entering the required information, click "Save" and the provider will be +available on the login page of your application. + +Here are guides to help you create the required OAuth application (sometimes +called an OAuth App or OAuth Client): + +- [Google](https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid#get_your_google_api_client_id) +- [GitHub](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app) +- [Discord](https://discord.com/developers/docs/quick-start/getting-started#step-1-creating-an-app) +- [Twitch](https://dev.twitch.tv/docs/authentication/register-app/) +- [Kick](https://docs.kick.com/getting-started/kick-apps-setup) + +Here are the redirect URIs you need to configure for each enabled provider: + +| Provider | Redirect URI | +| -------- | ---------------------------------------------------------------------- | +| Google | `https://auth.spacetimedb.com/interactions/federated/callback/google` | +| GitHub | `https://auth.spacetimedb.com/interactions/federated/callback/github` | +| Discord | `https://auth.spacetimedb.com/interactions/federated/callback/discord` | +| Twitch | `https://auth.spacetimedb.com/interactions/federated/callback/twitch` | +| Kick | `https://auth.spacetimedb.com/interactions/federated/callback/kick` | + +## Next Steps + +Now that you have created and configured a SpacetimeAuth project, you can +start integrating it into your application. Before writing code, we recommend +verifying your setup with a quick test. + +- [Test your configuration with OIDC Debugger](/spacetimeauth/testing) +- [React integration guide](/spacetimeauth/react-integration) diff --git a/docs/docs/12-spacetimeauth/04-testing.md b/docs/docs/12-spacetimeauth/04-testing.md new file mode 100644 index 00000000000..8c119e1fb05 --- /dev/null +++ b/docs/docs/12-spacetimeauth/04-testing.md @@ -0,0 +1,96 @@ +--- +title: Testing +slug: /spacetimeauth/testing +--- + +# Testing Your SpacetimeAuth Setup with OIDC Debugger + +:::warning + +SpacetimeAuth is currently in beta, some features may not be available yet or may change in the future. You might encounter bugs or issues while using the service. Please report any problems you encounter to help us improve SpacetimeAuth. + +::: + +Before integrating SpacetimeAuth into your application code, it’s a good idea +to verify that your client and redirect URIs are working correctly. One of the +easiest ways to do this is with [OIDC Debugger](https://oidcdebugger.com). + +## Why Use OIDC Debugger? + +OIDC Debugger simulates the OAuth2 / OIDC Authorization Code flow in your browser. +It allows you to: + +- Confirm that your **redirect URIs** are configured properly. +- Verify that your **client ID** works. +- Inspect the **ID Token** and claims (`email`, `sub`, `preferred_username`, etc.). +- Catch configuration issues before writing code. + +--- + +## Step 1: Gather Your Configuration + +- **Authorization Endpoint**: + `https://auth.spacetimedb.com/oidc/auth` + +- **Token Endpoint**: + `https://auth.spacetimedb.com/oidc/token` + +- **Client ID**: From your SpacetimeAuth dashboard, you can use any available client. +- **Redirect URI**: [https://oidcdebugger.com/debug](https://oidcdebugger.com/debug) must be added to your + client’s allowed redirect URIs in the SpacetimeAuth dashboard. + +--- + +## Step 2: Open OIDC Debugger + +1. Go to [https://oidcdebugger.com](https://oidcdebugger.com). +2. Fill out the fields as follows, leave all other fields at their defaults + (e.g., response type = code, state, nonce). + + | Field | Value | + | ------------- | ----------------------------------------- | + | Authorize URI | `https://auth.spacetimedb.com/oidc/auth` | + | Client ID | Your SpacetimeAuth client ID | + | Scope | `openid profile email` (or a subset) | + | Use PKCE? | Checked | + | Token URI | `https://auth.spacetimedb.com/oidc/token` | + +:::warning +You do not need to enter the client secret here since the tool runs in the browser. +::: + +![OIDC Debugger Setup](/images/spacetimeauth/oidcdebugger-config.png) + +--- + +## Step 3: Run the Flow + +1. Click **Send Request**. +2. Log in via SpacetimeAuth using any configured providers. +3. You’ll be redirected back to OIDC Debugger with an authorization code. +4. OIDC Debugger will automatically exchange the code for tokens and display the + results. + ![OIDC Debugger results](/images/spacetimeauth/oidcdebugger-results.png) + +--- + +## Step 4: Inspect your tokens + +Depending on the scopes you requested, you should receive an ID token like this: +![OIDC Debugger Result](/images/spacetimeauth/jwtio.png) + +You can decode the ID token using any JWT decoder (e.g. [jwt.io](https://jwt.io/)) +to see the claims included. For example: + +```json +{ + "sub": "user_ergqg1q5eg15fdd54", + "project_id": "project_xyz123", + "email": "user@example.com", + "email_verified": true, + "preferred_username": "exampleuser", + "first_name": "Example", + "last_name": "User", + "name": "Example User" +} +``` diff --git a/docs/docs/12-spacetimeauth/05-react-integration.md b/docs/docs/12-spacetimeauth/05-react-integration.md new file mode 100644 index 00000000000..70a65a17a71 --- /dev/null +++ b/docs/docs/12-spacetimeauth/05-react-integration.md @@ -0,0 +1,178 @@ +--- +title: React Integration +slug: /spacetimeauth/react-integration +--- + +# React Integration + +:::warning + +SpacetimeAuth is currently in beta, some features may not be available yet or may change in the future. You might encounter bugs or issues while using the service. Please report any problems you encounter to help us improve SpacetimeAuth. + +::: + +This guide will walk you through integrating SpacetimeAuth into a React +application using the [react-oidc-context](https://www.npmjs.com/package/react-oidc-context) +library. +This library provides a simple way to handle OpenID Connect (OIDC) authentication +in React. + +## Prerequisites + +1. Create a SpacetimeAuth project and configure a client as described in the + [Getting Started](/spacetimeauth/creating-a-project) and + [Configuration](/spacetimeauth/configuring-a-project) guides. +2. Have a React application set up. You can use Create React App or any other + React framework. +3. Install the `react-oidc-context` package in your React application: + +## Configuring react-oidc-context + +### 1. Add an OIDC configuration object + +Create an OIDC configuration object with your SpacetimeAuth project details. +Make sure to replace `YOUR_CLIENT_ID` with the actual client ID from your +SpacetimeAuth dashboard. + +```tsx +const oidcConfig = { + authority: 'https://auth.spacetimedb.com/oidc', + client_id: 'YOUR_CLIENT_ID', + redirect_uri: `${window.location.origin}/callback`, // Where the user is redirected after login + post_logout_redirect_uri: window.location.origin, // Where the user is redirected after logout + scope: 'openid profile email', + response_type: 'code', + automaticSilentRenew: true, +}; +``` + +### 2. Create a debug component + +This component will log various authentication events and state changes to +the console for debugging purposes. + +```tsx +export function OidcDebug() { + const auth = useAuth(); + + useEffect(() => { + const ev = auth.events; + + const onUserLoaded = (u: any) => + console.log('[OIDC] userLoaded', u?.profile?.sub, u); + const onUserUnloaded = () => console.log('[OIDC] userUnloaded'); + const onAccessTokenExpiring = () => + console.log('[OIDC] accessTokenExpiring'); + const onAccessTokenExpired = () => console.log('[OIDC] accessTokenExpired'); + const onSilentRenewError = (e: any) => + console.warn('[OIDC] silentRenewError', e); + const onUserSignedOut = () => console.log('[OIDC] userSignedOut'); + + ev.addUserLoaded(onUserLoaded); + ev.addUserUnloaded(onUserUnloaded); + ev.addAccessTokenExpiring(onAccessTokenExpiring); + ev.addAccessTokenExpired(onAccessTokenExpired); + ev.addSilentRenewError(onSilentRenewError); + ev.addUserSignedOut(onUserSignedOut); + + return () => { + ev.removeUserLoaded(onUserLoaded); + ev.removeUserUnloaded(onUserUnloaded); + ev.removeAccessTokenExpiring(onAccessTokenExpiring); + ev.removeAccessTokenExpired(onAccessTokenExpired); + ev.removeSilentRenewError(onSilentRenewError); + ev.removeUserSignedOut(onUserSignedOut); + }; + }, [auth.events]); + + useEffect(() => { + console.log('[OIDC] state', { + isLoading: auth.isLoading, + isAuthenticated: auth.isAuthenticated, + error: auth.error?.message, + activeNavigator: auth.activeNavigator, + user: !!auth.user, + }); + }, [ + auth.isLoading, + auth.isAuthenticated, + auth.error, + auth.activeNavigator, + auth.user, + ]); + + return null; +} +``` + +### 3. Wrap Your Application with AuthProvider + +Wrap your React application with the `AuthProvider` component to provide +authentication context. + +```tsx +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { AuthProvider, useAuth } from 'react-oidc-context'; +import App from './App'; +import { OidcDebug } from './OidcDebug'; + +const oidcConfig = {...}; + +function onSigninCallback() { + window.history.replaceState({}, document.title, window.location.pathname); +} + +const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement); +root.render( + + + + +); + +``` + +### 4. Implement Authentication Logic in Your App + +In your main component (e.g., `App.tsx`), use the `useAutoSignin` hook to automatically + +sign in users if they are not authenticated. + +```tsx +import React from 'react'; + +import { useAuth, useAutoSignin } from 'react-oidc-context'; + +import './App.css'; + +function App() { + const auth = useAuth(); + + useAutoSignin(); + + if (auth.isLoading) { + return
Loading...
; + } + + if (auth.error) { + return
Error: {auth.error.message}
; + } + + if (!auth.isAuthenticated) { + return
Redirecting to login...
; + } + + return ( +
+
+ Welcome, {auth.user?.profile.name} (id: {auth.user?.profile.sub})! + +
+
+ ); +} +``` + +You're now set up to use SpacetimeAuth in your React application. When users +access your app, they will be redirected to the SpacetimeAuth login page for authentication. diff --git a/docs/docs/13-HTTP API/01-authorization.md b/docs/docs/13-http-api/01-authorization.md similarity index 100% rename from docs/docs/13-HTTP API/01-authorization.md rename to docs/docs/13-http-api/01-authorization.md diff --git a/docs/docs/13-HTTP API/02-identity.md b/docs/docs/13-http-api/02-identity.md similarity index 100% rename from docs/docs/13-HTTP API/02-identity.md rename to docs/docs/13-http-api/02-identity.md diff --git a/docs/docs/13-HTTP API/03-database.md b/docs/docs/13-http-api/03-database.md similarity index 100% rename from docs/docs/13-HTTP API/03-database.md rename to docs/docs/13-http-api/03-database.md diff --git a/docs/docs/13-http-api/_category_.json b/docs/docs/13-http-api/_category_.json new file mode 100644 index 00000000000..76e68a0beae --- /dev/null +++ b/docs/docs/13-http-api/_category_.json @@ -0,0 +1,3 @@ +{ + "label": "HTTP API" +} \ No newline at end of file diff --git a/docs/docs/14-Internals/01-module-abi-reference.md b/docs/docs/14-internals/01-module-abi-reference.md similarity index 99% rename from docs/docs/14-Internals/01-module-abi-reference.md rename to docs/docs/14-internals/01-module-abi-reference.md index 5b7b4ddaca2..11e6905f58c 100644 --- a/docs/docs/14-Internals/01-module-abi-reference.md +++ b/docs/docs/14-internals/01-module-abi-reference.md @@ -498,6 +498,6 @@ uint16_t _iter_start_filtered( [`bindings_sys::raw`]: https://github.com/clockworklabs/SpacetimeDB/blob/master/crates/bindings-sys/src/lib.rs#L44-L215 [`bindings`]: https://github.com/clockworklabs/SpacetimeDB/blob/master/crates/bindings/src/lib.rs [module_ref]: /modules/rust -[module_quick_start]: /modules/rust/quickstart +[module_quick_start]: /docs/quickstarts/rust [wasm_c_abi]: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md [c_header]: #appendix-bindingsh diff --git a/docs/docs/14-internals/02-sats-json.md b/docs/docs/14-internals/02-sats-json.md new file mode 100644 index 00000000000..37b502f4ce4 --- /dev/null +++ b/docs/docs/14-internals/02-sats-json.md @@ -0,0 +1,173 @@ +--- +slug: /sats-json +--- + +# SATS-JSON Data Format + +The Spacetime Algebraic Type System JSON format defines how Spacetime `AlgebraicType`s and `AlgebraicValue`s are encoded as JSON. Algebraic types and values are JSON-encoded for transport via the [HTTP Databases API](/http/database) and the WebSocket text protocol. Note that SATS-JSON is not self-describing, and so a SATS value represented in JSON requires knowing the value's schema to meaningfully understand it - for example, it's not possible to tell whether a JSON object with a single field is a `ProductValue` with one element or a `SumValue`. + +## Values + +### At a glance + +| Type | Description | +| ---------------- | ---------------------------------------------------------------- | +| `AlgebraicValue` | A value whose type may be any [`AlgebraicType`](#algebraictype). | +| `SumValue` | A value whose type is a [`SumType`](#sumtype). | +| `ProductValue` | A value whose type is a [`ProductType`](#producttype). | +| `BuiltinValue` | A value whose type is a [`BuiltinType`](#builtintype). | +| | | + +### `AlgebraicValue` + +```json +SumValue | ProductValue | BuiltinValue +``` + +### `SumValue` + +An instance of a [`SumType`](#sumtype). `SumValue`s are encoded as a JSON object with a single key, a non-negative integer tag which identifies the variant. The value associated with this key is the variant data. Variants which hold no data will have an empty array as their value. + +The tag is an index into the [`SumType.variants`](#sumtype) array of the value's [`SumType`](#sumtype). + +```json +{ + "": AlgebraicValue +} +``` + +The tag may also be the name of one of the variants. + +### `ProductValue` + +An instance of a [`ProductType`](#producttype). `ProductValue`s are encoded as JSON arrays. Each element of the `ProductValue` array is of the type of the corresponding index in the [`ProductType.elements`](#producttype) array of the value's [`ProductType`](#producttype). + +```json +array +``` + +`ProductValue`s may also be encoded as a JSON object with the keys as the field +names of the `ProductValue` and the values as the corresponding +`AlgebraicValue`s. + +### `BuiltinValue` + +An instance of a [`BuiltinType`](#builtintype). `BuiltinValue`s are encoded as JSON values of corresponding types. + +```json +boolean | number | string | array | map +``` + +| [`BuiltinType`](#builtintype) | JSON type | +| ----------------------------- | ------------------------------------- | +| `Bool` | `boolean` | +| Integer types | `number` | +| Float types | `number` | +| `String` | `string` | +| Array types | `array` | +| Map types | `map` | + +All SATS integer types are encoded as JSON `number`s, so values of 64-bit and 128-bit integer types may lose precision when encoding values larger than 2⁵². + +## Types + +All SATS types are JSON-encoded by converting them to an `AlgebraicValue`, then JSON-encoding that meta-value. + +### At a glance + +| Type | Description | +| --------------------------------------- | ------------------------------------------------------------------------------------ | +| [`AlgebraicType`](#algebraictype) | Any SATS type. | +| [`SumType`](#sumtype) | Sum types, i.e. tagged unions. | +| [`ProductType`](#producttype) | Product types, i.e. structures. | +| [`BuiltinType`](#builtintype) | Built-in and primitive types, including booleans, numbers, strings, arrays and maps. | +| [`AlgebraicTypeRef`](#algebraictyperef) | An indirect reference to a type, used to implement recursive types. | + +#### `AlgebraicType` + +`AlgebraicType` is the most general meta-type in the Spacetime Algebraic Type System. Any SATS type can be represented as an `AlgebraicType`. `AlgebraicType` is encoded as a tagged union, with variants for [`SumType`](#sumtype), [`ProductType`](#producttype), [`BuiltinType`](#builtintype) and [`AlgebraicTypeRef`](#algebraictyperef). + +```json +{ "Sum": SumType } +| { "Product": ProductType } +| { "Builtin": BuiltinType } +| { "Ref": AlgebraicTypeRef } +``` + +#### `SumType` + +The meta-type `SumType` represents sum types, also called tagged unions or Rust `enum`s. A sum type has some number of variants, each of which has an `AlgebraicType` of variant data, and an optional string discriminant. For each instance, exactly one variant will be active. The instance will contain only that variant's data. + +A `SumType` with zero variants is called an empty type or never type because it is impossible to construct an instance. + +Instances of `SumType`s are [`SumValue`s](#sumvalue), and store a tag which identifies the active variant. + +```json +// SumType: +{ + "variants": array, +} + +// SumTypeVariant: +{ + "algebraic_type": AlgebraicType, + "name": { "some": string } | { "none": [] } +} +``` + +### `ProductType` + +The meta-type `ProductType` represents product types, also called structs or tuples. A product type has some number of fields, each of which has an `AlgebraicType` of field data, and an optional string field name. Each instance will contain data for all of the product type's fields. + +A `ProductType` with zero fields is called a unit type because it has a single instance, the unit, which is empty. + +Instances of `ProductType`s are [`ProductValue`s](#productvalue), and store an array of field data. + +```json +// ProductType: +{ + "elements": array, +} + +// ProductTypeElement: +{ + "algebraic_type": AlgebraicType, + "name": { "some": string } | { "none": [] } +} +``` + +### `BuiltinType` + +The meta-type `BuiltinType` represents SATS primitive types: booleans, integers, floating-point numbers, strings, arrays and maps. `BuiltinType` is encoded as a tagged union, with a variant for each SATS primitive type. + +SATS integer types are identified by their signedness and width in bits. SATS supports the same set of integer types as Rust, i.e. 8, 16, 32, 64 and 128-bit signed and unsigned integers. + +SATS floating-point number types are identified by their width in bits. SATS supports 32 and 64-bit floats, which correspond to [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) single- and double-precision binary floats, respectively. + +SATS array and map types are homogeneous, meaning that each array has a single element type to which all its elements must conform, and each map has a key type and a value type to which all of its keys and values must conform. + +```json +{ "Bool": [] } +| { "I8": [] } +| { "U8": [] } +| { "I16": [] } +| { "U16": [] } +| { "I32": [] } +| { "U32": [] } +| { "I64": [] } +| { "U64": [] } +| { "I128": [] } +| { "U128": [] } +| { "F32": [] } +| { "F64": [] } +| { "String": [] } +| { "Array": AlgebraicType } +| { "Map": { + "key_ty": AlgebraicType, + "ty": AlgebraicType, + } } +``` + +### `AlgebraicTypeRef` + +`AlgebraicTypeRef`s are JSON-encoded as non-negative integers. These are indices into a typespace, like the one returned by the [`GET /v1/database/:name_or_identity/schema` HTTP endpoint](/http/database#get-v1databasename_or_identityschema). diff --git a/docs/docs/14-internals/03-bsatn.md b/docs/docs/14-internals/03-bsatn.md new file mode 100644 index 00000000000..2115e44b5a2 --- /dev/null +++ b/docs/docs/14-internals/03-bsatn.md @@ -0,0 +1,141 @@ +--- +title: BSATN Data Format +slug: /bsatn +--- + +# Binary SATN Format (BSATN) + +The Spacetime Algebraic Type Notation binary (BSATN) format defines +how Spacetime `AlgebraicValue`s and friends are encoded as byte strings. + +Algebraic values and product values are BSATN-encoded for e.g., +module-host communication and for storing row data in the database. + +## Notes on notation + +In this reference, we give a formal definition of the format. +To do this, we use inductive definitions, and define the following notation: + +- `bsatn(x)` denotes a function converting some value `x` to a list of bytes. +- `a: B` means that `a` is of type `B`. +- `Foo(x)` denotes extracting `x` out of some variant or type `Foo`. +- `a ++ b` denotes concatenating two byte lists `a` and `b`. +- `bsatn(A) = bsatn(B) | ... | bsatn(Z)` where `B` to `Z` are variants of `A` + means that `bsatn(A)` is defined as e.g., + `bsatn(B)`, `bsatn(C)`, .., `bsatn(Z)` depending on what variant of `A` it was. +- `[]` denotes the empty list of bytes. + +## Values + +### At a glance + +| Type | Description | +| ----------------------------------- | ---------------------------------------------------- | +| [`AlgebraicValue`](#algebraicvalue) | A value of any type. | +| [`SumValue`](#sumvalue) | A value of a sum type, i.e. an enum or tagged union. | +| [`ProductValue`](#productvalue) | A value of a product type, i.e. a struct or tuple. | + +### `AlgebraicValue` + +The BSATN encoding of an `AlgebraicValue` defers to the encoding of each variant: + +```fsharp +bsatn(AlgebraicValue) + = bsatn(SumValue) + | bsatn(ProductValue) + | bsatn(ArrayValue) + | bsatn(String) + | bsatn(Bool) + | bsatn(U8) | bsatn(U16) | bsatn(U32) | bsatn(U64) | bsatn(U128) | bsatn(U256) + | bsatn(I8) | bsatn(I16) | bsatn(I32) | bsatn(I64) | bsatn(I128) | bsatn(I256) + | bsatn(F32) | bsatn(F64) +``` + +Algebraic values include sums, products, arrays, strings, and primitives types. +The primitive types include booleans, unsigned and signed integers up to 256-bits, and floats, both single and double precision. + +### `SumValue` + +An instance of a sum type, i.e. an enum or tagged union. +`SumValue`s are binary-encoded as `bsatn(tag) ++ bsatn(variant_data)` +where `tag: u8` is an index into the `SumType.variants` +array of the value's `SumType`, +and where `variant_data` is the data of the variant. +For variants holding no data, i.e., of some zero sized type, +`bsatn(variant_data) = []`. + +### `ProductValue` + +An instance of a product type, i.e. a struct or tuple. +`ProductValue`s are binary encoded as: + +```fsharp +bsatn(elems) = bsatn(elem_0) ++ .. ++ bsatn(elem_n) +``` + +Field names are not encoded. + +### `ArrayValue` + +The encoding of an `ArrayValue` is: + +``` +bsatn(ArrayValue(a)) + = bsatn(len(a) as u32) + ++ bsatn(normalize(a)_0) + ++ .. + ++ bsatn(normalize(a)_n) +``` + +where `normalize(a)` for `a: ArrayValue` converts `a` to a list of `AlgebraicValue`s. + +### Strings + +For strings, the encoding is defined as: + +```fsharp +bsatn(String(s)) = bsatn(len(s) as u32) ++ bsatn(utf8_to_bytes(s)) +``` + +That is, the BSATN encoding is the concatenation of + +- the bsatn of the string's length as a `u32` integer byte +- the utf8 representation of the string as a byte array + +### Primitives + +For the primitive variants of `AlgebraicValue`, the BSATN encodings are:s + +```fsharp +bsatn(Bool(false)) = [0] +bsatn(Bool(true)) = [1] +bsatn(U8(x)) = [x] +bsatn(U16(x: u16)) = to_little_endian_bytes(x) +bsatn(U32(x: u32)) = to_little_endian_bytes(x) +bsatn(U64(x: u64)) = to_little_endian_bytes(x) +bsatn(U128(x: u128)) = to_little_endian_bytes(x) +bsatn(U256(x: u256)) = to_little_endian_bytes(x) +bsatn(I8(x: i8)) = to_little_endian_bytes(x) +bsatn(I16(x: i16)) = to_little_endian_bytes(x) +bsatn(I32(x: i32)) = to_little_endian_bytes(x) +bsatn(I64(x: i64)) = to_little_endian_bytes(x) +bsatn(I128(x: i128)) = to_little_endian_bytes(x) +bsatn(I256(x: i256)) = to_little_endian_bytes(x) +bsatn(F32(x: f32)) = bsatn(f32_to_raw_bits(x)) // lossless conversion +bsatn(F64(x: f64)) = bsatn(f64_to_raw_bits(x)) // lossless conversion +bsatn(String(s)) = bsatn(len(s) as u32) ++ bsatn(bytes(s)) +``` + +Where + +- `f32_to_raw_bits(x)` extracts the raw bits of `x: f32` to `u32` +- `f64_to_raw_bits(x)` extracts the raw bits of `x: f64` to `u64` + +## Types + +All SATS types are BSATN-encoded by converting them to an `AlgebraicValue`, +then BSATN-encoding that meta-value. + +See [the SATN JSON Format](/sats-json) +for more details of the conversion to meta values. +Note that these meta values are converted to BSATN and _not JSON_. diff --git a/docs/docs/15-appendix/index.md b/docs/docs/15-appendix/index.md new file mode 100644 index 00000000000..40e34834d37 --- /dev/null +++ b/docs/docs/15-appendix/index.md @@ -0,0 +1,68 @@ +--- +slug: /appendix +--- + +# Appendix + +## SEQUENCE + +For each table containing an `#[auto_inc]` column, SpacetimeDB creates a sequence number generator behind the scenes, which functions similarly to `postgres`'s `SEQUENCE`. + +### How It Works + +:::warning + +Sequence number generation is not transactional. + +::: + +- Sequences in SpacetimeDB use Rust’s `i128` integer type. +- The field type marked with `#[auto_inc]` is cast to `i128` and increments by `1` for each new row. +- Sequences are pre-allocated in chunks of `4096` to speed up number generation, and then are only persisted to disk when the pre-allocated chunk is exhausted. +- Numbers are incremented even if a transaction is later rolled back. +- Unused numbers are not reclaimed, meaning sequences may have _gaps_. +- If the server restarts or a transaction rolls back, the sequence continues from the next pre-allocated chunk + `1`: + +**Example:** + +```rust +#[spacetimedb::table(name = users, public)] +struct Users { + #[auto_inc] + user_id: u64, + name: String, +} + +#[spacetimedb::reducer] +pub fn insert_user(ctx: &ReducerContext, count: u8) { + for i in 0..count { + let name = format!("User {}", i); + ctx.db.users().insert(Users { user_id: 0, name }); + } + // Query the table to see the effect of the `[auto_inc]` attribute: + for user in ctx.db.users().iter() { + log::info!("User: {:?}", user); + } +} +``` + +Then: + +```bash +❯ cargo run --bin spacetimedb-cli call sample insert_user 3 + +❯ spacetimedb-cli logs sample +... +.. User: Users { user_id: 1, name: "User 0" } +.. User: Users { user_id: 2, name: "User 1" } +.. User: Users { user_id: 3, name: "User 2" } + +# Database restart, then + +❯ cargo run --bin spacetimedb-cli call sample insert_user 1 + +❯ spacetimedb-cli logs sample +... +.. User: Users { user_id: 3, name: "User 2" } +.. User: Users { user_id: 4098, name: "User 0" } +``` diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index beb84237742..725187fc176 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -47,7 +47,8 @@ const config: Config = { favicon: 'https://spacetimedb.com/favicon-32x32.png', url: 'https://spacetimedb.com', - baseUrl: '/docs/', + // this means the site is served at https://spacetimedb.com/docs/ + baseUrl: '/docs/', onBrokenLinks: 'throw', onBrokenAnchors: 'throw', @@ -198,6 +199,7 @@ const config: Config = { }, ], ], + }; export default config; diff --git a/docs/package.json b/docs/package.json index bea5a4e5103..5e657c01a8a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,10 +15,11 @@ "typecheck": "tsc" }, "dependencies": { - "@docusaurus/core": "3.9.1", - "@docusaurus/plugin-content-docs": "^3.9.2", - "@docusaurus/preset-classic": "3.9.1", - "@docusaurus/theme-common": "^3.9.1", + "@docusaurus/core": "3.9.2", + "@docusaurus/plugin-client-redirects": "^3.9.2", + "@docusaurus/plugin-content-docs": "3.9.2", + "@docusaurus/preset-classic": "3.9.2", + "@docusaurus/theme-common": "3.9.2", "@easyops-cn/docusaurus-search-local": "^0.49.2", "@fontsource-variable/inter": "^5.2.8", "@fontsource-variable/source-code-pro": "^5.2.7", @@ -29,16 +30,25 @@ "@shikijs/rehype": "^3.3.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", - "react": "^19.0.0", - "react-dom": "^19.0.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", "shiki": "^3.3.0" }, "devDependencies": { - "@docusaurus/module-type-aliases": "3.9.1", - "@docusaurus/tsconfig": "3.9.1", - "@docusaurus/types": "3.9.1", + "@docusaurus/module-type-aliases": "3.9.2", + "@docusaurus/tsconfig": "3.9.2", + "@docusaurus/types": "3.9.2", + "@types/react": "^18.3.23", + "@types/react-dom": "^18.3.0", "typescript": "~5.6.2" }, + "pnpm": { + "overrides": { + "@docusaurus/*": "3.9.2", + "react": "18.3.1", + "react-dom": "18.3.1" + } + }, "browserslist": { "production": [ ">0.5%", diff --git a/docs/src/components/CardLink.tsx b/docs/src/components/CardLink.tsx new file mode 100644 index 00000000000..530c04e8776 --- /dev/null +++ b/docs/src/components/CardLink.tsx @@ -0,0 +1,55 @@ +import React, { ReactNode } from "react"; +import Link from "@docusaurus/Link"; +import { useDocById } from "@docusaurus/plugin-content-docs/client"; +import Heading from "@theme/Heading"; +import clsx from "clsx"; + +export type Item = { + href: string; + label: string; + icon?: ReactNode; + invertIcon?: boolean; + docId?: string; + description?: string; +}; + +function DocDescription({ docId }: { docId: string }) { + const doc = useDocById(docId); + return ( +

+ {doc?.description ?? ""} +

+ ); +} + +export function CardLink({ + className, + item, +}: { + className?: string; + item: Item; +}) { + const icon = item.icon; + return ( + + {icon} +
+ + {item.label} + + {item.docId ? ( + + ) : item.description ? ( +

{item.description}

+ ) : null} +
+ + ); +} \ No newline at end of file diff --git a/docs/src/components/CardLinkGrid.tsx b/docs/src/components/CardLinkGrid.tsx new file mode 100644 index 00000000000..e51c4849889 --- /dev/null +++ b/docs/src/components/CardLinkGrid.tsx @@ -0,0 +1,12 @@ +import { CardLink, Item } from "./CardLink"; + +export function CardLinkGrid(props: { items: Item[] }) { + const { items } = props; + return ( +
+ {items.map((item, index) => ( + + ))} +
+ ); +} \ No newline at end of file diff --git a/docs/src/components/DocsList.tsx b/docs/src/components/DocsList.tsx new file mode 100644 index 00000000000..16e998b58c2 --- /dev/null +++ b/docs/src/components/DocsList.tsx @@ -0,0 +1,20 @@ +import { useAllDocsData } from '@docusaurus/plugin-content-docs/lib/client/index.js'; + +export default function DocList() { + const allDocsData = useAllDocsData(); + // `default` is the ID of the docs plugin instance + const docs = allDocsData['default'].versions[0].docs; + + const docIds = docs.map((doc) => doc.id); + + return ( +
+

All Doc IDs

+
    + {docIds.map((id) => ( +
  • {id}
  • + ))} +
+
+ ); +} \ No newline at end of file diff --git a/docs/src/components/InstallCardLink.tsx b/docs/src/components/InstallCardLink.tsx new file mode 100644 index 00000000000..6d2004435c6 --- /dev/null +++ b/docs/src/components/InstallCardLink.tsx @@ -0,0 +1,8 @@ +import { CardLink } from "./CardLink"; +import CLIIcon from "@site/static/images/icons/cli-icon.svg"; + +export function InstallCardLink() { + return ( + }} /> + ); +} \ No newline at end of file diff --git a/docs/src/components/QuickstartLinks.tsx b/docs/src/components/QuickstartLinks.tsx new file mode 100644 index 00000000000..a6de5289458 --- /dev/null +++ b/docs/src/components/QuickstartLinks.tsx @@ -0,0 +1,94 @@ +import { CardLinkGrid } from "./CardLinkGrid"; +// import NextJSLogo from "@site/static/images/logos/nextjs-logo.svg"; +// import RemixLogo from "@site/static/images/logos/remix-logo.svg"; +// import NodeJSLogo from "@site/static/images/logos/nodejs-logo.svg"; +// import BunLogo from "@site/static/images/logos/bun-logo.svg"; +// import Html5Logo from "@site/static/images/logos/html5-logo.svg"; +import TypeScriptLogo from "@site/static/images/logos/typescript-logo.svg"; +import CSharpLogo from "@site/static/images/logos/csharp-logo.svg"; +import RustLogo from "@site/static/images/logos/rust-logo.svg"; +// import ReactLogo from "@site/static/images/logos/react-logo.svg"; +// import UnityLogo from "@site/static/images/logos/unity-logo.svg"; +// import UnrealLogo from "@site/static/images/logos/unreal-logo.svg"; + +export function QuickstartLinks() { + return ( + , + href: "/quickstarts/typescript", + docId: "quickstarts/typescript", + label: "TypeScript", + }, + { + icon: , + href: "/quickstarts/c-sharp", + docId: "quickstarts/c-sharp", + label: "C#", + }, + { + icon: , + href: "/quickstarts/rust", + docId: "quickstarts/rust", + invertIcon: true, + label: "Rust", + }, + // { + // icon: , + // href: "/quickstart/react", + // docId: "quickstart/react", + // label: "React", + // }, + // { + // icon: , + // href: "/quickstart/unity", + // docId: "quickstart/unity", + // label: "Unity", + // }, + // { + // icon: , + // href: "/quickstart/unreal", + // docId: "quickstart/unreal", + // label: "Unreal", + // }, + // { + // icon: , + // href: "/quickstart/react", + // docId: "quickstart/react", + // label: "React", + // }, + // { + // icon: , + // href: "/quickstart/nextjs", + // docId: "quickstart/nextjs", + // label: "Next.js", + // }, + // { + // icon: , + // href: "/quickstart/remix", + // docId: "quickstart/remix", + // label: "Remix", + // }, + // { + // icon: , + // href: "/quickstart/nodejs", + // docId: "quickstart/nodejs", + // label: "Node.js", + // }, + // { + // icon: , + // href: "/quickstart/bun", + // docId: "quickstart/bun", + // label: "Bun", + // }, + // { + // icon: , + // href: "/quickstart/script-tag", + // docId: "quickstart/script-tag", + // label: "Script tag", + // }, + ]} + /> + ); +} \ No newline at end of file diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index ebbdd843e84..ae31a33eda1 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -1,80 +1,8 @@ @import '@fontsource-variable/inter'; @import '@fontsource-variable/source-code-pro'; +@import './typography.css'; :root { - /* // rem conversions */ - --8px: 0.5rem; - --9px: 0.5625rem; - --10px: 0.625rem; - --11px: 0.6875rem; - --12px: 0.75rem; - --13px: 0.8125rem; - --14px: 0.875rem; - --15px: 0.9375rem; - --16px: 1rem; - --17px: 1.0625rem; - --18px: 1.125rem; - --19px: 1.1875rem; - --20px: 1.25rem; - --21px: 1.3125rem; - --22px: 1.375rem; - --23px: 1.4375rem; - --24px: 1.5rem; - --25px: 1.5625rem; - --26px: 1.625rem; - --27px: 1.6875rem; - --28px: 1.75rem; - --29px: 1.8125rem; - --30px: 1.875rem; - --31px: 1.9375rem; - --32px: 2rem; - --33px: 2.0625rem; - --34px: 2.125rem; - --35px: 2.1875rem; - --36px: 2.25rem; - --37px: 2.3125rem; - --38px: 2.375rem; - --39px: 2.4375rem; - --40px: 2.5rem; - --41px: 2.5625rem; - --42px: 2.625rem; - --43px: 2.6875rem; - --44px: 2.75rem; - --45px: 2.8125rem; - --46px: 2.875rem; - --47px: 2.9375rem; - --48px: 3rem; - --49px: 3.0625rem; - --50px: 3.125rem; - --51px: 3.1875rem; - --52px: 3.25rem; - --53px: 3.3125rem; - --54px: 3.375rem; - --55px: 3.4375rem; - --56px: 3.5rem; - --57px: 3.5625rem; - --58px: 3.625rem; - --59px: 3.6875rem; - --60px: 3.75rem; - --61px: 3.8125rem; - --62px: 3.875rem; - --63px: 3.9375rem; - --64px: 4rem; - --65px: 4.0625rem; - --66px: 4.125rem; - --67px: 4.1875rem; - --68px: 4.25rem; - --69px: 4.3125rem; - --70px: 4.375rem; - --71px: 4.4375rem; - --72px: 4.5rem; - --81px: 5.0625rem; - --90px: 5.625rem; - --108px: 6.75rem; - --118px: 7.40625rem; - --144px: 9rem; - --158px: 9.875rem; - /* // primary */ --clockworklabs-color-green: #4cf490; --clockworklabs-color-green-75: #4cf490bf; @@ -495,4 +423,66 @@ table { .DocSearch { width: inherit; } +} + +.cards { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; + margin: 16px 0 16px 0; +} + +/* 996px is the breakpoint between desktop and mobile in Docusaurus */ +@media screen and (max-width: 996px) { + .cards { + grid-template-columns: repeat(1, 1fr); + } +} + +a.card { + text-decoration: none; + color: inherit; +} + +.card { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + gap: 16px; + + &.card--invert-icon svg { + filter: invert(100%); + } + + svg { + min-width: 40px; + } + + .card--body { + display: flex; + flex-direction: column; + gap: 8px; + min-width: 0; + max-width: 100%; + + p { + margin: 0; + } + } + + border-radius: 8px; + border: 1px solid var(--clockworklabs-color-n6); + background: var(--clockworklabs-code-background-color); + padding: 16px 24px; + transition: box-shadow 0.2s ease-in-out; + cursor: pointer; + + &:hover { + background-color: var(--clockworklabs-color-n5); + } + + h6 { + margin: 0; + } } \ No newline at end of file diff --git a/docs/src/css/typography.css b/docs/src/css/typography.css new file mode 100644 index 00000000000..02501f9ee97 --- /dev/null +++ b/docs/src/css/typography.css @@ -0,0 +1,299 @@ +/* + This is copied verbatim from: https://github.com/clockworklabs/spacetime-web/blob/main/spacetimedb.com/app/styles/typography.css + IMPORTANT! Any changes should be propagated to that file as well. + + We use the following type ramp for headers and values on the site: + + https://www.figma.com/design/eb3GHGRnwqNx4iWXfwwVSS/SpacetimeDB-Library?node-id=3302-671&p=f&t=sQfp0SteZDkGVHpU-0 + + It is based on the Inter font family with a 16px base, on the Major Third + scale (1.25 ratio): + + https://www.modularscale.com/?16&px&1.25 + + The following font sizes are copied from the Figma design. The font size is + rounded to the nearest whole number of pixels, and the line height is + rounded to the nearest multiple of 4 pixels. + + hero: 144px/158px + + h1: 61px/72px + h2: 49px/56px + h3: 39px/44px + h4: 31px/36px + h5: 25px/28px + h6: 20px/24px + + value1: 49px/56px + value2: 31px/36px + value3: 14px/20px + + body1: 18px/28px + body2: 16px/24px + body3: 14px/20px + + code1: 16px/24px + code2: 14px/20px + + menu: 14px/16px + + tagline1: 14px/16px + tagline2: 12px/12px + + caption1: 12px/16px + caption2: 11px/12px + caption3: 10px/12px + + We always use rem for font sizes and line heights to ensure that the text + scales with the user's browser settings. However, we always use px for all + other measurements to ensure that the layout remains consistent across all + devices. + + See: + https://www.joshwcomeau.com/css/surprising-truth-about-pixels-and-accessibility/ + + We convert between rem and px assuming a base font size of 16px. This is the + default font size in most browsers, and it's the size that most users have + configured in their browser settings. + + I've included a table at the end of the file that does the conversion + between rem and px for the most common font sizes. +*/ + +.text-hero { + font-size: 144px; + line-height: var(--158px); + font-weight: 800; + letter-spacing: calc(var(--144px) * -0.04); + + @media (max-width: 1023px) { + font-size: var(--108px); + line-height: var(--118px); + } + + @media (max-width: 767px) { + font-size: var(--81px); + line-height: var(--90px); + } +} + +h1, +.text-xl { + font-size: var(--61px); + line-height: var(--72px); + font-weight: 400; + letter-spacing: calc(var(--61px) * -0.04); +} + +h2, +.text-l { + font-size: var(--49px); + line-height: var(--56px); + font-weight: 400; + letter-spacing: calc(var(--49px) * -0.04); +} + +h3, +.text-m { + font-size: var(--39px); + line-height: var(--44px); + font-weight: 400; + letter-spacing: calc(var(--39px) * -0.04); +} + +h4, +.text-s { + font-size: var(--31px); + line-height: var(--36px); + font-weight: 400; + letter-spacing: calc(var(--31px) * -0.04); +} + +h5, +.text-xs { + font-size: var(--25px); + line-height: var(--28px); + font-weight: 500; + letter-spacing: calc(var(--25px) * -0.04); +} + +h6, +.text-xxs { + font-size: var(--20px); + line-height: var(--24px); + font-weight: 600; + letter-spacing: calc(var(--20px) * -0.04); +} + +.text-value-1 { + font-family: var(--font-source); + font-size: var(--49px); + line-height: var(--56px); + letter-spacing: calc(var(--49px) * 0); +} + +.text-value-2 { + font-family: var(--font-source); + font-size: var(--31px); + line-height: var(--36px); + letter-spacing: calc(var(--31px) * 0); +} + +.text-value-3 { + font-family: var(--font-source); + font-size: var(--14px); + line-height: var(--20px); + font-weight: 600; + letter-spacing: calc(var(--14px) * 0); +} + +.text-body-1 { + font-size: var(--21px); + line-height: var(--32px); + letter-spacing: calc(var(--18px) * -0.01); +} + +.text-body-2 { + font-size: var(--16px); + line-height: var(--24px); + letter-spacing: calc(var(--16px) * -0.01); +} + +.text-body-3 { + font-size: var(--12px); + line-height: var(--16px); + letter-spacing: calc(var(--14px) * -0.01); +} + +.text-code-1 { + font-family: var(--font-source); + font-size: var(--16px); + line-height: var(--24px); + letter-spacing: calc(var(--16px) * -0.05); +} + +.text-code-2 { + font-family: var(--font-source); + font-size: var(--14px); + line-height: var(--20px); + letter-spacing: calc(var(--14px) * -0.05); +} + +.text-menu { + font-family: var(--font-source); + font-size: var(--14px); + line-height: var(--16px); + font-weight: 600; + letter-spacing: calc(var(--14px) * 0.08); + text-transform: uppercase; +} + +.text-tagline-1 { + font-family: var(--font-source); + font-size: var(--14px); + line-height: var(--16px); + font-weight: 600; + letter-spacing: calc(var(--14px) * 0); + text-transform: uppercase; +} + +.text-tagline-2 { + font-family: var(--font-source); + font-size: var(--12px); + line-height: var(--12px); + font-weight: 600; + letter-spacing: calc(var(--12px) * 0.02); + text-transform: uppercase; +} + +.text-caption-1 { + font-size: var(--12px); + line-height: var(--16px); + letter-spacing: calc(var(--12px) * 0.01); +} + +.text-caption-2 { + font-size: var(--11px); + line-height: var(--12px); + letter-spacing: calc(var(--11px) * 0.01); +} + +.text-caption-3 { + font-size: var(--10px); + line-height: var(--12px); + letter-spacing: calc(var(--10px) * 0.01); +} + +:root { + --8px: 0.5rem; + --9px: 0.5625rem; + --10px: 0.625rem; + --11px: 0.6875rem; + --12px: 0.75rem; + --13px: 0.8125rem; + --14px: 0.875rem; + --15px: 0.9375rem; + --16px: 1rem; + --17px: 1.0625rem; + --18px: 1.125rem; + --19px: 1.1875rem; + --20px: 1.25rem; + --21px: 1.3125rem; + --22px: 1.375rem; + --23px: 1.4375rem; + --24px: 1.5rem; + --25px: 1.5625rem; + --26px: 1.625rem; + --27px: 1.6875rem; + --28px: 1.75rem; + --29px: 1.8125rem; + --30px: 1.875rem; + --31px: 1.9375rem; + --32px: 2rem; + --33px: 2.0625rem; + --34px: 2.125rem; + --35px: 2.1875rem; + --36px: 2.25rem; + --37px: 2.3125rem; + --38px: 2.375rem; + --39px: 2.4375rem; + --40px: 2.5rem; + --41px: 2.5625rem; + --42px: 2.625rem; + --43px: 2.6875rem; + --44px: 2.75rem; + --45px: 2.8125rem; + --46px: 2.875rem; + --47px: 2.9375rem; + --48px: 3rem; + --49px: 3.0625rem; + --50px: 3.125rem; + --51px: 3.1875rem; + --52px: 3.25rem; + --53px: 3.3125rem; + --54px: 3.375rem; + --55px: 3.4375rem; + --56px: 3.5rem; + --57px: 3.5625rem; + --58px: 3.625rem; + --59px: 3.6875rem; + --60px: 3.75rem; + --61px: 3.8125rem; + --62px: 3.875rem; + --63px: 3.9375rem; + --64px: 4rem; + --65px: 4.0625rem; + --66px: 4.125rem; + --67px: 4.1875rem; + --68px: 4.25rem; + --69px: 4.3125rem; + --70px: 4.375rem; + --71px: 4.4375rem; + --72px: 4.5rem; + --81px: 5.0625rem; + --90px: 5.625rem; + --108px: 6.75rem; + --118px: 7.40625rem; + --144px: 9rem; + --158px: 9.875rem; +} \ No newline at end of file diff --git a/docs/static/images/icons/cli-icon.svg b/docs/static/images/icons/cli-icon.svg new file mode 100644 index 00000000000..a946687dc23 --- /dev/null +++ b/docs/static/images/icons/cli-icon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/static/images/icons/spacetimedb-icon.svg b/docs/static/images/icons/spacetimedb-icon.svg new file mode 100644 index 00000000000..57029ae9898 --- /dev/null +++ b/docs/static/images/icons/spacetimedb-icon.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/docs/static/images/icons/spin-up-icon.svg b/docs/static/images/icons/spin-up-icon.svg new file mode 100644 index 00000000000..7356cbb5f42 --- /dev/null +++ b/docs/static/images/icons/spin-up-icon.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/docs/static/images/logos/bun-logo.svg b/docs/static/images/logos/bun-logo.svg new file mode 100644 index 00000000000..aaec074212f --- /dev/null +++ b/docs/static/images/logos/bun-logo.svg @@ -0,0 +1,25 @@ + + Bun Logo + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/static/images/logos/csharp-logo.svg b/docs/static/images/logos/csharp-logo.svg new file mode 100644 index 00000000000..37cbbd2d568 --- /dev/null +++ b/docs/static/images/logos/csharp-logo.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/static/images/logos/html5-logo.svg b/docs/static/images/logos/html5-logo.svg new file mode 100644 index 00000000000..7f0fbd9a433 --- /dev/null +++ b/docs/static/images/logos/html5-logo.svg @@ -0,0 +1,8 @@ + + HTML5 Logo + + + + + + \ No newline at end of file diff --git a/docs/static/images/logos/javascript-logo.svg b/docs/static/images/logos/javascript-logo.svg new file mode 100644 index 00000000000..6cb2c9c2213 --- /dev/null +++ b/docs/static/images/logos/javascript-logo.svg @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/docs/static/images/logos/nextjs-logo.svg b/docs/static/images/logos/nextjs-logo.svg new file mode 100644 index 00000000000..e3eab3464b1 --- /dev/null +++ b/docs/static/images/logos/nextjs-logo.svg @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/docs/static/images/logos/nodejs-logo.svg b/docs/static/images/logos/nodejs-logo.svg new file mode 100644 index 00000000000..6acf9227af5 --- /dev/null +++ b/docs/static/images/logos/nodejs-logo.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/images/logos/react-logo.svg b/docs/static/images/logos/react-logo.svg new file mode 100644 index 00000000000..e07b101184d --- /dev/null +++ b/docs/static/images/logos/react-logo.svg @@ -0,0 +1,9 @@ + + React Logo + + + + + + + \ No newline at end of file diff --git a/docs/static/images/logos/remix-logo.svg b/docs/static/images/logos/remix-logo.svg new file mode 100644 index 00000000000..9f5cf565e94 --- /dev/null +++ b/docs/static/images/logos/remix-logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/static/images/logos/rust-logo.svg b/docs/static/images/logos/rust-logo.svg new file mode 100644 index 00000000000..069824645ce --- /dev/null +++ b/docs/static/images/logos/rust-logo.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/images/logos/typescript-logo.svg b/docs/static/images/logos/typescript-logo.svg new file mode 100644 index 00000000000..6a811a0cdb2 --- /dev/null +++ b/docs/static/images/logos/typescript-logo.svg @@ -0,0 +1,16 @@ + + + + diff --git a/docs/static/images/logos/unity-logo.svg b/docs/static/images/logos/unity-logo.svg new file mode 100644 index 00000000000..306a4306e49 --- /dev/null +++ b/docs/static/images/logos/unity-logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/docs/static/images/logos/unreal-logo.svg b/docs/static/images/logos/unreal-logo.svg new file mode 100644 index 00000000000..28e4a3a2289 --- /dev/null +++ b/docs/static/images/logos/unreal-logo.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/docs/tsconfig.json b/docs/tsconfig.json index 920d7a6523b..5153109b8e5 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -4,5 +4,6 @@ "compilerOptions": { "baseUrl": "." }, + "include": ["src", "docusaurus.config.ts", "sidebars.ts"], "exclude": [".docusaurus", "build"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd66da9016c..4bebb51eb9c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -207,20 +207,23 @@ importers: docs: dependencies: '@docusaurus/core': - specifier: 3.9.1 - version: 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-docs': + specifier: 3.9.2 + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-client-redirects': specifier: ^3.9.2 - version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(debug@4.4.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': + specifier: 3.9.2 + version: 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/preset-classic': - specifier: 3.9.1 - version: 3.9.1(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3) + specifier: 3.9.2 + version: 3.9.2(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.6.3) '@docusaurus/theme-common': - specifier: ^3.9.1 - version: 3.9.1(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 3.9.2 + version: 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@easyops-cn/docusaurus-search-local': specifier: ^0.49.2 - version: 0.49.2(@docusaurus/theme-common@3.9.1(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + version: 0.49.2(@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@fontsource-variable/inter': specifier: ^5.2.8 version: 5.2.8 @@ -229,16 +232,16 @@ importers: version: 5.2.7 '@inkeep/cxkit-docusaurus': specifier: ^0.5.98 - version: 0.5.98(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12) + version: 0.5.98(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12) '@inkeep/cxkit-react': specifier: ^0.5.101 - version: 0.5.101(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12) + version: 0.5.101(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12) '@inkeep/widgets': specifier: ^0.2.292 - version: 0.2.292(@internationalized/date@3.10.0)(@types/react@19.2.0)(jsdom@26.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + version: 0.2.292(@internationalized/date@3.10.0)(@types/react@18.3.23)(jsdom@26.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@mdx-js/react': specifier: ^3.0.0 - version: 3.1.1(@types/react@19.2.0)(react@19.2.0) + version: 3.1.1(@types/react@18.3.23)(react@18.3.1) '@shikijs/rehype': specifier: ^3.3.0 version: 3.13.0 @@ -247,26 +250,32 @@ importers: version: 2.1.1 prism-react-renderer: specifier: ^2.3.0 - version: 2.4.1(react@19.2.0) + version: 2.4.1(react@18.3.1) react: - specifier: ^19.0.0 - version: 19.2.0 + specifier: ^18.3.1 + version: 18.3.1 react-dom: - specifier: ^19.0.0 - version: 19.2.0(react@19.2.0) + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) shiki: specifier: ^3.3.0 version: 3.13.0 devDependencies: '@docusaurus/module-type-aliases': - specifier: 3.9.1 - version: 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 3.9.2 + version: 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/tsconfig': - specifier: 3.9.1 - version: 3.9.1 + specifier: 3.9.2 + version: 3.9.2 '@docusaurus/types': - specifier: 3.9.1 - version: 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + specifier: 3.9.2 + version: 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react': + specifier: ^18.3.23 + version: 18.3.23 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.7(@types/react@18.3.23) typescript: specifier: ~5.6.2 version: 5.6.3 @@ -1366,23 +1375,10 @@ packages: search-insights: optional: true - '@docusaurus/babel@3.9.1': - resolution: {integrity: sha512-/uoi3oG+wvbVWNBRfPrzrEslOSeLxrQEyWMywK51TLDFTANqIRivzkMusudh5bdDty8fXzCYUT+tg5t697jYqg==} - engines: {node: '>=20.0'} - '@docusaurus/babel@3.9.2': resolution: {integrity: sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA==} engines: {node: '>=20.0'} - '@docusaurus/bundler@3.9.1': - resolution: {integrity: sha512-E1c9DgNmAz4NqbNtiJVp4UgjLtr8O01IgtXD/NDQ4PZaK8895cMiTOgb3k7mN0qX8A3lb8vqyrPJ842+yMpuUg==} - engines: {node: '>=20.0'} - peerDependencies: - '@docusaurus/faster': '*' - peerDependenciesMeta: - '@docusaurus/faster': - optional: true - '@docusaurus/bundler@3.9.2': resolution: {integrity: sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA==} engines: {node: '>=20.0'} @@ -1392,15 +1388,6 @@ packages: '@docusaurus/faster': optional: true - '@docusaurus/core@3.9.1': - resolution: {integrity: sha512-FWDk1LIGD5UR5Zmm9rCrXRoxZUgbwuP6FBA7rc50DVfzqDOMkeMe3NyJhOsA2dF0zBE3VbHEIMmTjKwTZJwbaA==} - engines: {node: '>=20.0'} - hasBin: true - peerDependencies: - '@mdx-js/react': ^3.0.0 - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/core@3.9.2': resolution: {integrity: sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==} engines: {node: '>=20.0'} @@ -1410,10 +1397,6 @@ packages: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/cssnano-preset@3.9.1': - resolution: {integrity: sha512-2y7+s7RWQMqBg+9ejeKwvZs7Bdw/hHIVJIodwMXbs2kr+S48AhcmAfdOh6Cwm0unJb0hJUshN0ROwRoQMwl3xg==} - engines: {node: '>=20.0'} - '@docusaurus/cssnano-preset@3.9.2': resolution: {integrity: sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ==} engines: {node: '>=20.0'} @@ -1426,13 +1409,6 @@ packages: resolution: {integrity: sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA==} engines: {node: '>=20.0'} - '@docusaurus/mdx-loader@3.9.1': - resolution: {integrity: sha512-/1PY8lqry8jCt0qZddJSpc0U2sH6XC27kVJZfpA7o2TiQ3mdBQyH5AVbj/B2m682B1ounE+XjI0LdpOkAQLPoA==} - engines: {node: '>=20.0'} - peerDependencies: - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/mdx-loader@3.9.2': resolution: {integrity: sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ==} engines: {node: '>=20.0'} @@ -1440,30 +1416,24 @@ packages: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/module-type-aliases@3.9.1': - resolution: {integrity: sha512-YBce3GbJGGcMbJTyHcnEOMvdXqg41pa5HsrMCGA5Rm4z0h0tHS6YtEldj0mlfQRhCG7Y0VD66t2tb87Aom+11g==} - peerDependencies: - react: '*' - react-dom: '*' - '@docusaurus/module-type-aliases@3.9.2': resolution: {integrity: sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew==} peerDependencies: react: '*' react-dom: '*' - '@docusaurus/plugin-content-blog@3.9.1': - resolution: {integrity: sha512-vT6kIimpJLWvW9iuWzH4u7VpTdsGlmn4yfyhq0/Kb1h4kf9uVouGsTmrD7WgtYBUG1P+TSmQzUUQa+ALBSRTig==} + '@docusaurus/plugin-client-redirects@3.9.2': + resolution: {integrity: sha512-lUgMArI9vyOYMzLRBUILcg9vcPTCyyI2aiuXq/4npcMVqOr6GfmwtmBYWSbNMlIUM0147smm4WhpXD0KFboffw==} engines: {node: '>=20.0'} peerDependencies: - '@docusaurus/plugin-content-docs': '*' react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-content-docs@3.9.1': - resolution: {integrity: sha512-DyLk9BIA6I9gPIuia8XIL+XIEbNnExam6AHzRsfrEq4zJr7k/DsWW7oi4aJMepDnL7jMRhpVcdsCxdjb0/A9xg==} + '@docusaurus/plugin-content-blog@3.9.2': + resolution: {integrity: sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==} engines: {node: '>=20.0'} peerDependencies: + '@docusaurus/plugin-content-docs': '*' react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 @@ -1474,61 +1444,61 @@ packages: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-content-pages@3.9.1': - resolution: {integrity: sha512-/1wFzRnXYASI+Nv9ck9IVPIMw0O5BGQ8ZVhDzEwhkL+tl44ycvSnY6PIe6rW2HLxsw61Z3WFwAiU8+xMMtMZpg==} + '@docusaurus/plugin-content-pages@3.9.2': + resolution: {integrity: sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-css-cascade-layers@3.9.1': - resolution: {integrity: sha512-/QyW2gRCk/XE3ttCK/ERIgle8KJ024dBNKMu6U5SmpJvuT2il1n5jR/48Pp/9wEwut8WVml4imNm6X8JsL5A0Q==} + '@docusaurus/plugin-css-cascade-layers@3.9.2': + resolution: {integrity: sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ==} engines: {node: '>=20.0'} - '@docusaurus/plugin-debug@3.9.1': - resolution: {integrity: sha512-qPeAuk0LccC251d7jg2MRhNI+o7niyqa924oEM/AxnZJvIpMa596aAxkRImiAqNN6+gtLE1Hkrz/RHUH2HDGsA==} + '@docusaurus/plugin-debug@3.9.2': + resolution: {integrity: sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-google-analytics@3.9.1': - resolution: {integrity: sha512-k4Qq2HphqOrIU/CevGPdEO1yJnWUI8m0zOJsYt5NfMJwNsIn/gDD6gv/DKD+hxHndQT5pacsfBd4BWHZVNVroQ==} + '@docusaurus/plugin-google-analytics@3.9.2': + resolution: {integrity: sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-google-gtag@3.9.1': - resolution: {integrity: sha512-n9BURBiQyJKI/Ecz35IUjXYwXcgNCSq7/eA07+ZYcDiSyH2p/EjPf8q/QcZG3CyEJPZ/SzGkDHePfcVPahY4Gg==} + '@docusaurus/plugin-google-gtag@3.9.2': + resolution: {integrity: sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-google-tag-manager@3.9.1': - resolution: {integrity: sha512-rZAQZ25ZuXaThBajxzLjXieTDUCMmBzfAA6ThElQ3o7Q+LEpOjCIrwGFau0KLY9HeG6x91+FwwsAM8zeApYDrg==} + '@docusaurus/plugin-google-tag-manager@3.9.2': + resolution: {integrity: sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-sitemap@3.9.1': - resolution: {integrity: sha512-k/bf5cXDxAJUYTzqatgFJwmZsLUbIgl6S8AdZMKGG2Mv2wcOHt+EQNN9qPyWZ5/9cFj+Q8f8DN+KQheBMYLong==} + '@docusaurus/plugin-sitemap@3.9.2': + resolution: {integrity: sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/plugin-svgr@3.9.1': - resolution: {integrity: sha512-TeZOXT2PSdTNR1OpDJMkYqFyX7MMhbd4t16hQByXksgZQCXNyw3Dio+KaDJ2Nj+LA4WkOvsk45bWgYG5MAaXSQ==} + '@docusaurus/plugin-svgr@3.9.2': + resolution: {integrity: sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/preset-classic@3.9.1': - resolution: {integrity: sha512-ZHga2xsxxsyd0dN1BpLj8S889Eu9eMBuj2suqxdw/vaaXu/FjJ8KEGbcaeo6nHPo8VQcBBnPEdkBtSDm2TfMNw==} + '@docusaurus/preset-classic@3.9.2': + resolution: {integrity: sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 @@ -1539,21 +1509,13 @@ packages: peerDependencies: react: '*' - '@docusaurus/theme-classic@3.9.1': - resolution: {integrity: sha512-LrAIu/mQ04nG6s1cssC0TMmICD8twFIIn/hJ5Pd9uIPQvtKnyAKEn12RefopAul5KfMo9kixPaqogV5jIJr26w==} + '@docusaurus/theme-classic@3.9.2': + resolution: {integrity: sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/theme-common@3.9.1': - resolution: {integrity: sha512-j9adi961F+6Ps9d0jcb5BokMcbjXAAJqKkV43eo8nh4YgmDj7KUNDX4EnOh/MjTQeO06oPY5cxp3yUXdW/8Ggw==} - engines: {node: '>=20.0'} - peerDependencies: - '@docusaurus/plugin-content-docs': '*' - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/theme-common@3.9.2': resolution: {integrity: sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==} engines: {node: '>=20.0'} @@ -1562,8 +1524,8 @@ packages: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 - '@docusaurus/theme-search-algolia@3.9.1': - resolution: {integrity: sha512-WjM28bzlgfT6nHlEJemkwyGVpvGsZWPireV/w+wZ1Uo64xCZ8lNOb4xwQRukDaLSed3oPBN0gSnu06l5VuCXHg==} + '@docusaurus/theme-search-algolia@3.9.2': + resolution: {integrity: sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw==} engines: {node: '>=20.0'} peerDependencies: react: ^18.0.0 || ^19.0.0 @@ -1573,8 +1535,12 @@ packages: resolution: {integrity: sha512-mUQd49BSGKTiM6vP9+JFgRJL28lMIN3PUvXjF3rzuOHMByUZUBNwCt26Z23GkKiSIOrRkjKoaBNTipR/MHdYSQ==} engines: {node: '>=20.0'} - '@docusaurus/tsconfig@3.9.1': - resolution: {integrity: sha512-stdzM1dNDgRO0OvxeznXlE3N1igUoeHPNJjiKqyffLizgpVgNXJBAWeG6fuoYiCH4udGUBqy2dyM+1+kG2/UPQ==} + '@docusaurus/theme-translations@3.9.2': + resolution: {integrity: sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==} + engines: {node: '>=20.0'} + + '@docusaurus/tsconfig@3.9.2': + resolution: {integrity: sha512-j6/Fp4Rlpxsc632cnRnl5HpOWeb6ZKssDj6/XzzAzVGXXfm9Eptx3rxCC+fDzySn9fHTS+CWJjPineCR1bB5WQ==} '@docusaurus/types@3.9.1': resolution: {integrity: sha512-ElekJ29sk39s5LTEZMByY1c2oH9FMtw7KbWFU3BtuQ1TytfIK39HhUivDEJvm5KCLyEnnfUZlvSNDXeyk0vzAA==} @@ -3360,9 +3326,6 @@ packages: '@types/react@19.1.13': resolution: {integrity: sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==} - '@types/react@19.2.0': - resolution: {integrity: sha512-1LOH8xovvsKsCBq1wnT4ntDUdCJKmnEakhsuoUSy6ExlHCkGP2hqnatagYTgFk6oeL0VU31u7SNjunPN+GchtA==} - '@types/retry@0.12.2': resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} @@ -4239,6 +4202,11 @@ packages: resolution: {integrity: sha512-uA9fOtlTRC0iqKfzff1W34DXUA3GyVqbUaeo3Rw3d4gd1eavKVCETXrn3NzO74W+UVkG3UHu8WxUi+XvKI/huA==} engines: {node: '>= 10.16.0'} + browserslist@4.25.2: + resolution: {integrity: sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + browserslist@4.26.3: resolution: {integrity: sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -4314,6 +4282,9 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + caniuse-lite@1.0.30001735: + resolution: {integrity: sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==} + caniuse-lite@1.0.30001747: resolution: {integrity: sha512-mzFa2DGIhuc5490Nd/G31xN1pnBnYMadtkyTjefPI7wzypqgCEpeWu9bJr0OnDsyKrW75zA9ZAt7pbQFmwLsQg==} @@ -4874,6 +4845,9 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + electron-to-chromium@1.5.204: + resolution: {integrity: sha512-s9VbBXWxfDrl67PlO4avwh0/GU2vcwx8Fph3wlR8LJl7ySGYId59EFE17VWVcuC3sLWNPENm6Z/uGqKbkPCcXA==} + electron-to-chromium@1.5.229: resolution: {integrity: sha512-cwhDcZKGcT/rEthLRJ9eBlMDkh1sorgsuk+6dpsehV0g9CABsIqBxU4rLRjG+d/U6pYU1s37A4lSKrVc5lSQYg==} @@ -6571,6 +6545,9 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-releases@2.0.21: resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} @@ -7404,11 +7381,6 @@ packages: peerDependencies: react: ^18.3.1 - react-dom@19.2.0: - resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} - peerDependencies: - react: ^19.2.0 - react-error-boundary@4.1.2: resolution: {integrity: sha512-GQDxZ5Jd+Aq/qUxbCm1UtzmL/s++V7zKgE8yMktJiCQXCCFZnMZh9ng+6/Ne6PjNSXH0L9CjeOEREfRnq6Duag==} peerDependencies: @@ -7542,10 +7514,6 @@ packages: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} - react@19.2.0: - resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} - engines: {node: '>=0.10.0'} - readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -7768,9 +7736,6 @@ packages: scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} - scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - schema-dts@1.1.5: resolution: {integrity: sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==} @@ -8882,12 +8847,12 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/react@2.0.77(react@19.2.0)(zod@4.1.12)': + '@ai-sdk/react@2.0.77(react@18.3.1)(zod@4.1.12)': dependencies: '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) ai: 5.0.77(zod@4.1.12) - react: 19.2.0 - swr: 2.3.6(react@19.2.0) + react: 18.3.1 + swr: 2.3.6(react@18.3.1) throttleit: 2.1.0 optionalDependencies: zod: 4.1.12 @@ -9005,7 +8970,7 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.30 - '@apollo/client@3.14.0(@types/react@19.2.0)(graphql-ws@5.16.2(graphql@16.11.0))(graphql@16.11.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@apollo/client@3.14.0(@types/react@18.3.23)(graphql-ws@5.16.2(graphql@16.11.0))(graphql@16.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) '@wry/caches': 1.0.1 @@ -9016,15 +8981,15 @@ snapshots: hoist-non-react-statics: 3.3.2 optimism: 0.18.1 prop-types: 15.8.1 - rehackt: 0.1.0(@types/react@19.2.0)(react@19.2.0) + rehackt: 0.1.0(@types/react@18.3.23)(react@18.3.1) symbol-observable: 4.0.0 ts-invariant: 0.10.3 tslib: 2.8.1 zen-observable-ts: 1.2.5 optionalDependencies: graphql-ws: 5.16.2(graphql@16.11.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - '@types/react' @@ -9065,7 +9030,7 @@ snapshots: transitivePeerDependencies: - '@internationalized/date' - '@ark-ui/react@0.15.0(@internationalized/date@3.10.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@ark-ui/react@0.15.0(@internationalized/date@3.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@zag-js/accordion': 0.19.1 '@zag-js/anatomy': 0.19.1 @@ -9091,7 +9056,7 @@ snapshots: '@zag-js/radio-group': 0.19.1 '@zag-js/range-slider': 0.19.1 '@zag-js/rating-group': 0.19.1 - '@zag-js/react': 0.19.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@zag-js/react': 0.19.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@zag-js/select': 0.19.1 '@zag-js/slider': 0.19.1 '@zag-js/splitter': 0.19.1 @@ -9102,8 +9067,8 @@ snapshots: '@zag-js/toggle-group': 0.19.1 '@zag-js/tooltip': 0.19.1 '@zag-js/types': 0.19.1 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - '@internationalized/date' @@ -9159,7 +9124,7 @@ snapshots: dependencies: '@babel/compat-data': 7.28.0 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.26.3 + browserslist: 4.25.2 lru-cache: 5.1.1 semver: 6.3.1 @@ -9205,7 +9170,7 @@ snapshots: '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.3 '@babel/types': 7.28.2 transitivePeerDependencies: - supports-color @@ -9647,7 +9612,7 @@ snapshots: '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color @@ -9827,7 +9792,7 @@ snapshots: dependencies: '@babel/core': 7.28.3 '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 esutils: 2.0.3 '@babel/preset-react@7.27.1(@babel/core@7.28.3)': @@ -10220,9 +10185,9 @@ snapshots: '@docsearch/css@4.2.0': {} - '@docsearch/react@4.2.0(@algolia/client-search@5.39.0)(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)': + '@docsearch/react@4.2.0(@algolia/client-search@5.39.0)(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)': dependencies: - '@ai-sdk/react': 2.0.77(react@19.2.0)(zod@4.1.12) + '@ai-sdk/react': 2.0.77(react@18.3.1)(zod@4.1.12) '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.39.0)(algoliasearch@5.39.0)(search-insights@2.17.3) '@docsearch/css': 4.2.0 ai: 5.0.77(zod@4.1.12) @@ -10230,40 +10195,14 @@ snapshots: marked: 16.4.1 zod: 4.1.12 optionalDependencies: - '@types/react': 19.2.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@types/react': 18.3.23 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/babel@3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': - dependencies: - '@babel/core': 7.28.3 - '@babel/generator': 7.28.3 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.28.3) - '@babel/plugin-transform-runtime': 7.28.3(@babel/core@7.28.3) - '@babel/preset-env': 7.28.3(@babel/core@7.28.3) - '@babel/preset-react': 7.27.1(@babel/core@7.28.3) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.3) - '@babel/runtime': 7.28.4 - '@babel/runtime-corejs3': 7.28.4 - '@babel/traverse': 7.28.3 - '@docusaurus/logger': 3.9.1 - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - babel-plugin-dynamic-import-node: 2.3.3 - fs-extra: 11.3.2 - tslib: 2.8.1 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - react - - react-dom - - supports-color - - uglify-js - - webpack-cli - - '@docusaurus/babel@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/babel@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/core': 7.28.3 '@babel/generator': 7.28.3 @@ -10276,7 +10215,7 @@ snapshots: '@babel/runtime-corejs3': 7.28.4 '@babel/traverse': 7.28.4 '@docusaurus/logger': 3.9.2 - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) babel-plugin-dynamic-import-node: 2.3.3 fs-extra: 11.3.2 tslib: 2.8.1 @@ -10289,55 +10228,14 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/bundler@3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': - dependencies: - '@babel/core': 7.28.3 - '@docusaurus/babel': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/cssnano-preset': 3.9.1 - '@docusaurus/logger': 3.9.1 - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - babel-loader: 9.2.1(@babel/core@7.28.3)(webpack@5.102.0) - clean-css: 5.3.3 - copy-webpack-plugin: 11.0.0(webpack@5.102.0) - css-loader: 6.11.0(webpack@5.102.0) - css-minimizer-webpack-plugin: 5.0.1(clean-css@5.3.3)(webpack@5.102.0) - cssnano: 6.1.2(postcss@8.5.6) - file-loader: 6.2.0(webpack@5.102.0) - html-minifier-terser: 7.2.0 - mini-css-extract-plugin: 2.9.4(webpack@5.102.0) - null-loader: 4.0.1(webpack@5.102.0) - postcss: 8.5.6 - postcss-loader: 7.3.4(postcss@8.5.6)(typescript@5.6.3)(webpack@5.102.0) - postcss-preset-env: 10.4.0(postcss@8.5.6) - terser-webpack-plugin: 5.3.14(webpack@5.102.0) - tslib: 2.8.1 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.102.0))(webpack@5.102.0) - webpack: 5.102.0 - webpackbar: 6.0.1(webpack@5.102.0) - transitivePeerDependencies: - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - csso - - esbuild - - lightningcss - - react - - react-dom - - supports-color - - typescript - - uglify-js - - webpack-cli - - '@docusaurus/bundler@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/bundler@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: '@babel/core': 7.28.3 - '@docusaurus/babel': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/babel': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/cssnano-preset': 3.9.2 '@docusaurus/logger': 3.9.2 - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) babel-loader: 9.2.1(@babel/core@7.28.3)(webpack@5.102.0) clean-css: 5.3.3 copy-webpack-plugin: 11.0.0(webpack@5.102.0) @@ -10371,80 +10269,16 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/core@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': - dependencies: - '@docusaurus/babel': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/bundler': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/logger': 3.9.1 - '@docusaurus/mdx-loader': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@mdx-js/react': 3.1.1(@types/react@19.2.0)(react@19.2.0) - boxen: 6.2.1 - chalk: 4.1.2 - chokidar: 3.6.0 - cli-table3: 0.6.5 - combine-promises: 1.2.0 - commander: 5.1.0 - core-js: 3.45.1 - detect-port: 1.6.1 - escape-html: 1.0.3 - eta: 2.2.0 - eval: 0.1.8 - execa: 5.1.1 - fs-extra: 11.3.2 - html-tags: 3.3.1 - html-webpack-plugin: 5.6.4(webpack@5.102.0) - leven: 3.1.0 - lodash: 4.17.21 - open: 8.4.2 - p-map: 4.0.0 - prompts: 2.4.2 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.0))(webpack@5.102.0) - react-router: 5.3.4(react@19.2.0) - react-router-config: 5.1.1(react-router@5.3.4(react@19.2.0))(react@19.2.0) - react-router-dom: 5.3.4(react@19.2.0) - semver: 7.7.2 - serve-handler: 6.1.6 - tinypool: 1.1.1 - tslib: 2.8.1 - update-notifier: 6.0.2 - webpack: 5.102.0 - webpack-bundle-analyzer: 4.10.2 - webpack-dev-server: 5.2.2(debug@4.4.3)(webpack@5.102.0) - webpack-merge: 6.0.1 - transitivePeerDependencies: - - '@docusaurus/faster' - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - bufferutil - - csso - - debug - - esbuild - - lightningcss - - supports-color - - typescript - - uglify-js - - utf-8-validate - - webpack-cli - - '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(debug@4.4.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/babel': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/bundler': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/babel': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/bundler': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@mdx-js/react': 3.1.1(@types/react@19.2.0)(react@19.2.0) + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/react': 3.1.1(@types/react@18.3.23)(react@18.3.1) boxen: 6.2.1 chalk: 4.1.2 chokidar: 3.6.0 @@ -10465,14 +10299,14 @@ snapshots: open: 8.4.2 p-map: 4.0.0 prompts: 2.4.2 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' - react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.0))(webpack@5.102.0) - react-router: 5.3.4(react@19.2.0) - react-router-config: 5.1.1(react-router@5.3.4(react@19.2.0))(react@19.2.0) - react-router-dom: 5.3.4(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' + react-loadable-ssr-addon-v5-slorber: 1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.102.0) + react-router: 5.3.4(react@18.3.1) + react-router-config: 5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1) + react-router-dom: 5.3.4(react@18.3.1) semver: 7.7.2 serve-handler: 6.1.6 tinypool: 1.1.1 @@ -10499,13 +10333,6 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/cssnano-preset@3.9.1': - dependencies: - cssnano-preset-advanced: 6.1.2(postcss@8.5.6) - postcss: 8.5.6 - postcss-sort-media-queries: 5.2.0(postcss@8.5.6) - tslib: 2.8.1 - '@docusaurus/cssnano-preset@3.9.2': dependencies: cssnano-preset-advanced: 6.1.2(postcss@8.5.6) @@ -10523,46 +10350,11 @@ snapshots: chalk: 4.1.2 tslib: 2.8.1 - '@docusaurus/mdx-loader@3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': - dependencies: - '@docusaurus/logger': 3.9.1 - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@mdx-js/mdx': 3.1.1 - '@slorber/remark-comment': 1.0.0 - escape-html: 1.0.3 - estree-util-value-to-estree: 3.4.0 - file-loader: 6.2.0(webpack@5.102.0) - fs-extra: 11.3.2 - image-size: 2.0.2 - mdast-util-mdx: 3.0.0 - mdast-util-to-string: 4.0.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - rehype-raw: 7.0.0 - remark-directive: 3.0.1 - remark-emoji: 4.0.1 - remark-frontmatter: 5.0.0 - remark-gfm: 4.0.1 - stringify-object: 3.3.0 - tslib: 2.8.1 - unified: 11.0.5 - unist-util-visit: 5.0.0 - url-loader: 4.1.1(file-loader@6.2.0(webpack@5.102.0))(webpack@5.102.0) - vfile: 6.0.3 - webpack: 5.102.0 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - uglify-js - - webpack-cli - - '@docusaurus/mdx-loader@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/mdx-loader@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/logger': 3.9.2 - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mdx-js/mdx': 3.1.1 '@slorber/remark-comment': 1.0.0 escape-html: 1.0.3 @@ -10572,8 +10364,8 @@ snapshots: image-size: 2.0.2 mdast-util-mdx: 3.0.0 mdast-util-to-string: 4.0.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) rehype-raw: 7.0.0 remark-directive: 3.0.1 remark-emoji: 4.0.1 @@ -10593,17 +10385,17 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/module-type-aliases@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 '@types/react': 18.3.23 '@types/react-router-config': 5.0.11 '@types/react-router-dom': 5.3.3 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' transitivePeerDependencies: - '@swc/core' - esbuild @@ -10611,41 +10403,54 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/module-type-aliases@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/plugin-client-redirects@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@types/history': 4.7.11 - '@types/react': 18.3.23 - '@types/react-router-config': 5.0.11 - '@types/react-router-dom': 5.3.3 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + eta: 2.2.0 + fs-extra: 11.3.2 + lodash: 4.17.21 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 transitivePeerDependencies: + - '@docusaurus/faster' + - '@mdx-js/react' + - '@parcel/css' + - '@rspack/core' - '@swc/core' + - '@swc/css' + - bufferutil + - csso + - debug - esbuild + - lightningcss - supports-color + - typescript - uglify-js + - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-blog@3.9.1(@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-content-blog@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/logger': 3.9.1 - '@docusaurus/mdx-loader': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/plugin-content-docs': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-common': 3.9.1(@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) cheerio: 1.0.0-rc.12 feed: 4.2.2 fs-extra: 11.3.2 lodash: 4.17.21 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) schema-dts: 1.1.5 srcset: 4.0.0 tslib: 2.8.1 @@ -10670,24 +10475,24 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/logger': 3.9.1 - '@docusaurus/mdx-loader': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/module-type-aliases': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/theme-common': 3.9.1(@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.3.2 js-yaml: 4.1.0 lodash: 4.17.21 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) schema-dts: 1.1.5 tslib: 2.8.1 utility-types: 3.11.0 @@ -10710,25 +10515,25 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(debug@4.4.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(debug@4.4.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@docusaurus/logger': 3.9.2 - '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/react-router-config': 5.0.11 combine-promises: 1.2.0 fs-extra: 11.3.2 js-yaml: 4.1.0 lodash: 4.17.21 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - schema-dts: 1.1.5 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + schema-dts: 1.1.5 tslib: 2.8.1 utility-types: 3.11.0 webpack: 5.102.0 @@ -10750,16 +10555,16 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-pages@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-content-pages@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/mdx-loader': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.2 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 webpack: 5.102.0 transitivePeerDependencies: @@ -10780,12 +10585,12 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-css-cascade-layers@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-css-cascade-layers@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -10807,15 +10612,15 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-debug@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-debug@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.2 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-json-view-lite: 2.5.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-json-view-lite: 2.5.0(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -10835,13 +10640,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-analytics@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-google-analytics@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -10861,14 +10666,14 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-gtag@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-google-gtag@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/gtag.js': 0.0.12 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -10888,13 +10693,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-google-tag-manager@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -10914,17 +10719,17 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-sitemap@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-sitemap@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/logger': 3.9.1 - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.2 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) sitemap: 7.1.2 tslib: 2.8.1 transitivePeerDependencies: @@ -10945,16 +10750,16 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-svgr@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/plugin-svgr@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@svgr/core': 8.1.0(typescript@5.6.3) '@svgr/webpack': 8.1.0(typescript@5.6.3) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 webpack: 5.102.0 transitivePeerDependencies: @@ -10975,25 +10780,25 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.9.1(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3)': - dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-blog': 3.9.1(@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-docs': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-pages': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-css-cascade-layers': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-debug': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-google-analytics': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-google-gtag': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-google-tag-manager': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-sitemap': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-svgr': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-classic': 3.9.1(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-common': 3.9.1(@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/theme-search-algolia': 3.9.1(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3) - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.6.3)': + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-css-cascade-layers': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-debug': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-google-analytics': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-google-gtag': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-google-tag-manager': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-sitemap': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/theme-classic': 3.9.2(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.6.3) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - '@algolia/client-search' - '@docusaurus/faster' @@ -11015,37 +10820,37 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/react-loadable@6.0.0(react@19.2.0)': + '@docusaurus/react-loadable@6.0.0(react@18.3.1)': dependencies: '@types/react': 18.3.23 - react: 19.2.0 + react: 18.3.1 - '@docusaurus/theme-classic@3.9.1(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@docusaurus/theme-classic@3.9.2(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/logger': 3.9.1 - '@docusaurus/mdx-loader': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/module-type-aliases': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/plugin-content-blog': 3.9.1(@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-docs': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/plugin-content-pages': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-common': 3.9.1(@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/theme-translations': 3.9.1 - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@mdx-js/react': 3.1.1(@types/react@19.2.0)(react@19.2.0) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/plugin-content-pages': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-translations': 3.9.2 + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mdx-js/react': 3.1.1(@types/react@18.3.23)(react@18.3.1) clsx: 2.1.1 infima: 0.2.0-alpha.45 lodash: 4.17.21 nprogress: 0.2.0 postcss: 8.5.6 - prism-react-renderer: 2.4.1(react@19.2.0) + prism-react-renderer: 2.4.1(react@18.3.1) prismjs: 1.30.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-router-dom: 5.3.4(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router-dom: 5.3.4(react@18.3.1) rtlcss: 4.3.0 tslib: 2.8.1 utility-types: 3.11.0 @@ -11067,45 +10872,21 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-common@3.9.1(@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': - dependencies: - '@docusaurus/mdx-loader': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/module-type-aliases': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/plugin-content-docs': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@types/history': 4.7.11 - '@types/react': 18.3.23 - '@types/react-router-config': 5.0.11 - clsx: 2.1.1 - parse-numeric-range: 1.3.0 - prism-react-renderer: 2.4.1(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - tslib: 2.8.1 - utility-types: 3.11.0 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - supports-color - - uglify-js - - webpack-cli - - '@docusaurus/theme-common@3.9.1(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/mdx-loader': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/module-type-aliases': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(debug@4.4.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 '@types/react': 18.3.23 '@types/react-router-config': 5.0.11 clsx: 2.1.1 parse-numeric-range: 1.3.0 - prism-react-renderer: 2.4.1(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + prism-react-renderer: 2.4.1(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: @@ -11115,21 +10896,21 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/mdx-loader': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/module-type-aliases': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(debug@4.4.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/mdx-loader': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/module-type-aliases': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 '@types/react': 18.3.23 '@types/react-router-config': 5.0.11 clsx: 2.1.1 parse-numeric-range: 1.3.0 - prism-react-renderer: 2.4.1(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + prism-react-renderer: 2.4.1(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: @@ -11139,24 +10920,24 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-search-algolia@3.9.1(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3)(typescript@5.6.3)': + '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.39.0)(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.6.3)': dependencies: - '@docsearch/react': 4.2.0(@algolia/client-search@5.39.0)(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(search-insights@2.17.3) - '@docusaurus/core': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/logger': 3.9.1 - '@docusaurus/plugin-content-docs': 3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-common': 3.9.1(@docusaurus/plugin-content-docs@3.9.1(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/theme-translations': 3.9.1 - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docsearch/react': 4.2.0(@algolia/client-search@5.39.0)(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/logger': 3.9.2 + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-translations': 3.9.2 + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) algoliasearch: 5.39.0 algoliasearch-helper: 3.26.0(algoliasearch@5.39.0) clsx: 2.1.1 eta: 2.2.0 fs-extra: 11.3.2 lodash: 4.17.21 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 utility-types: 3.11.0 transitivePeerDependencies: @@ -11185,9 +10966,14 @@ snapshots: fs-extra: 11.3.2 tslib: 2.8.1 - '@docusaurus/tsconfig@3.9.1': {} + '@docusaurus/theme-translations@3.9.2': + dependencies: + fs-extra: 11.3.2 + tslib: 2.8.1 + + '@docusaurus/tsconfig@3.9.2': {} - '@docusaurus/types@3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/types@3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@mdx-js/mdx': 3.1.1 '@types/history': 4.7.11 @@ -11195,9 +10981,9 @@ snapshots: '@types/react': 18.3.23 commander: 5.1.0 joi: 17.13.3 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' utility-types: 3.11.0 webpack: 5.102.0 webpack-merge: 5.10.0 @@ -11208,7 +10994,7 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/types@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/types@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@mdx-js/mdx': 3.1.1 '@types/history': 4.7.11 @@ -11216,9 +11002,9 @@ snapshots: '@types/react': 18.3.23 commander: 5.1.0 joi: 17.13.3 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)' + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-helmet-async: '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)' utility-types: 3.11.0 webpack: 5.102.0 webpack-merge: 5.10.0 @@ -11229,9 +11015,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-common@3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/utils-common@3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@swc/core' @@ -11242,9 +11028,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-common@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/utils-common@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@swc/core' @@ -11255,11 +11041,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-validation@3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/utils-validation@3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/logger': 3.9.1 - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.2 joi: 17.13.3 js-yaml: 4.1.0 @@ -11274,11 +11060,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils-validation@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/utils-validation@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/logger': 3.9.2 - '@docusaurus/utils': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.2 joi: 17.13.3 js-yaml: 4.1.0 @@ -11293,11 +11079,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/utils@3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/logger': 3.9.1 - '@docusaurus/types': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) escape-string-regexp: 4.0.0 execa: 5.1.1 file-loader: 6.2.0(webpack@5.102.0) @@ -11325,11 +11111,11 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/utils@3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@docusaurus/utils@3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/logger': 3.9.2 - '@docusaurus/types': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/types': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) escape-string-regexp: 4.0.0 execa: 5.1.1 file-loader: 6.2.0(webpack@5.102.0) @@ -11362,14 +11148,14 @@ snapshots: cssesc: 3.0.0 immediate: 3.3.0 - '@easyops-cn/docusaurus-search-local@0.49.2(@docusaurus/theme-common@3.9.1(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@easyops-cn/docusaurus-search-local@0.49.2(@docusaurus/theme-common@3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(debug@4.4.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) - '@docusaurus/theme-common': 3.9.1(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(debug@4.4.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) + '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/theme-translations': 3.9.1 - '@docusaurus/utils': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-common': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@docusaurus/utils-validation': 3.9.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@docusaurus/utils': 3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-common': 3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/utils-validation': 3.9.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@easyops-cn/autocomplete.js': 0.38.1 '@node-rs/jieba': 1.10.4 cheerio: 1.1.2 @@ -11381,8 +11167,8 @@ snapshots: lunr: 2.3.9 lunr-languages: 1.14.0 mark.js: 8.11.1 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) tslib: 2.8.1 transitivePeerDependencies: - '@docusaurus/faster' @@ -11566,11 +11352,11 @@ snapshots: '@floating-ui/core': 1.7.3 '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@floating-ui/react-dom@2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/dom': 1.7.4 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) '@floating-ui/utils@0.1.6': {} @@ -11603,22 +11389,22 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inkeep/color-mode@0.0.26(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@inkeep/color-mode@0.0.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@inkeep/components@0.0.26(@ark-ui/react@0.15.0(@internationalized/date@3.10.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@internationalized/date@3.10.0)(jsdom@26.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@inkeep/components@0.0.26(@ark-ui/react@0.15.0(@internationalized/date@3.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@internationalized/date@3.10.0)(jsdom@26.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@ark-ui/react': 0.15.0(@internationalized/date@3.10.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@ark-ui/react': 0.15.0(@internationalized/date@3.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@inkeep/preset': 0.0.26(@internationalized/date@3.10.0)(jsdom@26.1.0)(typescript@5.6.3) '@inkeep/preset-chakra': 0.0.26(@internationalized/date@3.10.0)(jsdom@26.1.0)(typescript@5.6.3) '@inkeep/shared': 0.0.27 '@inkeep/styled-system': 0.0.48 '@pandacss/dev': 0.22.1(jsdom@26.1.0)(typescript@5.6.3) - framer-motion: 10.18.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + framer-motion: 10.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - '@internationalized/date' - jsdom @@ -11628,13 +11414,13 @@ snapshots: '@inkeep/cxkit-color-mode@0.5.98': {} - '@inkeep/cxkit-docusaurus@0.5.98(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12)': + '@inkeep/cxkit-docusaurus@0.5.98(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12)': dependencies: - '@inkeep/cxkit-react': 0.5.98(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12) + '@inkeep/cxkit-react': 0.5.98(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12) merge-anything: 5.1.7 path: 0.12.7 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - '@types/react' - '@types/react-dom' @@ -11642,60 +11428,60 @@ snapshots: - supports-color - zod - '@inkeep/cxkit-primitives@0.5.101(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12)': + '@inkeep/cxkit-primitives@0.5.101(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12)': dependencies: '@inkeep/cxkit-color-mode': 0.5.101 '@inkeep/cxkit-theme': 0.5.101 '@inkeep/cxkit-types': 0.5.101 '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-avatar': 1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-checkbox': 1.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-popover': 1.1.6(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-scroll-area': 1.2.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-tabs': 1.1.13(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-tooltip': 1.1.6(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.0)(react@19.2.0) + '@radix-ui/react-avatar': 1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-checkbox': 1.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-popover': 1.1.6(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-scroll-area': 1.2.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tooltip': 1.1.6(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1) '@zag-js/focus-trap': 1.25.0 '@zag-js/presence': 1.25.0 - '@zag-js/react': 1.25.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@zag-js/react': 1.25.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) altcha-lib: 1.3.0 aria-hidden: 1.2.6 dequal: 2.0.3 humps: 2.0.1 - lucide-react: 0.503.0(react@19.2.0) + lucide-react: 0.503.0(react@18.3.1) marked: 15.0.12 merge-anything: 5.1.7 openai: 4.78.1(zod@4.1.12) - prism-react-renderer: 2.4.1(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-error-boundary: 6.0.0(react@19.2.0) - react-hook-form: 7.54.2(react@19.2.0) - react-markdown: 9.0.3(@types/react@19.2.0)(react@19.2.0) - react-remove-scroll: 2.7.1(@types/react@19.2.0)(react@19.2.0) - react-svg: 16.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-textarea-autosize: 8.5.7(@types/react@19.2.0)(react@19.2.0) + prism-react-renderer: 2.4.1(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-error-boundary: 6.0.0(react@18.3.1) + react-hook-form: 7.54.2(react@18.3.1) + react-markdown: 9.0.3(@types/react@18.3.23)(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.23)(react@18.3.1) + react-svg: 16.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-textarea-autosize: 8.5.7(@types/react@18.3.23)(react@18.3.1) rehype-raw: 7.0.0 remark-gfm: 4.0.1 unist-util-visit: 5.0.0 - use-sync-external-store: 1.6.0(react@19.2.0) + use-sync-external-store: 1.6.0(react@18.3.1) transitivePeerDependencies: - '@types/react' - '@types/react-dom' @@ -11703,60 +11489,60 @@ snapshots: - supports-color - zod - '@inkeep/cxkit-primitives@0.5.98(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12)': + '@inkeep/cxkit-primitives@0.5.98(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12)': dependencies: '@inkeep/cxkit-color-mode': 0.5.98 '@inkeep/cxkit-theme': 0.5.98 '@inkeep/cxkit-types': 0.5.98 '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-avatar': 1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-checkbox': 1.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-popover': 1.1.6(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-scroll-area': 1.2.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-tabs': 1.1.13(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-tooltip': 1.1.6(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.0)(react@19.2.0) + '@radix-ui/react-avatar': 1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-checkbox': 1.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-popover': 1.1.6(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-scroll-area': 1.2.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tooltip': 1.1.6(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1) '@zag-js/focus-trap': 1.25.0 '@zag-js/presence': 1.25.0 - '@zag-js/react': 1.25.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@zag-js/react': 1.25.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) altcha-lib: 1.3.0 aria-hidden: 1.2.6 dequal: 2.0.3 humps: 2.0.1 - lucide-react: 0.503.0(react@19.2.0) + lucide-react: 0.503.0(react@18.3.1) marked: 15.0.12 merge-anything: 5.1.7 openai: 4.78.1(zod@4.1.12) - prism-react-renderer: 2.4.1(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-error-boundary: 6.0.0(react@19.2.0) - react-hook-form: 7.54.2(react@19.2.0) - react-markdown: 9.0.3(@types/react@19.2.0)(react@19.2.0) - react-remove-scroll: 2.7.1(@types/react@19.2.0)(react@19.2.0) - react-svg: 16.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-textarea-autosize: 8.5.7(@types/react@19.2.0)(react@19.2.0) + prism-react-renderer: 2.4.1(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-error-boundary: 6.0.0(react@18.3.1) + react-hook-form: 7.54.2(react@18.3.1) + react-markdown: 9.0.3(@types/react@18.3.23)(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.23)(react@18.3.1) + react-svg: 16.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-textarea-autosize: 8.5.7(@types/react@18.3.23)(react@18.3.1) rehype-raw: 7.0.0 remark-gfm: 4.0.1 unist-util-visit: 5.0.0 - use-sync-external-store: 1.6.0(react@19.2.0) + use-sync-external-store: 1.6.0(react@18.3.1) transitivePeerDependencies: - '@types/react' - '@types/react-dom' @@ -11764,11 +11550,11 @@ snapshots: - supports-color - zod - '@inkeep/cxkit-react@0.5.101(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12)': + '@inkeep/cxkit-react@0.5.101(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12)': dependencies: - '@inkeep/cxkit-styled': 0.5.101(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.0)(react@19.2.0) - lucide-react: 0.503.0(react@19.2.0) + '@inkeep/cxkit-styled': 0.5.101(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1) + lucide-react: 0.503.0(react@18.3.1) transitivePeerDependencies: - '@types/react' - '@types/react-dom' @@ -11778,11 +11564,11 @@ snapshots: - supports-color - zod - '@inkeep/cxkit-react@0.5.98(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12)': + '@inkeep/cxkit-react@0.5.98(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12)': dependencies: - '@inkeep/cxkit-styled': 0.5.98(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.0)(react@19.2.0) - lucide-react: 0.503.0(react@19.2.0) + '@inkeep/cxkit-styled': 0.5.98(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1) + lucide-react: 0.503.0(react@18.3.1) transitivePeerDependencies: - '@types/react' - '@types/react-dom' @@ -11792,9 +11578,9 @@ snapshots: - supports-color - zod - '@inkeep/cxkit-styled@0.5.101(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12)': + '@inkeep/cxkit-styled@0.5.101(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12)': dependencies: - '@inkeep/cxkit-primitives': 0.5.101(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12) + '@inkeep/cxkit-primitives': 0.5.101(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12) class-variance-authority: 0.7.1 clsx: 2.1.1 merge-anything: 5.1.7 @@ -11808,9 +11594,9 @@ snapshots: - supports-color - zod - '@inkeep/cxkit-styled@0.5.98(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12)': + '@inkeep/cxkit-styled@0.5.98(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12)': dependencies: - '@inkeep/cxkit-primitives': 0.5.98(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(zod@4.1.12) + '@inkeep/cxkit-primitives': 0.5.98(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(zod@4.1.12) class-variance-authority: 0.7.1 clsx: 2.1.1 merge-anything: 5.1.7 @@ -11862,12 +11648,12 @@ snapshots: '@inkeep/styled-system@0.0.48': {} - '@inkeep/widgets@0.2.292(@internationalized/date@3.10.0)(@types/react@19.2.0)(jsdom@26.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3)': + '@inkeep/widgets@0.2.292(@internationalized/date@3.10.0)(@types/react@18.3.23)(jsdom@26.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3)': dependencies: - '@apollo/client': 3.14.0(@types/react@19.2.0)(graphql-ws@5.16.2(graphql@16.11.0))(graphql@16.11.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@ark-ui/react': 0.15.0(@internationalized/date@3.10.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@inkeep/color-mode': 0.0.26(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@inkeep/components': 0.0.26(@ark-ui/react@0.15.0(@internationalized/date@3.10.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@internationalized/date@3.10.0)(jsdom@26.1.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.6.3) + '@apollo/client': 3.14.0(@types/react@18.3.23)(graphql-ws@5.16.2(graphql@16.11.0))(graphql@16.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ark-ui/react': 0.15.0(@internationalized/date@3.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@inkeep/color-mode': 0.0.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@inkeep/components': 0.0.26(@ark-ui/react@0.15.0(@internationalized/date@3.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@internationalized/date@3.10.0)(jsdom@26.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) '@inkeep/preset': 0.0.26(@internationalized/date@3.10.0)(jsdom@26.1.0)(typescript@5.6.3) '@inkeep/preset-chakra': 0.0.26(@internationalized/date@3.10.0)(jsdom@26.1.0)(typescript@5.6.3) '@inkeep/shared': 0.0.27 @@ -11875,20 +11661,20 @@ snapshots: '@types/lodash.isequal': 4.5.8 graphql: 16.11.0 graphql-ws: 5.16.2(graphql@16.11.0) - html-react-parser: 3.0.16(react@19.2.0) + html-react-parser: 3.0.16(react@18.3.1) humps: 2.0.1 lodash.isequal: 4.5.0 - prism-react-renderer: 2.4.1(react@19.2.0) + prism-react-renderer: 2.4.1(react@18.3.1) prismjs: 1.30.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-error-boundary: 4.1.2(react@19.2.0) - react-hook-form: 7.54.2(react@19.2.0) - react-hotkeys-hook: 4.6.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-icons: 4.12.0(react@19.2.0) - react-markdown: 8.0.7(@types/react@19.2.0)(react@19.2.0) - react-svg: 16.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-textarea-autosize: 8.5.7(@types/react@19.2.0)(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-error-boundary: 4.1.2(react@18.3.1) + react-hook-form: 7.54.2(react@18.3.1) + react-hotkeys-hook: 4.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-icons: 4.12.0(react@18.3.1) + react-markdown: 8.0.7(@types/react@18.3.23)(react@18.3.1) + react-svg: 16.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-textarea-autosize: 8.5.7(@types/react@18.3.23)(react@18.3.1) rehype-raw: 6.1.1 xregexp: 5.1.2 transitivePeerDependencies: @@ -12024,11 +11810,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@mdx-js/react@3.1.1(@types/react@19.2.0)(react@19.2.0)': + '@mdx-js/react@3.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: '@types/mdx': 2.0.13 - '@types/react': 19.2.0 - react: 19.2.0 + '@types/react': 18.3.23 + react: 18.3.1 '@napi-rs/wasm-runtime@0.2.12': dependencies: @@ -12304,560 +12090,560 @@ snapshots: '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-arrow@1.1.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-arrow@1.1.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-arrow@1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-arrow@1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-avatar@1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-avatar@1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-context': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-checkbox@1.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-checkbox@1.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-previous': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-size': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-compose-refs@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-compose-refs@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-context@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-context@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-context@1.1.2(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-context@1.1.2(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-direction@1.1.0(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-direction@1.1.0(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-direction@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-direction@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-dismissable-layer@1.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-dismissable-layer@1.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-focus-guards@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-hover-card@1.1.15(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-hover-card@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-id@1.1.0(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-id@1.1.0(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-id@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-id@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-popover@1.1.6(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-popover@1.1.6(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.2.0)(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.23)(react@18.3.1) aria-hidden: 1.2.6 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - react-remove-scroll: 2.7.1(@types/react@19.2.0)(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.1(@types/react@18.3.23)(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) - - '@radix-ui/react-popper@1.2.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': - dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-arrow': 1.1.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-rect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-size': 1.1.0(@types/react@19.2.0)(react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) + + '@radix-ui/react-popper@1.2.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.23)(react@18.3.1) '@radix-ui/rect': 1.1.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) - - '@radix-ui/react-popper@1.2.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': - dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-rect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-size': 1.1.0(@types/react@19.2.0)(react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) + + '@radix-ui/react-popper@1.2.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.23)(react@18.3.1) '@radix-ui/rect': 1.1.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) - - '@radix-ui/react-popper@1.2.8(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': - dependencies: - '@floating-ui/react-dom': 2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.0)(react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.23)(react@18.3.1) '@radix-ui/rect': 1.1.1 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-portal@1.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-portal@1.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-portal@1.1.4(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-portal@1.1.4(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-portal@1.1.9(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-presence@1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-presence@1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-presence@1.1.5(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-presence@1.1.5(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-primitive@2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-primitive@2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-slot': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-primitive@2.0.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-primitive@2.0.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.1.2(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-slot': 1.1.2(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-scroll-area@1.2.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-scroll-area@1.2.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/number': 1.1.0 '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-direction': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-slot@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-slot@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-slot@1.1.2(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-slot@1.1.2(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-slot@1.2.3(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-slot@1.2.3(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-tabs@1.1.13(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-tabs@1.1.13(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-tooltip@1.1.6(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-tooltip@1.1.6(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-dismissable-layer': 1.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-popper': 1.2.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-portal': 1.1.3(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@radix-ui/react-slot': 1.1.1(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-visually-hidden': 1.1.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-context': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-popper': 1.2.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.1(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) - '@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-controllable-state@1.1.0(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.0)(react@19.2.0) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.23)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-previous@1.1.0(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-previous@1.1.0(@types/react@18.3.23)(react@18.3.1)': dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-rect@1.1.0(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.23)(react@18.3.1)': dependencies: '@radix-ui/rect': 1.1.0 - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: '@radix-ui/rect': 1.1.1 - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-size@1.1.0(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-size@1.1.0(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-use-size@1.1.1(@types/react@19.2.0)(react@19.2.0)': + '@radix-ui/react-use-size@1.1.1(@types/react@18.3.23)(react@18.3.1)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.0)(react@19.2.0) - react: 19.2.0 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.23)(react@18.3.1) + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - '@radix-ui/react-visually-hidden@1.1.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@radix-ui/react-visually-hidden@1.1.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@19.2.0))(@types/react@19.2.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 - '@types/react-dom': 18.3.7(@types/react@19.2.0) + '@types/react': 18.3.23 + '@types/react-dom': 18.3.7(@types/react@18.3.23) '@radix-ui/rect@1.1.0': {} @@ -12990,13 +12776,13 @@ snapshots: dependencies: size-limit: 11.2.0 - '@slorber/react-helmet-async@1.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@slorber/react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.28.4 invariant: 2.2.4 prop-types: 15.8.1 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) react-fast-compare: 3.2.2 shallowequal: 1.1.0 @@ -13352,11 +13138,6 @@ snapshots: dependencies: '@types/react': 18.3.23 - '@types/react-dom@18.3.7(@types/react@19.2.0)': - dependencies: - '@types/react': 19.2.0 - optional: true - '@types/react-router-config@5.0.11': dependencies: '@types/history': 4.7.11 @@ -13383,10 +13164,6 @@ snapshots: dependencies: csstype: 3.1.3 - '@types/react@19.2.0': - dependencies: - csstype: 3.1.3 - '@types/retry@0.12.2': {} '@types/sax@1.2.7': @@ -14418,23 +14195,23 @@ snapshots: '@zag-js/types': 0.20.0 '@zag-js/utils': 0.20.0 - '@zag-js/react@0.19.1(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@zag-js/react@0.19.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@zag-js/core': 0.19.1 '@zag-js/store': 0.19.1 '@zag-js/types': 0.19.1 proxy-compare: 2.5.1 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@zag-js/react@1.25.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@zag-js/react@1.25.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@zag-js/core': 1.25.0 '@zag-js/store': 1.25.0 '@zag-js/types': 1.25.0 '@zag-js/utils': 1.25.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) '@zag-js/rect-utils@0.19.1': {} @@ -14998,6 +14775,13 @@ snapshots: dependencies: duplexer: 0.1.1 + browserslist@4.25.2: + dependencies: + caniuse-lite: 1.0.30001735 + electron-to-chromium: 1.5.204 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.25.2) + browserslist@4.26.3: dependencies: baseline-browser-mapping: 2.8.10 @@ -15077,6 +14861,8 @@ snapshots: lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 + caniuse-lite@1.0.30001735: {} + caniuse-lite@1.0.30001747: {} ccount@2.0.1: {} @@ -15632,6 +15418,8 @@ snapshots: ee-first@1.1.1: {} + electron-to-chromium@1.5.204: {} + electron-to-chromium@1.5.229: {} emoji-regex@8.0.0: {} @@ -16088,13 +15876,13 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@10.18.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + framer-motion@10.18.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: tslib: 2.8.1 optionalDependencies: '@emotion/is-prop-valid': 0.8.8 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) fresh@0.5.2: {} @@ -16489,11 +16277,11 @@ snapshots: relateurl: 0.2.7 terser: 5.43.1 - html-react-parser@3.0.16(react@19.2.0): + html-react-parser@3.0.16(react@18.3.1): dependencies: domhandler: 5.0.3 html-dom-parser: 3.1.7 - react: 19.2.0 + react: 18.3.1 react-property: 2.0.0 style-to-js: 1.1.3 @@ -16995,9 +16783,9 @@ snapshots: dependencies: yallist: 3.1.1 - lucide-react@0.503.0(react@19.2.0): + lucide-react@0.503.0(react@18.3.1): dependencies: - react: 19.2.0 + react: 18.3.1 lunr-languages@1.14.0: {} @@ -17833,6 +17621,8 @@ snapshots: node-forge@1.3.1: {} + node-releases@2.0.19: {} + node-releases@2.0.21: {} normalize-path@3.0.0: {} @@ -18608,11 +18398,11 @@ snapshots: pretty-time@1.1.0: {} - prism-react-renderer@2.4.1(react@19.2.0): + prism-react-renderer@2.4.1(react@18.3.1): dependencies: '@types/prismjs': 1.26.5 clsx: 2.1.1 - react: 19.2.0 + react: 18.3.1 prismjs@1.30.0: {} @@ -18688,35 +18478,30 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 - react-dom@19.2.0(react@19.2.0): - dependencies: - react: 19.2.0 - scheduler: 0.27.0 - - react-error-boundary@4.1.2(react@19.2.0): + react-error-boundary@4.1.2(react@18.3.1): dependencies: '@babel/runtime': 7.28.4 - react: 19.2.0 + react: 18.3.1 - react-error-boundary@6.0.0(react@19.2.0): + react-error-boundary@6.0.0(react@18.3.1): dependencies: '@babel/runtime': 7.28.4 - react: 19.2.0 + react: 18.3.1 react-fast-compare@3.2.2: {} - react-hook-form@7.54.2(react@19.2.0): + react-hook-form@7.54.2(react@18.3.1): dependencies: - react: 19.2.0 + react: 18.3.1 - react-hotkeys-hook@4.6.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + react-hotkeys-hook@4.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react-icons@4.12.0(react@19.2.0): + react-icons@4.12.0(react@18.3.1): dependencies: - react: 19.2.0 + react: 18.3.1 react-is@16.13.1: {} @@ -18724,27 +18509,27 @@ snapshots: react-is@18.3.1: {} - react-json-view-lite@2.5.0(react@19.2.0): + react-json-view-lite@2.5.0(react@18.3.1): dependencies: - react: 19.2.0 + react: 18.3.1 - react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.0))(webpack@5.102.0): + react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@18.3.1))(webpack@5.102.0): dependencies: '@babel/runtime': 7.28.4 - react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.0)' + react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' webpack: 5.102.0 - react-markdown@8.0.7(@types/react@19.2.0)(react@19.2.0): + react-markdown@8.0.7(@types/react@18.3.23)(react@18.3.1): dependencies: '@types/hast': 2.3.10 '@types/prop-types': 15.7.15 - '@types/react': 19.2.0 + '@types/react': 18.3.23 '@types/unist': 2.0.11 comma-separated-tokens: 2.0.3 hast-util-whitespace: 2.0.1 prop-types: 15.8.1 property-information: 6.5.0 - react: 19.2.0 + react: 18.3.1 react-is: 18.3.1 remark-parse: 10.0.2 remark-rehype: 10.1.0 @@ -18756,15 +18541,15 @@ snapshots: transitivePeerDependencies: - supports-color - react-markdown@9.0.3(@types/react@19.2.0)(react@19.2.0): + react-markdown@9.0.3(@types/react@18.3.23)(react@18.3.1): dependencies: '@types/hast': 3.0.4 - '@types/react': 19.2.0 + '@types/react': 18.3.23 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.6 html-url-attributes: 3.0.1 mdast-util-to-hast: 13.2.0 - react: 19.2.0 + react: 18.3.1 remark-parse: 11.0.0 remark-rehype: 11.1.2 unified: 11.0.5 @@ -18777,43 +18562,43 @@ snapshots: react-refresh@0.17.0: {} - react-remove-scroll-bar@2.3.8(@types/react@19.2.0)(react@19.2.0): + react-remove-scroll-bar@2.3.8(@types/react@18.3.23)(react@18.3.1): dependencies: - react: 19.2.0 - react-style-singleton: 2.2.3(@types/react@19.2.0)(react@19.2.0) + react: 18.3.1 + react-style-singleton: 2.2.3(@types/react@18.3.23)(react@18.3.1) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - react-remove-scroll@2.7.1(@types/react@19.2.0)(react@19.2.0): + react-remove-scroll@2.7.1(@types/react@18.3.23)(react@18.3.1): dependencies: - react: 19.2.0 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.0)(react@19.2.0) - react-style-singleton: 2.2.3(@types/react@19.2.0)(react@19.2.0) + react: 18.3.1 + react-remove-scroll-bar: 2.3.8(@types/react@18.3.23)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.23)(react@18.3.1) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.0)(react@19.2.0) - use-sidecar: 1.1.3(@types/react@19.2.0)(react@19.2.0) + use-callback-ref: 1.3.3(@types/react@18.3.23)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.23)(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - react-router-config@5.1.1(react-router@5.3.4(react@19.2.0))(react@19.2.0): + react-router-config@5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.28.4 - react: 19.2.0 - react-router: 5.3.4(react@19.2.0) + react: 18.3.1 + react-router: 5.3.4(react@18.3.1) - react-router-dom@5.3.4(react@19.2.0): + react-router-dom@5.3.4(react@18.3.1): dependencies: '@babel/runtime': 7.28.4 history: 4.10.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.2.0 - react-router: 5.3.4(react@19.2.0) + react: 18.3.1 + react-router: 5.3.4(react@18.3.1) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react-router@5.3.4(react@19.2.0): + react-router@5.3.4(react@18.3.1): dependencies: '@babel/runtime': 7.28.4 history: 4.10.1 @@ -18821,34 +18606,34 @@ snapshots: loose-envify: 1.4.0 path-to-regexp: 1.9.0 prop-types: 15.8.1 - react: 19.2.0 + react: 18.3.1 react-is: 16.13.1 tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - react-style-singleton@2.2.3(@types/react@19.2.0)(react@19.2.0): + react-style-singleton@2.2.3(@types/react@18.3.23)(react@18.3.1): dependencies: get-nonce: 1.0.1 - react: 19.2.0 + react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - react-svg@16.3.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0): + react-svg@16.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.28.4 '@tanem/svg-injector': 10.1.68 '@types/prop-types': 15.7.15 prop-types: 15.8.1 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - react-textarea-autosize@8.5.7(@types/react@19.2.0)(react@19.2.0): + react-textarea-autosize@8.5.7(@types/react@18.3.23)(react@18.3.1): dependencies: '@babel/runtime': 7.28.4 - react: 19.2.0 - use-composed-ref: 1.4.0(@types/react@19.2.0)(react@19.2.0) - use-latest: 1.3.0(@types/react@19.2.0)(react@19.2.0) + react: 18.3.1 + use-composed-ref: 1.4.0(@types/react@18.3.23)(react@18.3.1) + use-latest: 1.3.0(@types/react@18.3.23)(react@18.3.1) transitivePeerDependencies: - '@types/react' @@ -18856,8 +18641,6 @@ snapshots: dependencies: loose-envify: 1.4.0 - react@19.2.0: {} - readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -18953,10 +18736,10 @@ snapshots: dependencies: jsesc: 3.1.0 - rehackt@0.1.0(@types/react@19.2.0)(react@19.2.0): + rehackt@0.1.0(@types/react@18.3.23)(react@18.3.1): optionalDependencies: - '@types/react': 19.2.0 - react: 19.2.0 + '@types/react': 18.3.23 + react: 18.3.1 rehype-raw@6.1.1: dependencies: @@ -19170,8 +18953,6 @@ snapshots: dependencies: loose-envify: 1.4.0 - scheduler@0.27.0: {} - schema-dts@1.1.5: {} schema-utils@3.3.0: @@ -19545,11 +19326,11 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - swr@2.3.6(react@19.2.0): + swr@2.3.6(react@18.3.1): dependencies: dequal: 2.0.3 - react: 19.2.0 - use-sync-external-store: 1.6.0(react@19.2.0) + react: 18.3.1 + use-sync-external-store: 1.6.0(react@18.3.1) symbol-observable@4.0.0: {} @@ -19898,6 +19679,12 @@ snapshots: unpipe@1.0.0: {} + update-browserslist-db@1.1.3(browserslist@4.25.2): + dependencies: + browserslist: 4.25.2 + escalade: 3.2.0 + picocolors: 1.1.1 + update-browserslist-db@1.1.3(browserslist@4.26.3): dependencies: browserslist: 4.26.3 @@ -19934,43 +19721,43 @@ snapshots: optionalDependencies: file-loader: 6.2.0(webpack@5.102.0) - use-callback-ref@1.3.3(@types/react@19.2.0)(react@19.2.0): + use-callback-ref@1.3.3(@types/react@18.3.23)(react@18.3.1): dependencies: - react: 19.2.0 + react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - use-composed-ref@1.4.0(@types/react@19.2.0)(react@19.2.0): + use-composed-ref@1.4.0(@types/react@18.3.23)(react@18.3.1): dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - use-isomorphic-layout-effect@1.2.1(@types/react@19.2.0)(react@19.2.0): + use-isomorphic-layout-effect@1.2.1(@types/react@18.3.23)(react@18.3.1): dependencies: - react: 19.2.0 + react: 18.3.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - use-latest@1.3.0(@types/react@19.2.0)(react@19.2.0): + use-latest@1.3.0(@types/react@18.3.23)(react@18.3.1): dependencies: - react: 19.2.0 - use-isomorphic-layout-effect: 1.2.1(@types/react@19.2.0)(react@19.2.0) + react: 18.3.1 + use-isomorphic-layout-effect: 1.2.1(@types/react@18.3.23)(react@18.3.1) optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - use-sidecar@1.1.3(@types/react@19.2.0)(react@19.2.0): + use-sidecar@1.1.3(@types/react@18.3.23)(react@18.3.1): dependencies: detect-node-es: 1.1.0 - react: 19.2.0 + react: 18.3.1 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.0 + '@types/react': 18.3.23 - use-sync-external-store@1.6.0(react@19.2.0): + use-sync-external-store@1.6.0(react@18.3.1): dependencies: - react: 19.2.0 + react: 18.3.1 util-deprecate@1.0.2: {} diff --git a/smoketests/tests/quickstart.py b/smoketests/tests/quickstart.py index 9bed9fcd476..211a099df3b 100644 --- a/smoketests/tests/quickstart.py +++ b/smoketests/tests/quickstart.py @@ -32,7 +32,7 @@ def _parse_quickstart(doc_path: Path, language: str, module_name: str) -> str: found = False filtered_blocks = [] for block in blocks: - # The doc first create an empy class Module, so we need to fixup the closing + # The doc first create an empty class Module, so we need to fixup the closing if "partial class Module" in block: block = block.replace("}", "") end = "\n}" @@ -194,8 +194,8 @@ def _test_quickstart(self): class Rust(BaseQuickstart): lang = "rust" - server_doc = STDB_DIR / "docs/docs/06-Server Module Languages/02-rust-quickstart.md" - client_doc = STDB_DIR / "docs/docs/07-Client SDK Languages/04-rust-quickstart.md" + server_doc = STDB_DIR / "docs/docs/02-quickstarts/03-rust.md" + client_doc = STDB_DIR / "docs/docs/02-quickstarts/03-rust.md" server_file = "src/lib.rs" client_file = "src/main.rs" module_bindings = "src/module_bindings" @@ -243,8 +243,8 @@ def test_quickstart(self): class CSharp(BaseQuickstart): lang = "csharp" - server_doc = STDB_DIR / "docs/docs/06-Server Module Languages/04-csharp-quickstart.md" - client_doc = STDB_DIR / "docs/docs/07-Client SDK Languages/02-csharp-quickstart.md" + server_doc = STDB_DIR / "docs/docs/02-quickstarts/02-c-sharp.md" + client_doc = STDB_DIR / "docs/docs/02-quickstarts/02-c-sharp.md" server_file = "Lib.cs" client_file = "Program.cs" module_bindings = "module_bindings"