From ec5803364877441fb21e7a9d69c8a130cb8d88e2 Mon Sep 17 00:00:00 2001 From: Nathan Flurry Date: Thu, 26 Jun 2025 00:26:24 +0000 Subject: [PATCH] feat(core): add inline client driver to ActorContext & ActionContext --- CLAUDE.md | 3 + .../driver-test-suite/inline-client.ts | 57 ++++++++ .../fixtures/driver-test-suite/registry.ts | 3 + packages/core/src/actor/action.ts | 11 +- packages/core/src/actor/context.ts | 11 +- packages/core/src/actor/instance.ts | 11 +- packages/core/src/driver-test-suite/mod.ts | 3 + .../tests/actor-inline-client.ts | 133 ++++++++++++++++++ .../src/topologies/coordinate/actor-peer.ts | 8 ++ .../src/topologies/coordinate/conn/mod.ts | 6 + .../src/topologies/coordinate/router/sse.ts | 4 + .../topologies/coordinate/router/websocket.ts | 4 + .../src/topologies/coordinate/topology.ts | 11 +- .../core/src/topologies/partition/topology.ts | 25 +++- .../src/topologies/standalone/topology.ts | 11 +- vitest.base.ts | 5 +- 16 files changed, 296 insertions(+), 10 deletions(-) create mode 100644 packages/core/fixtures/driver-test-suite/inline-client.ts create mode 100644 packages/core/src/driver-test-suite/tests/actor-inline-client.ts diff --git a/CLAUDE.md b/CLAUDE.md index a2da8668b..5f1f822cc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -196,3 +196,6 @@ Always include a README.md. The `README.md` should always follow this structure: Apache 2.0 ``` +## Test Notes + +- Using setTimeout in tests & test actors will not work unless you call `await waitFor(driverTestConfig, )` \ No newline at end of file diff --git a/packages/core/fixtures/driver-test-suite/inline-client.ts b/packages/core/fixtures/driver-test-suite/inline-client.ts new file mode 100644 index 000000000..b3edefbcc --- /dev/null +++ b/packages/core/fixtures/driver-test-suite/inline-client.ts @@ -0,0 +1,57 @@ +import { actor } from "@rivetkit/core"; +import type { Registry } from "./registry"; + +export const inlineClientActor = actor({ + onAuth: () => {}, + state: { messages: [] as string[] }, + actions: { + // Action that uses client to call another actor (stateless) + callCounterIncrement: async (c, amount: number) => { + const client = c.client(); + const result = await client.counter.getOrCreate(["inline-test"]).increment(amount); + c.state.messages.push(`Called counter.increment(${amount}), result: ${result}`); + return result; + }, + + // Action that uses client to get counter state (stateless) + getCounterState: async (c) => { + const client = c.client(); + const count = await client.counter.getOrCreate(["inline-test"]).getCount(); + c.state.messages.push(`Got counter state: ${count}`); + return count; + }, + + // Action that uses client with .connect() for stateful communication + connectToCounterAndIncrement: async (c, amount: number) => { + const client = c.client(); + const handle = client.counter.getOrCreate(["inline-test-stateful"]); + const connection = handle.connect(); + + // Set up event listener + const events: number[] = []; + connection.on("newCount", (count: number) => { + events.push(count); + }); + + // Perform increments + const result1 = await connection.increment(amount); + const result2 = await connection.increment(amount * 2); + + await connection.dispose(); + + c.state.messages.push(`Connected to counter, incremented by ${amount} and ${amount * 2}, results: ${result1}, ${result2}, events: ${JSON.stringify(events)}`); + + return { result1, result2, events }; + }, + + // Get all messages from this actor's state + getMessages: (c) => { + return c.state.messages; + }, + + // Clear messages + clearMessages: (c) => { + c.state.messages = []; + }, + }, +}); diff --git a/packages/core/fixtures/driver-test-suite/registry.ts b/packages/core/fixtures/driver-test-suite/registry.ts index e9d135e8f..1bcbd33c6 100644 --- a/packages/core/fixtures/driver-test-suite/registry.ts +++ b/packages/core/fixtures/driver-test-suite/registry.ts @@ -24,6 +24,7 @@ import { connStateActor } from "./conn-state"; // Import actors from individual files import { counter } from "./counter"; import { customTimeoutActor, errorHandlingActor } from "./error-handling"; +import { inlineClientActor } from "./inline-client"; import { counterWithLifecycle } from "./lifecycle"; import { metadataActor } from "./metadata"; import { scheduled } from "./scheduled"; @@ -47,6 +48,8 @@ export const registry = setup({ // From error-handling.ts errorHandlingActor, customTimeoutActor, + // From inline-client.ts + inlineClientActor, // From action-inputs.ts inputActor, // From action-timeout.ts diff --git a/packages/core/src/actor/action.ts b/packages/core/src/actor/action.ts index c30c283b0..6c6f86f64 100644 --- a/packages/core/src/actor/action.ts +++ b/packages/core/src/actor/action.ts @@ -1,10 +1,12 @@ -import type { Logger } from "@/common/log"; import type { ActorKey } from "@/actor/mod"; +import type { Logger } from "@/common/log"; import type { Conn } from "./connection"; import type { ConnId } from "./connection"; import type { ActorContext } from "./context"; import type { SaveStateOptions } from "./instance"; import type { Schedule } from "./schedule"; +import { Registry } from "@/registry/mod"; +import { Client } from "@/client/client"; /** * Context for a remote procedure call. @@ -97,6 +99,13 @@ export class ActionContext { return this.#actorContext.conns; } + /** + * Returns the client for the given registry. + */ + client>(): Client { + return this.#actorContext.client(); + } + /** * @experimental */ diff --git a/packages/core/src/actor/context.ts b/packages/core/src/actor/context.ts index 9bd90c33c..1e1a51670 100644 --- a/packages/core/src/actor/context.ts +++ b/packages/core/src/actor/context.ts @@ -1,8 +1,10 @@ -import type { Logger } from "@/common/log"; import type { ActorKey } from "@/actor/mod"; +import type { Logger } from "@/common/log"; import type { Conn, ConnId } from "./connection"; import type { ActorInstance, SaveStateOptions } from "./instance"; import type { Schedule } from "./schedule"; +import { Client } from "@/client/client"; +import { Registry } from "@/registry/mod"; /** * ActorContext class that provides access to actor methods and state @@ -87,6 +89,13 @@ export class ActorContext { return this.#actor.conns; } + /** + * Returns the client for the given registry. + */ + client>(): Client { + return this.#actor.inlineClient as Client; + } + /** * Gets the database. * @experimental diff --git a/packages/core/src/actor/instance.ts b/packages/core/src/actor/instance.ts index 6c6c10f28..a0f4190de 100644 --- a/packages/core/src/actor/instance.ts +++ b/packages/core/src/actor/instance.ts @@ -1,8 +1,10 @@ +import type { ActorKey } from "@/actor/mod"; import type * as wsToClient from "@/actor/protocol/message/to-client"; import type * as wsToServer from "@/actor/protocol/message/to-server"; +import type { Client } from "@/client/client"; import type { Logger } from "@/common/log"; -import type { ActorKey } from "@/actor/mod"; import { isJsonSerializable, stringifyError } from "@/common/utils"; +import type { Registry } from "@/mod"; import invariant from "invariant"; import onChange from "on-change"; import type { ActionContext } from "./action"; @@ -136,6 +138,7 @@ export class ActorInstance { #config: ActorConfig; #connectionDrivers!: ConnDrivers; #actorDriver!: ActorDriver; + #inlineClient!: Client>; #actorId!: string; #name!: string; #key!: ActorKey; @@ -154,6 +157,10 @@ export class ActorInstance { return this.#actorId; } + get inlineClient(): Client> { + return this.#inlineClient; + } + /** * This constructor should never be used directly. * @@ -169,6 +176,7 @@ export class ActorInstance { async start( connectionDrivers: ConnDrivers, actorDriver: ActorDriver, + inlineClient: Client>, actorId: string, name: string, key: ActorKey, @@ -176,6 +184,7 @@ export class ActorInstance { ) { this.#connectionDrivers = connectionDrivers; this.#actorDriver = actorDriver; + this.#inlineClient = inlineClient; this.#actorId = actorId; this.#name = name; this.#key = key; diff --git a/packages/core/src/driver-test-suite/mod.ts b/packages/core/src/driver-test-suite/mod.ts index 3640f8ac7..93b68c0e0 100644 --- a/packages/core/src/driver-test-suite/mod.ts +++ b/packages/core/src/driver-test-suite/mod.ts @@ -20,6 +20,7 @@ import { runActorConnStateTests } from "./tests/actor-conn-state"; import { runActorDriverTests } from "./tests/actor-driver"; import { runActorErrorHandlingTests } from "./tests/actor-error-handling"; import { runActorHandleTests } from "./tests/actor-handle"; +import { runActorInlineClientTests } from "./tests/actor-inline-client"; import { runActorMetadataTests } from "./tests/actor-metadata"; import { runActorVarsTests } from "./tests/actor-vars"; import { runManagerDriverTests } from "./tests/manager-driver"; @@ -94,6 +95,8 @@ export function runDriverTests( runActorErrorHandlingTests(driverTestConfig); runActorAuthTests(driverTestConfig); + + runActorInlineClientTests(driverTestConfig); }); } } diff --git a/packages/core/src/driver-test-suite/tests/actor-inline-client.ts b/packages/core/src/driver-test-suite/tests/actor-inline-client.ts new file mode 100644 index 000000000..f3f0568ec --- /dev/null +++ b/packages/core/src/driver-test-suite/tests/actor-inline-client.ts @@ -0,0 +1,133 @@ +import { describe, expect, test } from "vitest"; +import type { DriverTestConfig } from "../mod"; +import { setupDriverTest } from "../utils"; + +export function runActorInlineClientTests(driverTestConfig: DriverTestConfig) { + describe("Actor Inline Client Tests", () => { + describe("Stateless Client Calls", () => { + test("should make stateless calls to other actors", async (c) => { + const { client } = await setupDriverTest(c, driverTestConfig); + + // Create the inline client actor + const inlineClientHandle = client.inlineClientActor.getOrCreate(["inline-client-test"]); + + // Test calling counter.increment via inline client + const result = await inlineClientHandle.callCounterIncrement(5); + expect(result).toBe(5); + + // Verify the counter state was actually updated + const counterState = await inlineClientHandle.getCounterState(); + expect(counterState).toBe(5); + + // Check that messages were logged + const messages = await inlineClientHandle.getMessages(); + expect(messages).toHaveLength(2); + expect(messages[0]).toContain("Called counter.increment(5), result: 5"); + expect(messages[1]).toContain("Got counter state: 5"); + }); + + test("should handle multiple stateless calls", async (c) => { + const { client } = await setupDriverTest(c, driverTestConfig); + + // Create the inline client actor + const inlineClientHandle = client.inlineClientActor.getOrCreate(["inline-client-multi"]); + + // Clear any existing messages + await inlineClientHandle.clearMessages(); + + // Make multiple calls + const result1 = await inlineClientHandle.callCounterIncrement(3); + const result2 = await inlineClientHandle.callCounterIncrement(7); + const finalState = await inlineClientHandle.getCounterState(); + + expect(result1).toBe(3); + expect(result2).toBe(10); // 3 + 7 + expect(finalState).toBe(10); + + // Check messages + const messages = await inlineClientHandle.getMessages(); + expect(messages).toHaveLength(3); + expect(messages[0]).toContain("Called counter.increment(3), result: 3"); + expect(messages[1]).toContain("Called counter.increment(7), result: 10"); + expect(messages[2]).toContain("Got counter state: 10"); + }); + }); + + describe("Stateful Client Calls", () => { + test("should connect to other actors and receive events", async (c) => { + const { client } = await setupDriverTest(c, driverTestConfig); + + // Create the inline client actor + const inlineClientHandle = client.inlineClientActor.getOrCreate(["inline-client-stateful"]); + + // Clear any existing messages + await inlineClientHandle.clearMessages(); + + // Test stateful connection with events + const result = await inlineClientHandle.connectToCounterAndIncrement(4); + + expect(result.result1).toBe(4); + expect(result.result2).toBe(12); // 4 + 8 + expect(result.events).toEqual([4, 12]); // Should have received both events + + // Check that message was logged + const messages = await inlineClientHandle.getMessages(); + expect(messages).toHaveLength(1); + expect(messages[0]).toContain("Connected to counter, incremented by 4 and 8"); + expect(messages[0]).toContain("results: 4, 12"); + expect(messages[0]).toContain("events: [4,12]"); + }); + + test("should handle stateful connection independently", async (c) => { + const { client } = await setupDriverTest(c, driverTestConfig); + + // Create the inline client actor + const inlineClientHandle = client.inlineClientActor.getOrCreate(["inline-client-independent"]); + + // Clear any existing messages + await inlineClientHandle.clearMessages(); + + // Test with different increment values + const result = await inlineClientHandle.connectToCounterAndIncrement(2); + + expect(result.result1).toBe(2); + expect(result.result2).toBe(6); // 2 + 4 + expect(result.events).toEqual([2, 6]); + + // Verify the state is independent from previous tests + const messages = await inlineClientHandle.getMessages(); + expect(messages).toHaveLength(1); + expect(messages[0]).toContain("Connected to counter, incremented by 2 and 4"); + }); + }); + + describe("Mixed Client Usage", () => { + test("should handle both stateless and stateful calls", async (c) => { + const { client } = await setupDriverTest(c, driverTestConfig); + + // Create the inline client actor + const inlineClientHandle = client.inlineClientActor.getOrCreate(["inline-client-mixed"]); + + // Clear any existing messages + await inlineClientHandle.clearMessages(); + + // Start with stateless calls + await inlineClientHandle.callCounterIncrement(1); + const statelessResult = await inlineClientHandle.getCounterState(); + expect(statelessResult).toBe(1); + + // Then do stateful call + const statefulResult = await inlineClientHandle.connectToCounterAndIncrement(3); + expect(statefulResult.result1).toBe(3); + expect(statefulResult.result2).toBe(9); // 3 + 6 + + // Check all messages were logged + const messages = await inlineClientHandle.getMessages(); + expect(messages).toHaveLength(3); + expect(messages[0]).toContain("Called counter.increment(1), result: 1"); + expect(messages[1]).toContain("Got counter state: 1"); + expect(messages[2]).toContain("Connected to counter, incremented by 3 and 6"); + }); + }); + }); +} \ No newline at end of file diff --git a/packages/core/src/topologies/coordinate/actor-peer.ts b/packages/core/src/topologies/coordinate/actor-peer.ts index 79f8de012..bb64e6c3a 100644 --- a/packages/core/src/topologies/coordinate/actor-peer.ts +++ b/packages/core/src/topologies/coordinate/actor-peer.ts @@ -1,6 +1,8 @@ import type { ActorDriver } from "@/actor/driver"; import type { AnyActorInstance } from "@/actor/instance"; import type { ActorKey } from "@/actor/mod"; +import type { Client } from "@/client/client"; +import type { Registry } from "@/mod"; import type { RegistryConfig } from "@/registry/config"; import type { RunConfig } from "@/registry/run-config"; import type { GlobalState } from "@/topologies/coordinate/topology"; @@ -16,6 +18,7 @@ export class ActorPeer { #runConfig: RunConfig; #coordinateDriver: CoordinateDriver; #actorDriver: ActorDriver; + #inlineClient: Client>; #globalState: GlobalState; #actorId: string; #actorName?: string; @@ -47,6 +50,7 @@ export class ActorPeer { runConfig: RunConfig, CoordinateDriver: CoordinateDriver, actorDriver: ActorDriver, + inlineClient: Client>, globalState: GlobalState, actorId: string, ) { @@ -54,6 +58,7 @@ export class ActorPeer { this.#runConfig = runConfig; this.#coordinateDriver = CoordinateDriver; this.#actorDriver = actorDriver; + this.#inlineClient = inlineClient; this.#globalState = globalState; this.#actorId = actorId; } @@ -63,6 +68,7 @@ export class ActorPeer { registryConfig: RegistryConfig, runConfig: RunConfig, actorDriver: ActorDriver, + inlineClient: Client>, CoordinateDriver: CoordinateDriver, globalState: GlobalState, actorId: string, @@ -77,6 +83,7 @@ export class ActorPeer { runConfig, CoordinateDriver, actorDriver, + inlineClient, globalState, actorId, ); @@ -226,6 +233,7 @@ export class ActorPeer { ), }, this.#actorDriver, + this.#inlineClient, this.#actorId, this.#actorName, this.#actorKey, diff --git a/packages/core/src/topologies/coordinate/conn/mod.ts b/packages/core/src/topologies/coordinate/conn/mod.ts index e2548c497..8a67f0d31 100644 --- a/packages/core/src/topologies/coordinate/conn/mod.ts +++ b/packages/core/src/topologies/coordinate/conn/mod.ts @@ -9,6 +9,8 @@ import { ActorPeer } from "../actor-peer"; import type { CoordinateDriver } from "../driver"; import { logger } from "../log"; import { publishMessageToLeader } from "../node/message"; +import { Client } from "@/client/client"; +import { Registry } from "@/mod"; export interface RelayConnDriver { sendMessage(message: messageToClient.ToClient): void; @@ -23,6 +25,7 @@ export class RelayConn { #runConfig: RunConfig; #coordinateDriver: CoordinateDriver; #actorDriver: ActorDriver; + #inlineClient: Client>; #globalState: GlobalState; #driver: RelayConnDriver; #actorId: string; @@ -52,6 +55,7 @@ export class RelayConn { registryConfig: RegistryConfig, runConfig: RunConfig, actorDriver: ActorDriver, + inlineClient: Client>, CoordinateDriver: CoordinateDriver, globalState: GlobalState, driver: RelayConnDriver, @@ -63,6 +67,7 @@ export class RelayConn { this.#runConfig = runConfig; this.#coordinateDriver = CoordinateDriver; this.#actorDriver = actorDriver; + this.#inlineClient = inlineClient; this.#driver = driver; this.#globalState = globalState; this.#actorId = actorId; @@ -89,6 +94,7 @@ export class RelayConn { this.#registryConfig, this.#runConfig, this.#actorDriver, + this.#inlineClient, this.#coordinateDriver, this.#globalState, this.#actorId, diff --git a/packages/core/src/topologies/coordinate/router/sse.ts b/packages/core/src/topologies/coordinate/router/sse.ts index dd035ddce..b09ce61db 100644 --- a/packages/core/src/topologies/coordinate/router/sse.ts +++ b/packages/core/src/topologies/coordinate/router/sse.ts @@ -10,11 +10,14 @@ import type { GlobalState } from "@/topologies/coordinate/topology"; import { RelayConn } from "../conn/mod"; import type { CoordinateDriver } from "../driver"; import { logger } from "../log"; +import { Registry } from "@/registry/mod"; +import { Client } from "@/client/client"; export async function serveSse( registryConfig: RegistryConfig, runConfig: RunConfig, actorDriver: ActorDriver, + inlineClient: Client>, CoordinateDriver: CoordinateDriver, globalState: GlobalState, actorId: string, @@ -27,6 +30,7 @@ export async function serveSse( registryConfig, runConfig, actorDriver, + inlineClient, CoordinateDriver, globalState, { diff --git a/packages/core/src/topologies/coordinate/router/websocket.ts b/packages/core/src/topologies/coordinate/router/websocket.ts index e5fb3e2ca..ebd028805 100644 --- a/packages/core/src/topologies/coordinate/router/websocket.ts +++ b/packages/core/src/topologies/coordinate/router/websocket.ts @@ -14,11 +14,14 @@ import { RelayConn } from "../conn/mod"; import type { CoordinateDriver } from "../driver"; import { logger } from "../log"; import { publishMessageToLeader } from "../node/message"; +import { Registry } from "@/registry/mod"; +import { Client } from "@/client/client"; export async function serveWebSocket( registryConfig: RegistryConfig, runConfig: RunConfig, actorDriver: ActorDriver, + inlineClient: Client>, CoordinateDriver: CoordinateDriver, globalState: GlobalState, actorId: string, @@ -31,6 +34,7 @@ export async function serveWebSocket( registryConfig, runConfig, actorDriver, + inlineClient, CoordinateDriver, globalState, { diff --git a/packages/core/src/topologies/coordinate/topology.ts b/packages/core/src/topologies/coordinate/topology.ts index 7947d7182..10d72a380 100644 --- a/packages/core/src/topologies/coordinate/topology.ts +++ b/packages/core/src/topologies/coordinate/topology.ts @@ -11,10 +11,15 @@ import type { ConnectionHandlers, ConnsMessageOpts, } from "@/actor/router-endpoints"; -import type { ClientDriver } from "@/client/client"; +import { + type Client, + type ClientDriver, + createClientWithDriver, +} from "@/client/client"; import { createInlineClientDriver } from "@/inline-client-driver/mod"; import { createManagerRouter } from "@/manager/router"; import type { RegistryConfig } from "@/registry/config"; +import type { Registry } from "@/registry/mod"; import type { RunConfig } from "@/registry/run-config"; import { Hono } from "hono"; import invariant from "invariant"; @@ -37,6 +42,7 @@ export interface GlobalState { export class CoordinateTopology { public readonly clientDriver: ClientDriver; + inlineClient: Client>; public readonly router: Hono; constructor(registryConfig: RegistryConfig, runConfig: RunConfig) { @@ -73,6 +79,7 @@ export class CoordinateTopology { registryConfig, runConfig, actorDriver, + this.inlineClient, CoordinateDriver, globalState, opts.actorId, @@ -84,6 +91,7 @@ export class CoordinateTopology { registryConfig, runConfig, actorDriver, + this.inlineClient, CoordinateDriver, globalState, opts.actorId, @@ -124,6 +132,7 @@ export class CoordinateTopology { const managerDriver = runConfig.driver.manager; invariant(managerDriver, "missing manager driver"); this.clientDriver = createInlineClientDriver(managerDriver, routingHandler); + this.inlineClient = createClientWithDriver(this.clientDriver); // Build manager router const { router: managerRouter } = createManagerRouter( diff --git a/packages/core/src/topologies/partition/topology.ts b/packages/core/src/topologies/partition/topology.ts index 79ed3c7d0..e85b00b2d 100644 --- a/packages/core/src/topologies/partition/topology.ts +++ b/packages/core/src/topologies/partition/topology.ts @@ -7,6 +7,7 @@ import { import type { ConnDriver } from "@/actor/driver"; import * as errors from "@/actor/errors"; import type { AnyActorInstance } from "@/actor/instance"; +import type { ActorKey } from "@/actor/mod"; import type { ActionOpts, ActionOutput, @@ -16,11 +17,15 @@ import type { ConnectWebSocketOutput, ConnsMessageOpts, } from "@/actor/router-endpoints"; -import type { ClientDriver } from "@/client/client"; -import type { ActorKey } from "@/actor/mod"; +import { + type Client, + type ClientDriver, + createClientWithDriver, +} from "@/client/client"; import { createInlineClientDriver } from "@/inline-client-driver/mod"; import { createManagerRouter } from "@/manager/router"; import type { RegistryConfig } from "@/registry/config"; +import type { Registry } from "@/registry/mod"; import type { RunConfig } from "@/registry/run-config"; import { createActorRouter } from "@/topologies/partition/actor-router"; import type { Hono } from "hono"; @@ -50,6 +55,7 @@ export type OpenWebSocketHandler = ( export class PartitionTopologyManager { clientDriver: ClientDriver; + inlineClient: Client>; router: Hono; constructor(registryConfig: RegistryConfig, runConfig: RunConfig) { @@ -62,6 +68,7 @@ export class PartitionTopologyManager { const managerDriver = runConfig.driver.manager; invariant(managerDriver, "missing manager driver"); this.clientDriver = createInlineClientDriver(managerDriver, routingHandler); + this.inlineClient = createClientWithDriver(this.clientDriver); const { router } = createManagerRouter( registryConfig, @@ -101,6 +108,8 @@ export class PartitionTopologyManager { /** Manages the actor in the topology. */ export class PartitionTopologyActor { + clientDriver: ClientDriver; + inlineClient: Client>; router: Hono; #registryConfig: RegistryConfig; @@ -122,6 +131,17 @@ export class PartitionTopologyActor { this.#registryConfig = registryConfig; this.#runConfig = runConfig; + const routingHandler = runConfig.driver.manager.connRoutingHandler; + invariant( + routingHandler, + "partition run config must provide custom routing handler", + ); + + const managerDriver = runConfig.driver.manager; + invariant(managerDriver, "missing manager driver"); + this.clientDriver = createInlineClientDriver(managerDriver, routingHandler); + this.inlineClient = createClientWithDriver(this.clientDriver); + const genericConnGlobalState = new GenericConnGlobalState(); this.#connDrivers = createGenericConnDrivers(genericConnGlobalState); @@ -331,6 +351,7 @@ export class PartitionTopologyActor { await this.#actor.start( this.#connDrivers, actorDriver, + this.inlineClient, id, name, key, diff --git a/packages/core/src/topologies/standalone/topology.ts b/packages/core/src/topologies/standalone/topology.ts index 2ce7f33a9..f5eaf634e 100644 --- a/packages/core/src/topologies/standalone/topology.ts +++ b/packages/core/src/topologies/standalone/topology.ts @@ -17,10 +17,14 @@ import type { ConnectionHandlers, ConnsMessageOpts, } from "@/actor/router-endpoints"; -import type { ClientDriver } from "@/client/client"; +import { + type Client, + type ClientDriver, + createClientWithDriver, +} from "@/client/client"; import { createInlineClientDriver } from "@/inline-client-driver/mod"; import { createManagerRouter } from "@/manager/router"; -import type { RunConfig } from "@/mod"; +import type { Registry, RunConfig } from "@/mod"; import type { RegistryConfig } from "@/registry/config"; import { Hono } from "hono"; import invariant from "invariant"; @@ -52,6 +56,7 @@ class ActorHandler { */ export class StandaloneTopology { clientDriver: ClientDriver; + inlineClient: Client>; router: Hono; #registryConfig: RegistryConfig; @@ -71,6 +76,7 @@ export class StandaloneTopology { const managerDriver = this.#runConfig.driver.manager; invariant(managerDriver, "missing manager driver"); this.clientDriver = createInlineClientDriver(managerDriver, routingHandler); + this.inlineClient = createClientWithDriver(this.clientDriver); // Build manager router const { router: managerRouter } = createManagerRouter( @@ -153,6 +159,7 @@ export class StandaloneTopology { await handler.actor.start( connDrivers, this.#runConfig.driver.actor, + this.inlineClient, actorId, actorMetadata.name, actorMetadata.key, diff --git a/vitest.base.ts b/vitest.base.ts index b45ace23d..21f1ec176 100644 --- a/vitest.base.ts +++ b/vitest.base.ts @@ -2,6 +2,7 @@ import { type ViteUserConfig } from "vitest/config"; export default { test: { + testTimeout: 500, // Enable parallelism sequence: { // TODO: This breaks fake timers, unsure how to make tests run in parallel within the same file @@ -10,7 +11,7 @@ export default { env: { // Enable logging _LOG_LEVEL: "DEBUG", - _RIVETKIT_ERROR_STACK: "1" - } + _RIVETKIT_ERROR_STACK: "1", + }, }, } satisfies ViteUserConfig;