rivetkit 2.0.23 → 2.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/schemas/actor-persist/v2.ts +3 -3
- package/dist/schemas/actor-persist/v3.ts +274 -0
- package/dist/schemas/client-protocol/v2.ts +432 -0
- package/dist/schemas/file-system-driver/v2.ts +136 -0
- package/dist/tsup/actor/errors.cjs +2 -4
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +7 -10
- package/dist/tsup/actor/errors.d.ts +7 -10
- package/dist/tsup/actor/errors.js +9 -11
- package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.cts → actor-router-consts-DzI2szci.d.cts} +5 -9
- package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.ts → actor-router-consts-DzI2szci.d.ts} +5 -9
- package/dist/tsup/{chunk-3JYSUFET.cjs → chunk-3543NCSN.cjs} +45 -57
- package/dist/tsup/chunk-3543NCSN.cjs.map +1 -0
- package/dist/tsup/chunk-4SHILYS5.cjs +5694 -0
- package/dist/tsup/chunk-4SHILYS5.cjs.map +1 -0
- package/dist/tsup/{chunk-NCUALX2Q.cjs → chunk-5BZO5XPS.cjs} +3 -3
- package/dist/tsup/{chunk-NCUALX2Q.cjs.map → chunk-5BZO5XPS.cjs.map} +1 -1
- package/dist/tsup/{chunk-5PKKNNNS.js → chunk-BAIGSF64.js} +189 -187
- package/dist/tsup/chunk-BAIGSF64.js.map +1 -0
- package/dist/tsup/{chunk-HNYF4T36.cjs → chunk-CHLZBSI2.cjs} +17 -17
- package/dist/tsup/chunk-CHLZBSI2.cjs.map +1 -0
- package/dist/tsup/chunk-D3SLADUD.cjs +512 -0
- package/dist/tsup/chunk-D3SLADUD.cjs.map +1 -0
- package/dist/tsup/{chunk-KSRXX3Z4.cjs → chunk-D6762AOA.cjs} +20 -25
- package/dist/tsup/chunk-D6762AOA.cjs.map +1 -0
- package/dist/tsup/{chunk-C56XVVV4.cjs → chunk-DLK5YCTN.cjs} +187 -185
- package/dist/tsup/chunk-DLK5YCTN.cjs.map +1 -0
- package/dist/tsup/{chunk-DLYZKFRY.js → chunk-DUJQWGYD.js} +3 -7
- package/dist/tsup/chunk-DUJQWGYD.js.map +1 -0
- package/dist/tsup/{chunk-5UJQWWO3.js → chunk-EIPANQMF.js} +2 -2
- package/dist/tsup/{chunk-54DVMQPT.cjs → chunk-ESMTDP7G.cjs} +6 -6
- package/dist/tsup/chunk-ESMTDP7G.cjs.map +1 -0
- package/dist/tsup/{chunk-XYK5PY3B.cjs → chunk-FVAKREFB.cjs} +1900 -1737
- package/dist/tsup/chunk-FVAKREFB.cjs.map +1 -0
- package/dist/tsup/{chunk-PHNIVSG5.js → chunk-I3XT7WOF.js} +44 -56
- package/dist/tsup/chunk-I3XT7WOF.js.map +1 -0
- package/dist/tsup/{chunk-3I6ZIJVJ.js → chunk-IMDS5T42.js} +3 -3
- package/dist/tsup/chunk-IMDS5T42.js.map +1 -0
- package/dist/tsup/{chunk-SN4KWTRA.cjs → chunk-J3HZJF2P.cjs} +10 -14
- package/dist/tsup/chunk-J3HZJF2P.cjs.map +1 -0
- package/dist/tsup/{chunk-NOZSCUPQ.js → chunk-MBBJUHSP.js} +1844 -1681
- package/dist/tsup/chunk-MBBJUHSP.js.map +1 -0
- package/dist/tsup/{chunk-RVVUS4X6.js → chunk-MO5CB6MD.js} +9 -9
- package/dist/tsup/chunk-MO5CB6MD.js.map +1 -0
- package/dist/tsup/chunk-OFOTPKAH.js +512 -0
- package/dist/tsup/chunk-OFOTPKAH.js.map +1 -0
- package/dist/tsup/{chunk-G64QUEDJ.js → chunk-W6RDS6NW.js} +23 -28
- package/dist/tsup/chunk-W6RDS6NW.js.map +1 -0
- package/dist/tsup/{chunk-XSDSNHSE.cjs → chunk-YC5DUHPM.cjs} +4 -8
- package/dist/tsup/chunk-YC5DUHPM.cjs.map +1 -0
- package/dist/tsup/{chunk-YAYNBR37.js → chunk-YC7YPM2T.js} +2 -6
- package/dist/tsup/chunk-YC7YPM2T.js.map +1 -0
- package/dist/tsup/{chunk-FTQ62XTN.js → chunk-ZSPU5R4C.js} +3322 -2251
- package/dist/tsup/chunk-ZSPU5R4C.js.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.d.cts +5 -7
- package/dist/tsup/client/mod.d.ts +5 -7
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{conn-B3Vhbgnd.d.ts → config-BRDYDraU.d.cts} +1119 -1047
- package/dist/tsup/{conn-DJWL3nGx.d.cts → config-Bo-blHpJ.d.ts} +1119 -1047
- package/dist/tsup/driver-helpers/mod.cjs +5 -13
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +11 -9
- package/dist/tsup/driver-helpers/mod.d.ts +11 -9
- package/dist/tsup/driver-helpers/mod.js +14 -22
- package/dist/tsup/driver-test-suite/mod.cjs +474 -303
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +6 -9
- package/dist/tsup/driver-test-suite/mod.d.ts +6 -9
- package/dist/tsup/driver-test-suite/mod.js +1085 -914
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.d.cts +5 -7
- package/dist/tsup/inspector/mod.d.ts +5 -7
- package/dist/tsup/inspector/mod.js +5 -5
- package/dist/tsup/mod.cjs +10 -16
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +23 -25
- package/dist/tsup/mod.d.ts +23 -25
- package/dist/tsup/mod.js +17 -23
- package/dist/tsup/test/mod.cjs +11 -11
- package/dist/tsup/test/mod.d.cts +4 -6
- package/dist/tsup/test/mod.d.ts +4 -6
- package/dist/tsup/test/mod.js +10 -10
- package/dist/tsup/utils.cjs +3 -5
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.d.cts +1 -2
- package/dist/tsup/utils.d.ts +1 -2
- package/dist/tsup/utils.js +2 -4
- package/package.json +13 -6
- package/src/actor/config.ts +56 -44
- package/src/actor/conn/driver.ts +61 -0
- package/src/actor/conn/drivers/http.ts +17 -0
- package/src/actor/conn/drivers/raw-request.ts +24 -0
- package/src/actor/conn/drivers/raw-websocket.ts +65 -0
- package/src/actor/conn/drivers/websocket.ts +129 -0
- package/src/actor/conn/mod.ts +232 -0
- package/src/actor/conn/persisted.ts +81 -0
- package/src/actor/conn/state-manager.ts +196 -0
- package/src/actor/contexts/action.ts +23 -0
- package/src/actor/{context.ts → contexts/actor.ts} +19 -8
- package/src/actor/contexts/conn-init.ts +31 -0
- package/src/actor/contexts/conn.ts +48 -0
- package/src/actor/contexts/create-conn-state.ts +13 -0
- package/src/actor/contexts/on-before-connect.ts +13 -0
- package/src/actor/contexts/on-connect.ts +22 -0
- package/src/actor/contexts/request.ts +48 -0
- package/src/actor/contexts/websocket.ts +48 -0
- package/src/actor/definition.ts +3 -3
- package/src/actor/driver.ts +36 -5
- package/src/actor/errors.ts +19 -24
- package/src/actor/instance/connection-manager.ts +465 -0
- package/src/actor/instance/event-manager.ts +292 -0
- package/src/actor/instance/kv.ts +15 -0
- package/src/actor/instance/mod.ts +1107 -0
- package/src/actor/instance/persisted.ts +67 -0
- package/src/actor/instance/schedule-manager.ts +349 -0
- package/src/actor/instance/state-manager.ts +502 -0
- package/src/actor/mod.ts +13 -16
- package/src/actor/protocol/old.ts +131 -43
- package/src/actor/protocol/serde.ts +19 -4
- package/src/actor/router-endpoints.ts +61 -586
- package/src/actor/router-websocket-endpoints.ts +408 -0
- package/src/actor/router.ts +63 -197
- package/src/actor/schedule.ts +1 -1
- package/src/client/actor-conn.ts +183 -249
- package/src/client/actor-handle.ts +29 -6
- package/src/client/client.ts +0 -4
- package/src/client/config.ts +1 -4
- package/src/client/mod.ts +0 -1
- package/src/client/raw-utils.ts +3 -3
- package/src/client/utils.ts +85 -39
- package/src/common/actor-router-consts.ts +5 -12
- package/src/common/{inline-websocket-adapter2.ts → inline-websocket-adapter.ts} +26 -48
- package/src/common/log.ts +1 -1
- package/src/common/router.ts +28 -17
- package/src/common/utils.ts +2 -0
- package/src/driver-helpers/mod.ts +7 -10
- package/src/driver-helpers/utils.ts +18 -9
- package/src/driver-test-suite/mod.ts +26 -50
- package/src/driver-test-suite/test-inline-client-driver.ts +27 -51
- package/src/driver-test-suite/tests/actor-conn-hibernation.ts +150 -0
- package/src/driver-test-suite/tests/actor-conn-state.ts +1 -4
- package/src/driver-test-suite/tests/actor-conn.ts +5 -9
- package/src/driver-test-suite/tests/actor-destroy.ts +294 -0
- package/src/driver-test-suite/tests/actor-driver.ts +0 -7
- package/src/driver-test-suite/tests/actor-handle.ts +12 -12
- package/src/driver-test-suite/tests/actor-metadata.ts +1 -1
- package/src/driver-test-suite/tests/manager-driver.ts +1 -1
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +8 -8
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +6 -5
- package/src/driver-test-suite/tests/raw-http.ts +5 -5
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +7 -7
- package/src/driver-test-suite/tests/request-access.ts +4 -4
- package/src/driver-test-suite/utils.ts +6 -10
- package/src/drivers/engine/actor-driver.ts +614 -424
- package/src/drivers/engine/mod.ts +0 -1
- package/src/drivers/file-system/actor.ts +24 -12
- package/src/drivers/file-system/global-state.ts +427 -37
- package/src/drivers/file-system/manager.ts +71 -83
- package/src/drivers/file-system/mod.ts +3 -0
- package/src/drivers/file-system/utils.ts +18 -8
- package/src/engine-process/mod.ts +38 -38
- package/src/inspector/utils.ts +7 -5
- package/src/manager/driver.ts +11 -4
- package/src/manager/gateway.ts +4 -29
- package/src/manager/protocol/mod.ts +0 -2
- package/src/manager/protocol/query.ts +0 -4
- package/src/manager/router.ts +67 -64
- package/src/manager-api/actors.ts +13 -0
- package/src/mod.ts +1 -3
- package/src/registry/mod.ts +20 -20
- package/src/registry/serve.ts +9 -14
- package/src/remote-manager-driver/actor-websocket-client.ts +1 -16
- package/src/remote-manager-driver/api-endpoints.ts +13 -1
- package/src/remote-manager-driver/api-utils.ts +8 -0
- package/src/remote-manager-driver/metadata.ts +58 -0
- package/src/remote-manager-driver/mod.ts +47 -62
- package/src/remote-manager-driver/ws-proxy.ts +1 -1
- package/src/schemas/actor-persist/mod.ts +1 -1
- package/src/schemas/actor-persist/versioned.ts +56 -31
- package/src/schemas/client-protocol/mod.ts +1 -1
- package/src/schemas/client-protocol/versioned.ts +41 -21
- package/src/schemas/client-protocol-zod/mod.ts +103 -0
- package/src/schemas/file-system-driver/mod.ts +1 -1
- package/src/schemas/file-system-driver/versioned.ts +42 -19
- package/src/serde.ts +33 -11
- package/src/test/mod.ts +7 -3
- package/src/utils/node.ts +173 -0
- package/src/utils.ts +0 -4
- package/dist/tsup/chunk-3I6ZIJVJ.js.map +0 -1
- package/dist/tsup/chunk-3JYSUFET.cjs.map +0 -1
- package/dist/tsup/chunk-54DVMQPT.cjs.map +0 -1
- package/dist/tsup/chunk-5PKKNNNS.js.map +0 -1
- package/dist/tsup/chunk-C56XVVV4.cjs.map +0 -1
- package/dist/tsup/chunk-D6PCH7FR.cjs +0 -4623
- package/dist/tsup/chunk-D6PCH7FR.cjs.map +0 -1
- package/dist/tsup/chunk-DLYZKFRY.js.map +0 -1
- package/dist/tsup/chunk-FTQ62XTN.js.map +0 -1
- package/dist/tsup/chunk-G64QUEDJ.js.map +0 -1
- package/dist/tsup/chunk-HNYF4T36.cjs.map +0 -1
- package/dist/tsup/chunk-JMLTKMJ7.cjs +0 -1119
- package/dist/tsup/chunk-JMLTKMJ7.cjs.map +0 -1
- package/dist/tsup/chunk-KSRXX3Z4.cjs.map +0 -1
- package/dist/tsup/chunk-NOZSCUPQ.js.map +0 -1
- package/dist/tsup/chunk-PHNIVSG5.js.map +0 -1
- package/dist/tsup/chunk-RUTBXBRR.js +0 -1119
- package/dist/tsup/chunk-RUTBXBRR.js.map +0 -1
- package/dist/tsup/chunk-RVVUS4X6.js.map +0 -1
- package/dist/tsup/chunk-SN4KWTRA.cjs.map +0 -1
- package/dist/tsup/chunk-XSDSNHSE.cjs.map +0 -1
- package/dist/tsup/chunk-XYK5PY3B.cjs.map +0 -1
- package/dist/tsup/chunk-YAYNBR37.js.map +0 -1
- package/src/actor/action.ts +0 -178
- package/src/actor/conn-drivers.ts +0 -216
- package/src/actor/conn-socket.ts +0 -8
- package/src/actor/conn.ts +0 -272
- package/src/actor/instance.ts +0 -2336
- package/src/actor/persisted.ts +0 -49
- package/src/actor/unstable-react.ts +0 -110
- package/src/driver-test-suite/tests/actor-reconnect.ts +0 -170
- package/src/drivers/engine/kv.ts +0 -3
- package/src/manager/hono-websocket-adapter.ts +0 -393
- /package/dist/tsup/{chunk-5UJQWWO3.js.map → chunk-EIPANQMF.js.map} +0 -0
|
@@ -1,78 +1,40 @@
|
|
|
1
1
|
import * as cbor from "cbor-x";
|
|
2
2
|
import type { Context as HonoContext, HonoRequest } from "hono";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import invariant from "invariant";
|
|
6
|
-
import { ActionContext } from "@/actor/action";
|
|
7
|
-
import type { AnyConn } from "@/actor/conn";
|
|
8
|
-
import {
|
|
9
|
-
generateConnId,
|
|
10
|
-
generateConnRequestId,
|
|
11
|
-
generateConnToken,
|
|
12
|
-
} from "@/actor/conn";
|
|
13
|
-
import { ConnDriverKind } from "@/actor/conn-drivers";
|
|
3
|
+
import type { AnyConn } from "@/actor/conn/mod";
|
|
4
|
+
import { ActionContext } from "@/actor/contexts/action";
|
|
14
5
|
import * as errors from "@/actor/errors";
|
|
15
|
-
import {
|
|
16
|
-
import type { InputData } from "@/actor/protocol/serde";
|
|
6
|
+
import type { AnyActorInstance } from "@/actor/instance/mod";
|
|
17
7
|
import { type Encoding, EncodingSchema } from "@/actor/protocol/serde";
|
|
18
8
|
import {
|
|
19
9
|
HEADER_ACTOR_QUERY,
|
|
20
|
-
HEADER_CONN_ID,
|
|
21
10
|
HEADER_CONN_PARAMS,
|
|
22
|
-
HEADER_CONN_TOKEN,
|
|
23
11
|
HEADER_ENCODING,
|
|
12
|
+
WS_PROTOCOL_CONN_PARAMS,
|
|
13
|
+
WS_PROTOCOL_ENCODING,
|
|
24
14
|
} from "@/common/actor-router-consts";
|
|
25
|
-
import
|
|
26
|
-
import { deconstructError, stringifyError } from "@/common/utils";
|
|
27
|
-
import type { UniversalWebSocket } from "@/common/websocket-interface";
|
|
28
|
-
import { HonoWebSocketAdapter } from "@/manager/hono-websocket-adapter";
|
|
15
|
+
import { stringifyError } from "@/common/utils";
|
|
29
16
|
import type { RunnerConfig } from "@/registry/run-config";
|
|
30
17
|
import type * as protocol from "@/schemas/client-protocol/mod";
|
|
31
18
|
import {
|
|
32
19
|
HTTP_ACTION_REQUEST_VERSIONED,
|
|
33
20
|
HTTP_ACTION_RESPONSE_VERSIONED,
|
|
34
|
-
TO_SERVER_VERSIONED,
|
|
35
21
|
} from "@/schemas/client-protocol/versioned";
|
|
22
|
+
import {
|
|
23
|
+
type HttpActionRequest as HttpActionRequestJson,
|
|
24
|
+
HttpActionRequestSchema,
|
|
25
|
+
type HttpActionResponse as HttpActionResponseJson,
|
|
26
|
+
HttpActionResponseSchema,
|
|
27
|
+
} from "@/schemas/client-protocol-zod/mod";
|
|
36
28
|
import {
|
|
37
29
|
contentTypeForEncoding,
|
|
38
30
|
deserializeWithEncoding,
|
|
39
31
|
serializeWithEncoding,
|
|
40
32
|
} from "@/serde";
|
|
41
|
-
import {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
promiseWithResolvers,
|
|
45
|
-
} from "@/utils";
|
|
33
|
+
import { bufferToArrayBuffer } from "@/utils";
|
|
34
|
+
import { createHttpDriver } from "./conn/drivers/http";
|
|
35
|
+
import { createRawRequestDriver } from "./conn/drivers/raw-request";
|
|
46
36
|
import type { ActorDriver } from "./driver";
|
|
47
37
|
import { loggerWithoutContext } from "./log";
|
|
48
|
-
import { parseMessage } from "./protocol/old";
|
|
49
|
-
|
|
50
|
-
export const SSE_PING_INTERVAL = 1000;
|
|
51
|
-
|
|
52
|
-
export interface ConnectWebSocketOpts {
|
|
53
|
-
req?: HonoRequest;
|
|
54
|
-
encoding: Encoding;
|
|
55
|
-
actorId: string;
|
|
56
|
-
params: unknown;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface ConnectWebSocketOutput {
|
|
60
|
-
onOpen: (ws: WSContext) => void;
|
|
61
|
-
onMessage: (message: protocol.ToServer) => void;
|
|
62
|
-
onClose: () => void;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export interface ConnectSseOpts {
|
|
66
|
-
req?: HonoRequest;
|
|
67
|
-
encoding: Encoding;
|
|
68
|
-
params: unknown;
|
|
69
|
-
actorId: string;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface ConnectSseOutput {
|
|
73
|
-
onOpen: (stream: SSEStreamingApi) => void;
|
|
74
|
-
onClose: () => Promise<void>;
|
|
75
|
-
}
|
|
76
38
|
|
|
77
39
|
export interface ActionOpts {
|
|
78
40
|
req?: HonoRequest;
|
|
@@ -89,7 +51,6 @@ export interface ActionOutput {
|
|
|
89
51
|
export interface ConnsMessageOpts {
|
|
90
52
|
req?: HonoRequest;
|
|
91
53
|
connId: string;
|
|
92
|
-
connToken: string;
|
|
93
54
|
message: protocol.ToServer;
|
|
94
55
|
actorId: string;
|
|
95
56
|
}
|
|
@@ -99,362 +60,6 @@ export interface FetchOpts {
|
|
|
99
60
|
actorId: string;
|
|
100
61
|
}
|
|
101
62
|
|
|
102
|
-
export interface WebSocketOpts {
|
|
103
|
-
request: Request;
|
|
104
|
-
websocket: UniversalWebSocket;
|
|
105
|
-
actorId: string;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Creates a WebSocket connection handler
|
|
110
|
-
*/
|
|
111
|
-
export async function handleWebSocketConnect(
|
|
112
|
-
req: Request | undefined,
|
|
113
|
-
runConfig: RunnerConfig,
|
|
114
|
-
actorDriver: ActorDriver,
|
|
115
|
-
actorId: string,
|
|
116
|
-
encoding: Encoding,
|
|
117
|
-
parameters: unknown,
|
|
118
|
-
requestId: string,
|
|
119
|
-
requestIdBuf: ArrayBuffer | undefined,
|
|
120
|
-
connId: string | undefined,
|
|
121
|
-
connToken: string | undefined,
|
|
122
|
-
): Promise<UpgradeWebSocketArgs> {
|
|
123
|
-
const exposeInternalError = req
|
|
124
|
-
? getRequestExposeInternalError(req)
|
|
125
|
-
: false;
|
|
126
|
-
|
|
127
|
-
// Setup promise for the init handlers since all other behavior depends on this
|
|
128
|
-
const {
|
|
129
|
-
promise: handlersPromise,
|
|
130
|
-
resolve: handlersResolve,
|
|
131
|
-
reject: handlersReject,
|
|
132
|
-
} = promiseWithResolvers<{
|
|
133
|
-
conn: AnyConn;
|
|
134
|
-
actor: AnyActorInstance;
|
|
135
|
-
connId: string;
|
|
136
|
-
}>();
|
|
137
|
-
|
|
138
|
-
// Pre-load the actor to catch errors early
|
|
139
|
-
let actor: AnyActorInstance;
|
|
140
|
-
try {
|
|
141
|
-
actor = await actorDriver.loadActor(actorId);
|
|
142
|
-
} catch (error) {
|
|
143
|
-
// Return handler that immediately closes with error
|
|
144
|
-
return {
|
|
145
|
-
onOpen: (_evt: any, ws: WSContext) => {
|
|
146
|
-
const { code } = deconstructError(
|
|
147
|
-
error,
|
|
148
|
-
actor.rLog,
|
|
149
|
-
{
|
|
150
|
-
wsEvent: "open",
|
|
151
|
-
},
|
|
152
|
-
exposeInternalError,
|
|
153
|
-
);
|
|
154
|
-
ws.close(1011, code);
|
|
155
|
-
},
|
|
156
|
-
onMessage: (_evt: { data: any }, ws: WSContext) => {
|
|
157
|
-
ws.close(1011, "Actor not loaded");
|
|
158
|
-
},
|
|
159
|
-
onClose: (_event: any, _ws: WSContext) => {},
|
|
160
|
-
onError: (_error: unknown) => {},
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Promise used to wait for the websocket close in `disconnect`
|
|
165
|
-
const closePromise = promiseWithResolvers<void>();
|
|
166
|
-
|
|
167
|
-
// Track connection outside of scope for cleanup
|
|
168
|
-
let createdConn: AnyConn | undefined;
|
|
169
|
-
|
|
170
|
-
return {
|
|
171
|
-
onOpen: (_evt: any, ws: WSContext) => {
|
|
172
|
-
actor.rLog.debug("actor websocket open");
|
|
173
|
-
|
|
174
|
-
// Run async operations in background
|
|
175
|
-
(async () => {
|
|
176
|
-
try {
|
|
177
|
-
let conn: AnyConn;
|
|
178
|
-
|
|
179
|
-
// Create or reconnect connection
|
|
180
|
-
actor.rLog.debug({
|
|
181
|
-
msg: connId
|
|
182
|
-
? "websocket reconnection attempt"
|
|
183
|
-
: "new websocket connection",
|
|
184
|
-
connId,
|
|
185
|
-
actorId,
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// Check if this is a hibernatable websocket
|
|
189
|
-
const isHibernatable =
|
|
190
|
-
!!requestIdBuf &&
|
|
191
|
-
actor[PERSIST_SYMBOL].hibernatableWebSocket.findIndex(
|
|
192
|
-
(ws) =>
|
|
193
|
-
arrayBuffersEqual(ws.requestId, requestIdBuf),
|
|
194
|
-
) !== -1;
|
|
195
|
-
|
|
196
|
-
conn = await actor.createConn(
|
|
197
|
-
{
|
|
198
|
-
requestId: requestId,
|
|
199
|
-
requestIdBuf: requestIdBuf,
|
|
200
|
-
hibernatable: isHibernatable,
|
|
201
|
-
driverState: {
|
|
202
|
-
[ConnDriverKind.WEBSOCKET]: {
|
|
203
|
-
encoding,
|
|
204
|
-
websocket: ws,
|
|
205
|
-
closePromise,
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
parameters,
|
|
210
|
-
req,
|
|
211
|
-
connId,
|
|
212
|
-
connToken,
|
|
213
|
-
);
|
|
214
|
-
|
|
215
|
-
// Store connection so we can clean on close
|
|
216
|
-
createdConn = conn;
|
|
217
|
-
|
|
218
|
-
// Unblock other handlers
|
|
219
|
-
handlersResolve({ conn, actor, connId: conn.id });
|
|
220
|
-
} catch (error) {
|
|
221
|
-
handlersReject(error);
|
|
222
|
-
|
|
223
|
-
const { code } = deconstructError(
|
|
224
|
-
error,
|
|
225
|
-
actor.rLog,
|
|
226
|
-
{
|
|
227
|
-
wsEvent: "open",
|
|
228
|
-
},
|
|
229
|
-
exposeInternalError,
|
|
230
|
-
);
|
|
231
|
-
ws.close(1011, code);
|
|
232
|
-
}
|
|
233
|
-
})();
|
|
234
|
-
},
|
|
235
|
-
onMessage: (evt: { data: any }, ws: WSContext) => {
|
|
236
|
-
// Handle message asynchronously
|
|
237
|
-
handlersPromise
|
|
238
|
-
.then(({ conn, actor }) => {
|
|
239
|
-
actor.rLog.debug({ msg: "received message" });
|
|
240
|
-
|
|
241
|
-
const value = evt.data.valueOf() as InputData;
|
|
242
|
-
parseMessage(value, {
|
|
243
|
-
encoding: encoding,
|
|
244
|
-
maxIncomingMessageSize:
|
|
245
|
-
runConfig.maxIncomingMessageSize,
|
|
246
|
-
})
|
|
247
|
-
.then((message) => {
|
|
248
|
-
actor
|
|
249
|
-
.processMessage(message, conn)
|
|
250
|
-
.catch((error) => {
|
|
251
|
-
const { code } = deconstructError(
|
|
252
|
-
error,
|
|
253
|
-
actor.rLog,
|
|
254
|
-
{
|
|
255
|
-
wsEvent: "message",
|
|
256
|
-
},
|
|
257
|
-
exposeInternalError,
|
|
258
|
-
);
|
|
259
|
-
ws.close(1011, code);
|
|
260
|
-
});
|
|
261
|
-
})
|
|
262
|
-
.catch((error) => {
|
|
263
|
-
const { code } = deconstructError(
|
|
264
|
-
error,
|
|
265
|
-
actor.rLog,
|
|
266
|
-
{
|
|
267
|
-
wsEvent: "message",
|
|
268
|
-
},
|
|
269
|
-
exposeInternalError,
|
|
270
|
-
);
|
|
271
|
-
ws.close(1011, code);
|
|
272
|
-
});
|
|
273
|
-
})
|
|
274
|
-
.catch((error) => {
|
|
275
|
-
const { code } = deconstructError(
|
|
276
|
-
error,
|
|
277
|
-
actor.rLog,
|
|
278
|
-
{
|
|
279
|
-
wsEvent: "message",
|
|
280
|
-
},
|
|
281
|
-
exposeInternalError,
|
|
282
|
-
);
|
|
283
|
-
ws.close(1011, code);
|
|
284
|
-
});
|
|
285
|
-
},
|
|
286
|
-
onClose: (
|
|
287
|
-
event: {
|
|
288
|
-
wasClean: boolean;
|
|
289
|
-
code: number;
|
|
290
|
-
reason: string;
|
|
291
|
-
},
|
|
292
|
-
ws: WSContext,
|
|
293
|
-
) => {
|
|
294
|
-
handlersReject(`WebSocket closed (${event.code}): ${event.reason}`);
|
|
295
|
-
|
|
296
|
-
closePromise.resolve();
|
|
297
|
-
|
|
298
|
-
if (event.wasClean) {
|
|
299
|
-
actor.rLog.info({
|
|
300
|
-
msg: "websocket closed",
|
|
301
|
-
code: event.code,
|
|
302
|
-
reason: event.reason,
|
|
303
|
-
wasClean: event.wasClean,
|
|
304
|
-
});
|
|
305
|
-
} else {
|
|
306
|
-
actor.rLog.warn({
|
|
307
|
-
msg: "websocket closed",
|
|
308
|
-
code: event.code,
|
|
309
|
-
reason: event.reason,
|
|
310
|
-
wasClean: event.wasClean,
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// HACK: Close socket in order to fix bug with Cloudflare leaving WS in closing state
|
|
315
|
-
// https://github.com/cloudflare/workerd/issues/2569
|
|
316
|
-
ws.close(1000, "hack_force_close");
|
|
317
|
-
|
|
318
|
-
// Wait for actor.createConn to finish before removing the connection
|
|
319
|
-
handlersPromise.finally(() => {
|
|
320
|
-
if (createdConn) {
|
|
321
|
-
const wasClean = event.wasClean || event.code === 1000;
|
|
322
|
-
actor.__connDisconnected(createdConn, wasClean, requestId);
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
},
|
|
326
|
-
onError: (_error: unknown) => {
|
|
327
|
-
try {
|
|
328
|
-
// Actors don't need to know about this, since it's abstracted away
|
|
329
|
-
actor.rLog.warn({ msg: "websocket error" });
|
|
330
|
-
} catch (error) {
|
|
331
|
-
deconstructError(
|
|
332
|
-
error,
|
|
333
|
-
actor.rLog,
|
|
334
|
-
{ wsEvent: "error" },
|
|
335
|
-
exposeInternalError,
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
},
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Creates an SSE connection handler
|
|
344
|
-
*/
|
|
345
|
-
export async function handleSseConnect(
|
|
346
|
-
c: HonoContext,
|
|
347
|
-
_runConfig: RunnerConfig,
|
|
348
|
-
actorDriver: ActorDriver,
|
|
349
|
-
actorId: string,
|
|
350
|
-
) {
|
|
351
|
-
c.header("Content-Encoding", "Identity");
|
|
352
|
-
|
|
353
|
-
const encoding = getRequestEncoding(c.req);
|
|
354
|
-
const parameters = getRequestConnParams(c.req);
|
|
355
|
-
const requestId = generateConnRequestId();
|
|
356
|
-
|
|
357
|
-
// Check for reconnection parameters
|
|
358
|
-
const connId = c.req.header(HEADER_CONN_ID);
|
|
359
|
-
const connToken = c.req.header(HEADER_CONN_TOKEN);
|
|
360
|
-
|
|
361
|
-
// Return the main handler with all async work inside
|
|
362
|
-
return streamSSE(c, async (stream) => {
|
|
363
|
-
let actor: AnyActorInstance | undefined;
|
|
364
|
-
let conn: AnyConn | undefined;
|
|
365
|
-
|
|
366
|
-
try {
|
|
367
|
-
// Do all async work inside the handler
|
|
368
|
-
actor = await actorDriver.loadActor(actorId);
|
|
369
|
-
|
|
370
|
-
// Create or reconnect connection
|
|
371
|
-
actor.rLog.debug({
|
|
372
|
-
msg: connId ? "sse reconnection attempt" : "sse open",
|
|
373
|
-
connId,
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
conn = await actor.createConn(
|
|
377
|
-
{
|
|
378
|
-
requestId: requestId,
|
|
379
|
-
hibernatable: false,
|
|
380
|
-
driverState: {
|
|
381
|
-
[ConnDriverKind.SSE]: {
|
|
382
|
-
encoding,
|
|
383
|
-
stream: stream,
|
|
384
|
-
},
|
|
385
|
-
},
|
|
386
|
-
},
|
|
387
|
-
parameters,
|
|
388
|
-
c.req.raw,
|
|
389
|
-
connId,
|
|
390
|
-
connToken,
|
|
391
|
-
);
|
|
392
|
-
|
|
393
|
-
// Wait for close
|
|
394
|
-
const abortResolver = promiseWithResolvers();
|
|
395
|
-
|
|
396
|
-
// HACK: This is required so the abort handler below works
|
|
397
|
-
//
|
|
398
|
-
// See https://github.com/honojs/hono/issues/1770#issuecomment-2461966225
|
|
399
|
-
stream.onAbort(() => {});
|
|
400
|
-
|
|
401
|
-
// Handle stream abort (when client closes the connection)
|
|
402
|
-
c.req.raw.signal.addEventListener("abort", async () => {
|
|
403
|
-
invariant(actor, "actor should exist");
|
|
404
|
-
const rLog = actor.rLog ?? loggerWithoutContext();
|
|
405
|
-
try {
|
|
406
|
-
rLog.debug("sse stream aborted");
|
|
407
|
-
|
|
408
|
-
// Cleanup
|
|
409
|
-
if (conn) {
|
|
410
|
-
actor.__connDisconnected(conn, false, requestId);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
abortResolver.resolve(undefined);
|
|
414
|
-
} catch (error) {
|
|
415
|
-
rLog.error({ msg: "error closing sse connection", error });
|
|
416
|
-
abortResolver.resolve(undefined);
|
|
417
|
-
}
|
|
418
|
-
});
|
|
419
|
-
|
|
420
|
-
// // HACK: Will throw if not configured
|
|
421
|
-
// try {
|
|
422
|
-
// c.executionCtx.waitUntil(abortResolver.promise);
|
|
423
|
-
// } catch {}
|
|
424
|
-
|
|
425
|
-
// Send ping every second to keep the connection alive
|
|
426
|
-
//
|
|
427
|
-
// NOTE: This is required on Cloudflare Workers in order to detect when the connection is closed
|
|
428
|
-
while (true) {
|
|
429
|
-
if (stream.closed || stream.aborted) {
|
|
430
|
-
actor?.rLog.debug({
|
|
431
|
-
msg: "sse stream closed",
|
|
432
|
-
closed: stream.closed,
|
|
433
|
-
aborted: stream.aborted,
|
|
434
|
-
});
|
|
435
|
-
break;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
await stream.writeSSE({ event: "ping", data: "" });
|
|
439
|
-
await stream.sleep(SSE_PING_INTERVAL);
|
|
440
|
-
}
|
|
441
|
-
} catch (error) {
|
|
442
|
-
loggerWithoutContext().error({
|
|
443
|
-
msg: "error in sse connection",
|
|
444
|
-
error,
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
// Cleanup on error
|
|
448
|
-
if (conn && actor !== undefined) {
|
|
449
|
-
actor.__connDisconnected(conn, false, requestId);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// Close the stream on error
|
|
453
|
-
stream.close();
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
|
|
458
63
|
/**
|
|
459
64
|
* Creates an action handler
|
|
460
65
|
*/
|
|
@@ -474,9 +79,14 @@ export async function handleAction(
|
|
|
474
79
|
encoding,
|
|
475
80
|
new Uint8Array(arrayBuffer),
|
|
476
81
|
HTTP_ACTION_REQUEST_VERSIONED,
|
|
82
|
+
HttpActionRequestSchema,
|
|
83
|
+
// JSON: args is already the decoded value (raw object/array)
|
|
84
|
+
(json: HttpActionRequestJson) => json.args,
|
|
85
|
+
// BARE/CBOR: args is ArrayBuffer that needs CBOR-decoding
|
|
86
|
+
(bare: protocol.HttpActionRequest) =>
|
|
87
|
+
cbor.decode(new Uint8Array(bare.args)),
|
|
477
88
|
);
|
|
478
|
-
const actionArgs =
|
|
479
|
-
const requestId = generateConnRequestId();
|
|
89
|
+
const actionArgs = request;
|
|
480
90
|
|
|
481
91
|
// Invoke the action
|
|
482
92
|
let actor: AnyActorInstance | undefined;
|
|
@@ -488,198 +98,82 @@ export async function handleAction(
|
|
|
488
98
|
actor.rLog.debug({ msg: "handling action", actionName, encoding });
|
|
489
99
|
|
|
490
100
|
// Create conn
|
|
491
|
-
conn = await actor.
|
|
492
|
-
|
|
493
|
-
requestId: requestId,
|
|
494
|
-
hibernatable: false,
|
|
495
|
-
driverState: { [ConnDriverKind.HTTP]: {} },
|
|
496
|
-
},
|
|
101
|
+
conn = await actor.connectionManager.prepareAndConnectConn(
|
|
102
|
+
createHttpDriver(),
|
|
497
103
|
parameters,
|
|
498
104
|
c.req.raw,
|
|
105
|
+
c.req.path,
|
|
106
|
+
c.req.header(),
|
|
499
107
|
);
|
|
500
108
|
|
|
501
109
|
// Call action
|
|
502
|
-
const ctx = new ActionContext(actor
|
|
110
|
+
const ctx = new ActionContext(actor, conn!);
|
|
503
111
|
output = await actor.executeAction(ctx, actionName, actionArgs);
|
|
504
112
|
} finally {
|
|
505
113
|
if (conn) {
|
|
506
|
-
|
|
507
|
-
actor?.__connDisconnected(conn, true, requestId);
|
|
114
|
+
conn.disconnect();
|
|
508
115
|
}
|
|
509
116
|
}
|
|
510
117
|
|
|
511
118
|
// Send response
|
|
512
|
-
const responseData: protocol.HttpActionResponse = {
|
|
513
|
-
output: bufferToArrayBuffer(cbor.encode(output)),
|
|
514
|
-
};
|
|
515
119
|
const serialized = serializeWithEncoding(
|
|
516
120
|
encoding,
|
|
517
|
-
|
|
121
|
+
output,
|
|
518
122
|
HTTP_ACTION_RESPONSE_VERSIONED,
|
|
123
|
+
HttpActionResponseSchema,
|
|
124
|
+
// JSON: output is the raw value (will be serialized by jsonStringifyCompat)
|
|
125
|
+
(value): HttpActionResponseJson => ({ output: value }),
|
|
126
|
+
// BARE/CBOR: output needs to be CBOR-encoded to ArrayBuffer
|
|
127
|
+
(value): protocol.HttpActionResponse => ({
|
|
128
|
+
output: bufferToArrayBuffer(cbor.encode(value)),
|
|
129
|
+
}),
|
|
519
130
|
);
|
|
520
131
|
|
|
521
|
-
// TODO:
|
|
132
|
+
// TODO: Remove any, Hono is being a dumbass
|
|
522
133
|
return c.body(serialized as Uint8Array as any, 200, {
|
|
523
134
|
"Content-Type": contentTypeForEncoding(encoding),
|
|
524
135
|
});
|
|
525
136
|
}
|
|
526
137
|
|
|
527
|
-
|
|
528
|
-
* Create a connection message handler
|
|
529
|
-
*/
|
|
530
|
-
export async function handleConnectionMessage(
|
|
138
|
+
export async function handleRawRequest(
|
|
531
139
|
c: HonoContext,
|
|
532
|
-
|
|
140
|
+
req: Request,
|
|
533
141
|
actorDriver: ActorDriver,
|
|
534
|
-
connId: string,
|
|
535
|
-
connToken: string,
|
|
536
142
|
actorId: string,
|
|
537
|
-
) {
|
|
538
|
-
const encoding = getRequestEncoding(c.req);
|
|
539
|
-
|
|
540
|
-
// Validate incoming request
|
|
541
|
-
const arrayBuffer = await c.req.arrayBuffer();
|
|
542
|
-
const message = deserializeWithEncoding(
|
|
543
|
-
encoding,
|
|
544
|
-
new Uint8Array(arrayBuffer),
|
|
545
|
-
TO_SERVER_VERSIONED,
|
|
546
|
-
);
|
|
547
|
-
|
|
143
|
+
): Promise<Response> {
|
|
548
144
|
const actor = await actorDriver.loadActor(actorId);
|
|
145
|
+
const parameters = getRequestConnParams(c.req);
|
|
549
146
|
|
|
550
|
-
//
|
|
551
|
-
|
|
552
|
-
if (!conn) {
|
|
553
|
-
throw new errors.ConnNotFound(connId);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// Authenticate connection
|
|
557
|
-
if (conn._token !== connToken) {
|
|
558
|
-
throw new errors.IncorrectConnToken();
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// Process message
|
|
562
|
-
await actor.processMessage(message, conn);
|
|
563
|
-
|
|
564
|
-
return c.json({});
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
export async function handleConnectionClose(
|
|
568
|
-
c: HonoContext,
|
|
569
|
-
_runConfig: RunnerConfig,
|
|
570
|
-
actorDriver: ActorDriver,
|
|
571
|
-
connId: string,
|
|
572
|
-
connToken: string,
|
|
573
|
-
actorId: string,
|
|
574
|
-
) {
|
|
575
|
-
const actor = await actorDriver.loadActor(actorId);
|
|
576
|
-
|
|
577
|
-
// Find connection
|
|
578
|
-
const conn = actor.conns.get(connId);
|
|
579
|
-
if (!conn) {
|
|
580
|
-
throw new errors.ConnNotFound(connId);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
// Authenticate connection
|
|
584
|
-
if (conn._token !== connToken) {
|
|
585
|
-
throw new errors.IncorrectConnToken();
|
|
586
|
-
}
|
|
147
|
+
// Track connection outside of scope for cleanup
|
|
148
|
+
let createdConn: AnyConn | undefined;
|
|
587
149
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
150
|
+
try {
|
|
151
|
+
const conn = await actor.connectionManager.prepareAndConnectConn(
|
|
152
|
+
createRawRequestDriver(),
|
|
153
|
+
parameters,
|
|
154
|
+
req,
|
|
155
|
+
c.req.path,
|
|
156
|
+
c.req.header(),
|
|
595
157
|
);
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// Close the SSE connection
|
|
599
|
-
await conn.disconnect("Connection closed by client request");
|
|
600
158
|
|
|
601
|
-
|
|
602
|
-
}
|
|
159
|
+
createdConn = conn;
|
|
603
160
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
const actor = await actorDriver.loadActor(actorId);
|
|
612
|
-
|
|
613
|
-
// Return WebSocket event handlers
|
|
614
|
-
return {
|
|
615
|
-
onOpen: (evt: any, ws: any) => {
|
|
616
|
-
// Extract rivetRequestId provided by engine runner
|
|
617
|
-
const rivetRequestId = evt?.rivetRequestId;
|
|
618
|
-
const isHibernatable =
|
|
619
|
-
actor[PERSIST_SYMBOL].hibernatableWebSocket.findIndex((ws) =>
|
|
620
|
-
arrayBuffersEqual(ws.requestId, rivetRequestId),
|
|
621
|
-
) !== -1;
|
|
622
|
-
|
|
623
|
-
// Wrap the Hono WebSocket in our adapter
|
|
624
|
-
const adapter = new HonoWebSocketAdapter(
|
|
625
|
-
ws,
|
|
626
|
-
rivetRequestId,
|
|
627
|
-
isHibernatable,
|
|
628
|
-
);
|
|
629
|
-
|
|
630
|
-
// Store adapter reference on the WebSocket for event handlers
|
|
631
|
-
(ws as any).__adapter = adapter;
|
|
632
|
-
|
|
633
|
-
const newPath = truncateRawWebSocketPathPrefix(path);
|
|
634
|
-
let newRequest: Request;
|
|
635
|
-
if (req) {
|
|
636
|
-
newRequest = new Request(`http://actor${newPath}`, req);
|
|
637
|
-
} else {
|
|
638
|
-
newRequest = new Request(`http://actor${newPath}`, {
|
|
639
|
-
method: "GET",
|
|
640
|
-
});
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
actor.rLog.debug({
|
|
644
|
-
msg: "rewriting websocket url",
|
|
645
|
-
fromPath: path,
|
|
646
|
-
toUrl: newRequest.url,
|
|
647
|
-
});
|
|
648
|
-
|
|
649
|
-
// Call the actor's onWebSocket handler with the adapted WebSocket
|
|
650
|
-
actor.handleWebSocket(adapter, {
|
|
651
|
-
request: newRequest,
|
|
652
|
-
});
|
|
653
|
-
},
|
|
654
|
-
onMessage: (event: any, ws: any) => {
|
|
655
|
-
// Find the adapter for this WebSocket
|
|
656
|
-
const adapter = (ws as any).__adapter;
|
|
657
|
-
if (adapter) {
|
|
658
|
-
adapter._handleMessage(event);
|
|
659
|
-
}
|
|
660
|
-
},
|
|
661
|
-
onClose: (evt: any, ws: any) => {
|
|
662
|
-
// Find the adapter for this WebSocket
|
|
663
|
-
const adapter = (ws as any).__adapter;
|
|
664
|
-
if (adapter) {
|
|
665
|
-
adapter._handleClose(evt?.code || 1006, evt?.reason || "");
|
|
666
|
-
}
|
|
667
|
-
},
|
|
668
|
-
onError: (error: any, ws: any) => {
|
|
669
|
-
// Find the adapter for this WebSocket
|
|
670
|
-
const adapter = (ws as any).__adapter;
|
|
671
|
-
if (adapter) {
|
|
672
|
-
adapter._handleError(error);
|
|
673
|
-
}
|
|
674
|
-
},
|
|
675
|
-
};
|
|
161
|
+
return await actor.handleRawRequest(conn, req);
|
|
162
|
+
} finally {
|
|
163
|
+
// Clean up the connection after the request completes
|
|
164
|
+
if (createdConn) {
|
|
165
|
+
createdConn.disconnect();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
676
168
|
}
|
|
677
169
|
|
|
678
170
|
// Helper to get the connection encoding from a request
|
|
171
|
+
//
|
|
172
|
+
// Defaults to JSON if not provided so we can support vanilla curl requests easily.
|
|
679
173
|
export function getRequestEncoding(req: HonoRequest): Encoding {
|
|
680
174
|
const encodingParam = req.header(HEADER_ENCODING);
|
|
681
175
|
if (!encodingParam) {
|
|
682
|
-
|
|
176
|
+
return "json";
|
|
683
177
|
}
|
|
684
178
|
|
|
685
179
|
const result = EncodingSchema.safeParse(encodingParam);
|
|
@@ -728,22 +222,3 @@ export function getRequestConnParams(req: HonoRequest): unknown {
|
|
|
728
222
|
);
|
|
729
223
|
}
|
|
730
224
|
}
|
|
731
|
-
|
|
732
|
-
/**
|
|
733
|
-
* Truncase the PATH_RAW_WEBSOCKET_PREFIX path prefix in order to pass a clean
|
|
734
|
-
* path to the onWebSocket handler.
|
|
735
|
-
*
|
|
736
|
-
* Example:
|
|
737
|
-
* - `/raw/websocket/foo` -> `/foo`
|
|
738
|
-
* - `/raw/websocket` -> `/`
|
|
739
|
-
*/
|
|
740
|
-
export function truncateRawWebSocketPathPrefix(path: string): string {
|
|
741
|
-
// Extract the path after prefix and preserve query parameters
|
|
742
|
-
// Use URL API for cleaner parsing
|
|
743
|
-
const url = new URL(path, "http://actor");
|
|
744
|
-
const pathname = url.pathname.replace(/^\/raw\/websocket\/?/, "") || "/";
|
|
745
|
-
const normalizedPath =
|
|
746
|
-
(pathname.startsWith("/") ? pathname : "/" + pathname) + url.search;
|
|
747
|
-
|
|
748
|
-
return normalizedPath;
|
|
749
|
-
}
|