Skip to content

Commit af0bb93

Browse files
committed
chore(rivetkit): add WebSocketContext and RequestContext
1 parent ddf6de8 commit af0bb93

File tree

8 files changed

+391
-18
lines changed

8 files changed

+391
-18
lines changed

rivetkit-typescript/packages/rivetkit/fixtures/driver-test-suite/raw-http-request-properties.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { type ActorContext, actor } from "rivetkit";
1+
import { actor, type RequestContext } from "rivetkit";
22

33
export const rawHttpRequestPropertiesActor = actor({
44
actions: {},
55
onRequest(
6-
ctx: ActorContext<any, any, any, any, any, any>,
6+
ctx: RequestContext<any, any, any, any, any, any>,
77
request: Request,
88
) {
99
// Extract all relevant Request properties

rivetkit-typescript/packages/rivetkit/fixtures/driver-test-suite/raw-http.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Hono } from "hono";
2-
import { type ActorContext, actor } from "rivetkit";
2+
import { actor, type RequestContext } from "rivetkit";
33

44
export const rawHttpActor = actor({
55
state: {
66
requestCount: 0,
77
},
88
onRequest(
9-
ctx: ActorContext<any, any, any, any, any, any>,
9+
ctx: RequestContext<any, any, any, any, any, any>,
1010
request: Request,
1111
) {
1212
const url = new URL(request.url);
@@ -111,7 +111,7 @@ export const rawHttpHonoActor = actor({
111111
return { router };
112112
},
113113
onRequest(
114-
ctx: ActorContext<any, any, any, any, any, any>,
114+
ctx: RequestContext<any, any, any, any, any, any>,
115115
request: Request,
116116
) {
117117
// Use the Hono router from vars

rivetkit-typescript/packages/rivetkit/src/actor/config.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type { UniversalWebSocket } from "@/common/websocket-interface";
33
import type { Conn } from "./conn/mod";
44
import type { ActionContext } from "./contexts/action";
55
import type { ActorContext } from "./contexts/actor";
6+
import type { RequestContext } from "./contexts/request";
7+
import type { WebSocketContext } from "./contexts/websocket";
68
import type { AnyDatabaseProvider } from "./database";
79

810
export type InitContext = ActorContext<
@@ -407,11 +409,13 @@ interface BaseActorConfig<
407409
* This handler receives raw HTTP requests made to `/actors/{actorName}/http/*` endpoints.
408410
* Use this hook to handle custom HTTP patterns, REST APIs, or other HTTP-based protocols.
409411
*
412+
* @param c The request context with access to the connection
410413
* @param request The raw HTTP request object
414+
* @param opts Additional options
411415
* @returns A Response object to send back, or void to continue with default routing
412416
*/
413417
onRequest?: (
414-
c: ActorContext<
418+
c: RequestContext<
415419
TState,
416420
TConnParams,
417421
TConnState,
@@ -420,7 +424,6 @@ interface BaseActorConfig<
420424
TDatabase
421425
>,
422426
request: Request,
423-
opts: {},
424427
) => Response | Promise<Response>;
425428

426429
/**
@@ -429,11 +432,12 @@ interface BaseActorConfig<
429432
* This handler receives WebSocket connections made to `/actors/{actorName}/websocket/*` endpoints.
430433
* Use this hook to handle custom WebSocket protocols, binary streams, or other WebSocket-based communication.
431434
*
435+
* @param c The WebSocket context with access to the connection
432436
* @param websocket The raw WebSocket connection
433-
* @param request The original HTTP upgrade request
437+
* @param opts Additional options including the original HTTP upgrade request
434438
*/
435439
onWebSocket?: (
436-
c: ActorContext<
440+
c: WebSocketContext<
437441
TState,
438442
TConnParams,
439443
TConnState,
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
import type { ActorKey } from "@/actor/mod";
2+
import type { Client } from "@/client/client";
3+
import type { Logger } from "@/common/log";
4+
import type { Registry } from "@/registry/mod";
5+
import type { Conn, ConnId } from "../conn/mod";
6+
import type { AnyDatabaseProvider, InferDatabaseClient } from "../database";
7+
import type { SaveStateOptions } from "../instance/state-manager";
8+
import type { Schedule } from "../schedule";
9+
import type { ActorContext } from "./actor";
10+
11+
/**
12+
* Context for raw HTTP request handlers (onRequest).
13+
*
14+
* @typeParam TState - The actor state type
15+
* @typeParam TConnParams - The connection parameters type
16+
* @typeParam TConnState - The connection state type
17+
* @typeParam TVars - The actor variables type
18+
* @typeParam TInput - The actor input type
19+
* @typeParam TDatabase - The database provider type
20+
*/
21+
export class RequestContext<
22+
TState,
23+
TConnParams,
24+
TConnState,
25+
TVars,
26+
TInput,
27+
TDatabase extends AnyDatabaseProvider,
28+
> {
29+
#actorContext: ActorContext<
30+
TState,
31+
TConnParams,
32+
TConnState,
33+
TVars,
34+
TInput,
35+
TDatabase
36+
>;
37+
38+
/**
39+
* Should not be called directly.
40+
*
41+
* @param actorContext - The actor context
42+
* @param conn - The connection associated with the request
43+
*/
44+
constructor(
45+
actorContext: ActorContext<
46+
TState,
47+
TConnParams,
48+
TConnState,
49+
TVars,
50+
TInput,
51+
TDatabase
52+
>,
53+
public readonly conn: Conn<
54+
TState,
55+
TConnParams,
56+
TConnState,
57+
TVars,
58+
TInput,
59+
TDatabase
60+
>,
61+
) {
62+
this.#actorContext = actorContext;
63+
}
64+
65+
/**
66+
* Get the actor state
67+
*/
68+
get state(): TState {
69+
return this.#actorContext.state;
70+
}
71+
72+
/**
73+
* Get the actor variables
74+
*/
75+
get vars(): TVars {
76+
return this.#actorContext.vars;
77+
}
78+
79+
/**
80+
* Broadcasts an event to all connected clients.
81+
*/
82+
broadcast(name: string, ...args: any[]): void {
83+
this.#actorContext.broadcast(name, ...args);
84+
}
85+
86+
/**
87+
* Gets the logger instance.
88+
*/
89+
get log(): Logger {
90+
return this.#actorContext.log;
91+
}
92+
93+
/**
94+
* Gets actor ID.
95+
*/
96+
get actorId(): string {
97+
return this.#actorContext.actorId;
98+
}
99+
100+
/**
101+
* Gets the actor name.
102+
*/
103+
get name(): string {
104+
return this.#actorContext.name;
105+
}
106+
107+
/**
108+
* Gets the actor key.
109+
*/
110+
get key(): ActorKey {
111+
return this.#actorContext.key;
112+
}
113+
114+
/**
115+
* Gets the region.
116+
*/
117+
get region(): string {
118+
return this.#actorContext.region;
119+
}
120+
121+
/**
122+
* Gets the scheduler.
123+
*/
124+
get schedule(): Schedule {
125+
return this.#actorContext.schedule;
126+
}
127+
128+
/**
129+
* Gets the map of connections.
130+
*/
131+
get conns(): Map<
132+
ConnId,
133+
Conn<TState, TConnParams, TConnState, TVars, TInput, TDatabase>
134+
> {
135+
return this.#actorContext.conns;
136+
}
137+
138+
/**
139+
* Returns the client for the given registry.
140+
*/
141+
client<R extends Registry<any>>(): Client<R> {
142+
return this.#actorContext.client<R>();
143+
}
144+
145+
/**
146+
* @experimental
147+
*/
148+
get db(): InferDatabaseClient<TDatabase> {
149+
return this.#actorContext.db;
150+
}
151+
152+
/**
153+
* Forces the state to get saved.
154+
*/
155+
async saveState(opts: SaveStateOptions): Promise<void> {
156+
return this.#actorContext.saveState(opts);
157+
}
158+
159+
/**
160+
* Prevents the actor from sleeping until promise is complete.
161+
*/
162+
waitUntil(promise: Promise<void>): void {
163+
this.#actorContext.waitUntil(promise);
164+
}
165+
166+
/**
167+
* AbortSignal that fires when the actor is stopping.
168+
*/
169+
get abortSignal(): AbortSignal {
170+
return this.#actorContext.abortSignal;
171+
}
172+
173+
/**
174+
* Forces the actor to sleep.
175+
*
176+
* Not supported on all drivers.
177+
*
178+
* @experimental
179+
*/
180+
sleep() {
181+
this.#actorContext.sleep();
182+
}
183+
}

0 commit comments

Comments
 (0)