rivetkit 2.0.1 → 2.0.3
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/v1.ts +228 -0
- package/dist/schemas/client-protocol/v1.ts +429 -0
- package/dist/schemas/file-system-driver/v1.ts +102 -0
- package/dist/tsup/actor/errors.cjs +69 -0
- package/dist/tsup/actor/errors.cjs.map +1 -0
- package/dist/tsup/actor/errors.d.cts +143 -0
- package/dist/tsup/actor/errors.d.ts +143 -0
- package/dist/tsup/actor/errors.js +69 -0
- package/dist/tsup/actor/errors.js.map +1 -0
- package/dist/tsup/chunk-2CRLFV6Z.cjs +202 -0
- package/dist/tsup/chunk-2CRLFV6Z.cjs.map +1 -0
- package/dist/tsup/chunk-3H7O2A7I.js +525 -0
- package/dist/tsup/chunk-3H7O2A7I.js.map +1 -0
- package/dist/tsup/chunk-42I3OZ3Q.js +15 -0
- package/dist/tsup/chunk-42I3OZ3Q.js.map +1 -0
- package/dist/tsup/chunk-4NSUQZ2H.js +1790 -0
- package/dist/tsup/chunk-4NSUQZ2H.js.map +1 -0
- package/dist/tsup/chunk-6PDXBYI5.js +132 -0
- package/dist/tsup/chunk-6PDXBYI5.js.map +1 -0
- package/dist/tsup/chunk-6WKQDDUD.cjs +1790 -0
- package/dist/tsup/chunk-6WKQDDUD.cjs.map +1 -0
- package/dist/tsup/chunk-CTBOSFUH.cjs +116 -0
- package/dist/tsup/chunk-CTBOSFUH.cjs.map +1 -0
- package/dist/tsup/chunk-EGVZZFE2.js +2857 -0
- package/dist/tsup/chunk-EGVZZFE2.js.map +1 -0
- package/dist/tsup/chunk-FCCPJNMA.cjs +132 -0
- package/dist/tsup/chunk-FCCPJNMA.cjs.map +1 -0
- package/dist/tsup/chunk-FLMTTN27.js +244 -0
- package/dist/tsup/chunk-FLMTTN27.js.map +1 -0
- package/dist/tsup/chunk-GIR3AFFI.cjs +315 -0
- package/dist/tsup/chunk-GIR3AFFI.cjs.map +1 -0
- package/dist/tsup/chunk-INGJP237.js +315 -0
- package/dist/tsup/chunk-INGJP237.js.map +1 -0
- package/dist/tsup/chunk-KJCJLKRM.js +116 -0
- package/dist/tsup/chunk-KJCJLKRM.js.map +1 -0
- package/dist/tsup/chunk-KUPQZYUQ.cjs +15 -0
- package/dist/tsup/chunk-KUPQZYUQ.cjs.map +1 -0
- package/dist/tsup/chunk-O2MBYIXO.cjs +2857 -0
- package/dist/tsup/chunk-O2MBYIXO.cjs.map +1 -0
- package/dist/tsup/chunk-OGAPU3UG.cjs +525 -0
- package/dist/tsup/chunk-OGAPU3UG.cjs.map +1 -0
- package/dist/tsup/chunk-OV6AYD4S.js +4406 -0
- package/dist/tsup/chunk-OV6AYD4S.js.map +1 -0
- package/dist/tsup/chunk-PO4VLDWA.js +47 -0
- package/dist/tsup/chunk-PO4VLDWA.js.map +1 -0
- package/dist/tsup/chunk-R2OPSKIV.cjs +244 -0
- package/dist/tsup/chunk-R2OPSKIV.cjs.map +1 -0
- package/dist/tsup/chunk-TZJKSBUQ.cjs +47 -0
- package/dist/tsup/chunk-TZJKSBUQ.cjs.map +1 -0
- package/dist/tsup/chunk-UBUC5C3G.cjs +189 -0
- package/dist/tsup/chunk-UBUC5C3G.cjs.map +1 -0
- package/dist/tsup/chunk-UIM22YJL.cjs +4406 -0
- package/dist/tsup/chunk-UIM22YJL.cjs.map +1 -0
- package/dist/tsup/chunk-URVFQMYI.cjs +230 -0
- package/dist/tsup/chunk-URVFQMYI.cjs.map +1 -0
- package/dist/tsup/chunk-UVUPOS46.js +230 -0
- package/dist/tsup/chunk-UVUPOS46.js.map +1 -0
- package/dist/tsup/chunk-VRRHBNJC.js +189 -0
- package/dist/tsup/chunk-VRRHBNJC.js.map +1 -0
- package/dist/tsup/chunk-XFSS33EQ.js +202 -0
- package/dist/tsup/chunk-XFSS33EQ.js.map +1 -0
- package/dist/tsup/client/mod.cjs +32 -0
- package/dist/tsup/client/mod.cjs.map +1 -0
- package/dist/tsup/client/mod.d.cts +26 -0
- package/dist/tsup/client/mod.d.ts +26 -0
- package/dist/tsup/client/mod.js +32 -0
- package/dist/tsup/client/mod.js.map +1 -0
- package/dist/tsup/common/log.cjs +13 -0
- package/dist/tsup/common/log.cjs.map +1 -0
- package/dist/tsup/common/log.d.cts +20 -0
- package/dist/tsup/common/log.d.ts +20 -0
- package/dist/tsup/common/log.js +13 -0
- package/dist/tsup/common/log.js.map +1 -0
- package/dist/tsup/common/websocket.cjs +10 -0
- package/dist/tsup/common/websocket.cjs.map +1 -0
- package/dist/tsup/common/websocket.d.cts +3 -0
- package/dist/tsup/common/websocket.d.ts +3 -0
- package/dist/tsup/common/websocket.js +10 -0
- package/dist/tsup/common/websocket.js.map +1 -0
- package/dist/tsup/common-CpqORuCq.d.cts +218 -0
- package/dist/tsup/common-CpqORuCq.d.ts +218 -0
- package/dist/tsup/connection-BR_Ve4ku.d.cts +2117 -0
- package/dist/tsup/connection-BwUMoe6n.d.ts +2117 -0
- package/dist/tsup/driver-helpers/mod.cjs +33 -0
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -0
- package/dist/tsup/driver-helpers/mod.d.cts +18 -0
- package/dist/tsup/driver-helpers/mod.d.ts +18 -0
- package/dist/tsup/driver-helpers/mod.js +33 -0
- package/dist/tsup/driver-helpers/mod.js.map +1 -0
- package/dist/tsup/driver-test-suite/mod.cjs +4619 -0
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -0
- package/dist/tsup/driver-test-suite/mod.d.cts +57 -0
- package/dist/tsup/driver-test-suite/mod.d.ts +57 -0
- package/dist/tsup/driver-test-suite/mod.js +4619 -0
- package/dist/tsup/driver-test-suite/mod.js.map +1 -0
- package/dist/tsup/inspector/mod.cjs +53 -0
- package/dist/tsup/inspector/mod.cjs.map +1 -0
- package/dist/tsup/inspector/mod.d.cts +408 -0
- package/dist/tsup/inspector/mod.d.ts +408 -0
- package/dist/tsup/inspector/mod.js +53 -0
- package/dist/tsup/inspector/mod.js.map +1 -0
- package/dist/tsup/mod.cjs +73 -0
- package/dist/tsup/mod.cjs.map +1 -0
- package/dist/tsup/mod.d.cts +100 -0
- package/dist/tsup/mod.d.ts +100 -0
- package/dist/tsup/mod.js +73 -0
- package/dist/tsup/mod.js.map +1 -0
- package/dist/tsup/router-endpoints-AYkXG8Tl.d.cts +66 -0
- package/dist/tsup/router-endpoints-DAbqVFx2.d.ts +66 -0
- package/dist/tsup/test/mod.cjs +21 -0
- package/dist/tsup/test/mod.cjs.map +1 -0
- package/dist/tsup/test/mod.d.cts +27 -0
- package/dist/tsup/test/mod.d.ts +27 -0
- package/dist/tsup/test/mod.js +21 -0
- package/dist/tsup/test/mod.js.map +1 -0
- package/dist/tsup/utils-CT0cv4jd.d.cts +17 -0
- package/dist/tsup/utils-CT0cv4jd.d.ts +17 -0
- package/dist/tsup/utils.cjs +26 -0
- package/dist/tsup/utils.cjs.map +1 -0
- package/dist/tsup/utils.d.cts +36 -0
- package/dist/tsup/utils.d.ts +36 -0
- package/dist/tsup/utils.js +26 -0
- package/dist/tsup/utils.js.map +1 -0
- package/package.json +208 -5
- package/src/actor/action.ts +182 -0
- package/src/actor/config.ts +765 -0
- package/src/actor/connection.ts +260 -0
- package/src/actor/context.ts +171 -0
- package/src/actor/database.ts +23 -0
- package/src/actor/definition.ts +86 -0
- package/src/actor/driver.ts +84 -0
- package/src/actor/errors.ts +360 -0
- package/src/actor/generic-conn-driver.ts +234 -0
- package/src/actor/instance.ts +1800 -0
- package/src/actor/log.ts +15 -0
- package/src/actor/mod.ts +113 -0
- package/src/actor/persisted.ts +42 -0
- package/src/actor/protocol/old.ts +281 -0
- package/src/actor/protocol/serde.ts +131 -0
- package/src/actor/router-endpoints.ts +685 -0
- package/src/actor/router.ts +263 -0
- package/src/actor/schedule.ts +17 -0
- package/src/actor/unstable-react.ts +110 -0
- package/src/actor/utils.ts +98 -0
- package/src/client/actor-common.ts +30 -0
- package/src/client/actor-conn.ts +804 -0
- package/src/client/actor-handle.ts +208 -0
- package/src/client/client.ts +623 -0
- package/src/client/errors.ts +41 -0
- package/src/client/http-client-driver.ts +326 -0
- package/src/client/log.ts +7 -0
- package/src/client/mod.ts +56 -0
- package/src/client/raw-utils.ts +92 -0
- package/src/client/test.ts +44 -0
- package/src/client/utils.ts +150 -0
- package/src/common/eventsource-interface.ts +47 -0
- package/src/common/eventsource.ts +80 -0
- package/src/common/fake-event-source.ts +266 -0
- package/src/common/inline-websocket-adapter2.ts +445 -0
- package/src/common/log-levels.ts +27 -0
- package/src/common/log.ts +139 -0
- package/src/common/logfmt.ts +228 -0
- package/src/common/network.ts +2 -0
- package/src/common/router.ts +87 -0
- package/src/common/utils.ts +322 -0
- package/src/common/versioned-data.ts +95 -0
- package/src/common/websocket-interface.ts +49 -0
- package/src/common/websocket.ts +43 -0
- package/src/driver-helpers/mod.ts +22 -0
- package/src/driver-helpers/utils.ts +17 -0
- package/src/driver-test-suite/log.ts +7 -0
- package/src/driver-test-suite/mod.ts +213 -0
- package/src/driver-test-suite/test-inline-client-driver.ts +402 -0
- package/src/driver-test-suite/tests/action-features.ts +136 -0
- package/src/driver-test-suite/tests/actor-auth.ts +591 -0
- package/src/driver-test-suite/tests/actor-conn-state.ts +249 -0
- package/src/driver-test-suite/tests/actor-conn.ts +349 -0
- package/src/driver-test-suite/tests/actor-driver.ts +25 -0
- package/src/driver-test-suite/tests/actor-error-handling.ts +158 -0
- package/src/driver-test-suite/tests/actor-handle.ts +259 -0
- package/src/driver-test-suite/tests/actor-inline-client.ts +152 -0
- package/src/driver-test-suite/tests/actor-inspector.ts +570 -0
- package/src/driver-test-suite/tests/actor-metadata.ts +116 -0
- package/src/driver-test-suite/tests/actor-onstatechange.ts +95 -0
- package/src/driver-test-suite/tests/actor-schedule.ts +108 -0
- package/src/driver-test-suite/tests/actor-sleep.ts +413 -0
- package/src/driver-test-suite/tests/actor-state.ts +54 -0
- package/src/driver-test-suite/tests/actor-vars.ts +93 -0
- package/src/driver-test-suite/tests/manager-driver.ts +365 -0
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +226 -0
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +414 -0
- package/src/driver-test-suite/tests/raw-http.ts +347 -0
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +392 -0
- package/src/driver-test-suite/tests/raw-websocket.ts +484 -0
- package/src/driver-test-suite/tests/request-access.ts +244 -0
- package/src/driver-test-suite/utils.ts +68 -0
- package/src/drivers/default.ts +31 -0
- package/src/drivers/engine/actor-driver.ts +360 -0
- package/src/drivers/engine/api-endpoints.ts +128 -0
- package/src/drivers/engine/api-utils.ts +70 -0
- package/src/drivers/engine/config.ts +39 -0
- package/src/drivers/engine/keys.test.ts +266 -0
- package/src/drivers/engine/keys.ts +89 -0
- package/src/drivers/engine/kv.ts +3 -0
- package/src/drivers/engine/log.ts +7 -0
- package/src/drivers/engine/manager-driver.ts +391 -0
- package/src/drivers/engine/mod.ts +36 -0
- package/src/drivers/engine/ws-proxy.ts +170 -0
- package/src/drivers/file-system/actor.ts +91 -0
- package/src/drivers/file-system/global-state.ts +673 -0
- package/src/drivers/file-system/log.ts +7 -0
- package/src/drivers/file-system/manager.ts +306 -0
- package/src/drivers/file-system/mod.ts +48 -0
- package/src/drivers/file-system/utils.ts +109 -0
- package/src/globals.d.ts +6 -0
- package/src/inline-client-driver/log.ts +7 -0
- package/src/inline-client-driver/mod.ts +385 -0
- package/src/inspector/actor.ts +298 -0
- package/src/inspector/config.ts +83 -0
- package/src/inspector/log.ts +5 -0
- package/src/inspector/manager.ts +86 -0
- package/src/inspector/mod.ts +2 -0
- package/src/inspector/protocol/actor.ts +10 -0
- package/src/inspector/protocol/common.ts +196 -0
- package/src/inspector/protocol/manager.ts +10 -0
- package/src/inspector/protocol/mod.ts +2 -0
- package/src/inspector/utils.ts +76 -0
- package/src/manager/auth.ts +121 -0
- package/src/manager/driver.ts +80 -0
- package/src/manager/hono-websocket-adapter.ts +333 -0
- package/src/manager/log.ts +7 -0
- package/src/manager/mod.ts +2 -0
- package/src/manager/protocol/mod.ts +24 -0
- package/src/manager/protocol/query.ts +89 -0
- package/src/manager/router.ts +1792 -0
- package/src/mod.ts +20 -0
- package/src/registry/config.ts +32 -0
- package/src/registry/log.ts +7 -0
- package/src/registry/mod.ts +124 -0
- package/src/registry/run-config.ts +54 -0
- package/src/registry/serve.ts +53 -0
- package/src/schemas/actor-persist/mod.ts +1 -0
- package/src/schemas/actor-persist/versioned.ts +25 -0
- package/src/schemas/client-protocol/mod.ts +1 -0
- package/src/schemas/client-protocol/versioned.ts +63 -0
- package/src/schemas/file-system-driver/mod.ts +1 -0
- package/src/schemas/file-system-driver/versioned.ts +28 -0
- package/src/serde.ts +84 -0
- package/src/test/config.ts +16 -0
- package/src/test/log.ts +7 -0
- package/src/test/mod.ts +153 -0
- package/src/utils.ts +172 -0
- package/README.md +0 -13
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import * as cbor from "cbor-x";
|
|
2
|
+
import type { Context as HonoContext } from "hono";
|
|
3
|
+
import type { WebSocket } from "ws";
|
|
4
|
+
import type { Encoding } from "@/actor/protocol/serde";
|
|
5
|
+
import {
|
|
6
|
+
HEADER_ACTOR_ID,
|
|
7
|
+
HEADER_ACTOR_QUERY,
|
|
8
|
+
HEADER_CONN_ID,
|
|
9
|
+
HEADER_CONN_PARAMS,
|
|
10
|
+
HEADER_CONN_TOKEN,
|
|
11
|
+
HEADER_ENCODING,
|
|
12
|
+
} from "@/actor/router-endpoints";
|
|
13
|
+
import { importEventSource } from "@/common/eventsource";
|
|
14
|
+
import type { UniversalEventSource } from "@/common/eventsource-interface";
|
|
15
|
+
import { importWebSocket } from "@/common/websocket";
|
|
16
|
+
import type { ActorQuery } from "@/manager/protocol/query";
|
|
17
|
+
import type * as protocol from "@/schemas/client-protocol/mod";
|
|
18
|
+
import {
|
|
19
|
+
HTTP_ACTION_REQUEST_VERSIONED,
|
|
20
|
+
HTTP_ACTION_RESPONSE_VERSIONED,
|
|
21
|
+
HTTP_RESOLVE_REQUEST_VERSIONED,
|
|
22
|
+
HTTP_RESOLVE_RESPONSE_VERSIONED,
|
|
23
|
+
TO_SERVER_VERSIONED,
|
|
24
|
+
} from "@/schemas/client-protocol/versioned";
|
|
25
|
+
import { serializeWithEncoding, wsBinaryTypeForEncoding } from "@/serde";
|
|
26
|
+
import { assertUnreachable, bufferToArrayBuffer, httpUserAgent } from "@/utils";
|
|
27
|
+
import type { ClientDriver } from "./client";
|
|
28
|
+
import * as errors from "./errors";
|
|
29
|
+
import { logger } from "./log";
|
|
30
|
+
import { sendHttpRequest } from "./utils";
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Client driver that communicates with the manager via HTTP.
|
|
34
|
+
*/
|
|
35
|
+
export function createHttpClientDriver(managerEndpoint: string): ClientDriver {
|
|
36
|
+
// Lazily import the dynamic imports so we don't have to turn `createClient` in to an async fn
|
|
37
|
+
const dynamicImports = (async () => {
|
|
38
|
+
// Import dynamic dependencies
|
|
39
|
+
const [WebSocket, EventSource] = await Promise.all([
|
|
40
|
+
importWebSocket(),
|
|
41
|
+
importEventSource(),
|
|
42
|
+
]);
|
|
43
|
+
return {
|
|
44
|
+
WebSocket,
|
|
45
|
+
EventSource,
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
|
|
49
|
+
const driver: ClientDriver = {
|
|
50
|
+
action: async <Args extends Array<unknown> = unknown[], Response = unknown>(
|
|
51
|
+
_c: HonoContext | undefined,
|
|
52
|
+
actorQuery: ActorQuery,
|
|
53
|
+
encoding: Encoding,
|
|
54
|
+
params: unknown,
|
|
55
|
+
name: string,
|
|
56
|
+
args: Args,
|
|
57
|
+
opts: { signal?: AbortSignal } | undefined,
|
|
58
|
+
): Promise<Response> => {
|
|
59
|
+
logger().debug("actor handle action", {
|
|
60
|
+
name,
|
|
61
|
+
args,
|
|
62
|
+
query: actorQuery,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const responseData = await sendHttpRequest<
|
|
66
|
+
protocol.HttpActionRequest,
|
|
67
|
+
protocol.HttpActionResponse
|
|
68
|
+
>({
|
|
69
|
+
url: `${managerEndpoint}/registry/actors/actions/${encodeURIComponent(name)}`,
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers: {
|
|
72
|
+
[HEADER_ENCODING]: encoding,
|
|
73
|
+
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
|
|
74
|
+
...(params !== undefined
|
|
75
|
+
? { [HEADER_CONN_PARAMS]: JSON.stringify(params) }
|
|
76
|
+
: {}),
|
|
77
|
+
},
|
|
78
|
+
body: {
|
|
79
|
+
args: bufferToArrayBuffer(cbor.encode(args)),
|
|
80
|
+
} satisfies protocol.HttpActionRequest,
|
|
81
|
+
encoding: encoding,
|
|
82
|
+
signal: opts?.signal,
|
|
83
|
+
requestVersionedDataHandler: HTTP_ACTION_REQUEST_VERSIONED,
|
|
84
|
+
responseVersionedDataHandler: HTTP_ACTION_RESPONSE_VERSIONED,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return cbor.decode(new Uint8Array(responseData.output));
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
resolveActorId: async (
|
|
91
|
+
_c: HonoContext | undefined,
|
|
92
|
+
actorQuery: ActorQuery,
|
|
93
|
+
encodingKind: Encoding,
|
|
94
|
+
params: unknown,
|
|
95
|
+
): Promise<string> => {
|
|
96
|
+
logger().debug("resolving actor ID", { query: actorQuery });
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
const result = await sendHttpRequest<
|
|
100
|
+
null,
|
|
101
|
+
protocol.HttpResolveResponse
|
|
102
|
+
>({
|
|
103
|
+
url: `${managerEndpoint}/registry/actors/resolve`,
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: {
|
|
106
|
+
[HEADER_ENCODING]: encodingKind,
|
|
107
|
+
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
|
|
108
|
+
...(params !== undefined
|
|
109
|
+
? { [HEADER_CONN_PARAMS]: JSON.stringify(params) }
|
|
110
|
+
: {}),
|
|
111
|
+
},
|
|
112
|
+
body: null,
|
|
113
|
+
encoding: encodingKind,
|
|
114
|
+
requestVersionedDataHandler: HTTP_RESOLVE_REQUEST_VERSIONED,
|
|
115
|
+
responseVersionedDataHandler: HTTP_RESOLVE_RESPONSE_VERSIONED,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
logger().debug("resolved actor ID", { actorId: result.actorId });
|
|
119
|
+
return result.actorId;
|
|
120
|
+
} catch (error) {
|
|
121
|
+
logger().error("failed to resolve actor ID", { error });
|
|
122
|
+
if (error instanceof errors.ActorError) {
|
|
123
|
+
throw error;
|
|
124
|
+
} else {
|
|
125
|
+
throw new errors.InternalError(
|
|
126
|
+
`Failed to resolve actor ID: ${String(error)}`,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
connectWebSocket: async (
|
|
133
|
+
_c: HonoContext | undefined,
|
|
134
|
+
actorQuery: ActorQuery,
|
|
135
|
+
encodingKind: Encoding,
|
|
136
|
+
params: unknown,
|
|
137
|
+
): Promise<WebSocket> => {
|
|
138
|
+
const { WebSocket } = await dynamicImports;
|
|
139
|
+
|
|
140
|
+
const endpoint = managerEndpoint
|
|
141
|
+
.replace(/^http:/, "ws:")
|
|
142
|
+
.replace(/^https:/, "wss:");
|
|
143
|
+
const url = `${endpoint}/registry/actors/connect/websocket`;
|
|
144
|
+
|
|
145
|
+
// Pass sensitive data via protocol
|
|
146
|
+
const protocol = [
|
|
147
|
+
`query.${encodeURIComponent(JSON.stringify(actorQuery))}`,
|
|
148
|
+
`encoding.${encodingKind}`,
|
|
149
|
+
];
|
|
150
|
+
if (params)
|
|
151
|
+
protocol.push(
|
|
152
|
+
`conn_params.${encodeURIComponent(JSON.stringify(params))}`,
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
156
|
+
protocol.push("rivetkit");
|
|
157
|
+
|
|
158
|
+
logger().debug("connecting to websocket", { url });
|
|
159
|
+
const ws = new WebSocket(url, protocol);
|
|
160
|
+
// HACK: Bun bug prevents changing binary type, so we ignore the error https://github.com/oven-sh/bun/issues/17005
|
|
161
|
+
try {
|
|
162
|
+
ws.binaryType = wsBinaryTypeForEncoding(encodingKind);
|
|
163
|
+
} catch (error) {}
|
|
164
|
+
|
|
165
|
+
// Node & web WebSocket types not compatible
|
|
166
|
+
return ws as any;
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
connectSse: async (
|
|
170
|
+
_c: HonoContext | undefined,
|
|
171
|
+
actorQuery: ActorQuery,
|
|
172
|
+
encodingKind: Encoding,
|
|
173
|
+
params: unknown,
|
|
174
|
+
): Promise<UniversalEventSource> => {
|
|
175
|
+
const { EventSource } = await dynamicImports;
|
|
176
|
+
|
|
177
|
+
const url = `${managerEndpoint}/registry/actors/connect/sse`;
|
|
178
|
+
|
|
179
|
+
logger().debug("connecting to sse", { url });
|
|
180
|
+
const eventSource = new EventSource(url, {
|
|
181
|
+
fetch: (input, init) => {
|
|
182
|
+
return fetch(input, {
|
|
183
|
+
...init,
|
|
184
|
+
headers: {
|
|
185
|
+
...init?.headers,
|
|
186
|
+
"User-Agent": httpUserAgent(),
|
|
187
|
+
[HEADER_ENCODING]: encodingKind,
|
|
188
|
+
[HEADER_ACTOR_QUERY]: JSON.stringify(actorQuery),
|
|
189
|
+
...(params !== undefined
|
|
190
|
+
? { [HEADER_CONN_PARAMS]: JSON.stringify(params) }
|
|
191
|
+
: {}),
|
|
192
|
+
},
|
|
193
|
+
credentials: "include",
|
|
194
|
+
});
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
return eventSource as UniversalEventSource;
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
sendHttpMessage: async (
|
|
202
|
+
_c: HonoContext | undefined,
|
|
203
|
+
actorId: string,
|
|
204
|
+
encoding: Encoding,
|
|
205
|
+
connectionId: string,
|
|
206
|
+
connectionToken: string,
|
|
207
|
+
message: protocol.ToServer,
|
|
208
|
+
): Promise<void> => {
|
|
209
|
+
// TODO: Implement ordered messages, this is not guaranteed order. Needs to use an index in order to ensure we can pipeline requests efficiently.
|
|
210
|
+
// TODO: Validate that we're using HTTP/3 whenever possible for pipelining requests
|
|
211
|
+
const messageSerialized = serializeWithEncoding(
|
|
212
|
+
encoding,
|
|
213
|
+
message,
|
|
214
|
+
TO_SERVER_VERSIONED,
|
|
215
|
+
);
|
|
216
|
+
const res = await fetch(`${managerEndpoint}/registry/actors/message`, {
|
|
217
|
+
method: "POST",
|
|
218
|
+
headers: {
|
|
219
|
+
"User-Agent": httpUserAgent(),
|
|
220
|
+
[HEADER_ENCODING]: encoding,
|
|
221
|
+
[HEADER_ACTOR_ID]: actorId,
|
|
222
|
+
[HEADER_CONN_ID]: connectionId,
|
|
223
|
+
[HEADER_CONN_TOKEN]: connectionToken,
|
|
224
|
+
},
|
|
225
|
+
body: messageSerialized,
|
|
226
|
+
credentials: "include",
|
|
227
|
+
});
|
|
228
|
+
if (!res.ok) {
|
|
229
|
+
throw new errors.InternalError(
|
|
230
|
+
`Publish message over HTTP error (${res.statusText}):\n${await res.text()}`,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Discard response
|
|
235
|
+
await res.body?.cancel();
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
rawHttpRequest: async (
|
|
239
|
+
_c: HonoContext | undefined,
|
|
240
|
+
actorQuery: ActorQuery,
|
|
241
|
+
encoding: Encoding,
|
|
242
|
+
params: unknown,
|
|
243
|
+
path: string,
|
|
244
|
+
init: RequestInit,
|
|
245
|
+
): Promise<Response> => {
|
|
246
|
+
// Build the full URL
|
|
247
|
+
// Remove leading slash from path to avoid double slashes
|
|
248
|
+
const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
249
|
+
const url = `${managerEndpoint}/registry/actors/raw/http/${normalizedPath}`;
|
|
250
|
+
|
|
251
|
+
logger().debug("rewriting http url", {
|
|
252
|
+
from: path,
|
|
253
|
+
to: url,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Merge headers properly
|
|
257
|
+
const headers = new Headers(init.headers);
|
|
258
|
+
headers.set("User-Agent", httpUserAgent());
|
|
259
|
+
headers.set(HEADER_ACTOR_QUERY, JSON.stringify(actorQuery));
|
|
260
|
+
headers.set(HEADER_ENCODING, encoding);
|
|
261
|
+
if (params !== undefined) {
|
|
262
|
+
headers.set(HEADER_CONN_PARAMS, JSON.stringify(params));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Forward the request with query in headers
|
|
266
|
+
return await fetch(url, {
|
|
267
|
+
...init,
|
|
268
|
+
headers,
|
|
269
|
+
});
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
rawWebSocket: async (
|
|
273
|
+
_c: HonoContext | undefined,
|
|
274
|
+
actorQuery: ActorQuery,
|
|
275
|
+
encoding: Encoding,
|
|
276
|
+
params: unknown,
|
|
277
|
+
path: string,
|
|
278
|
+
protocols: string | string[] | undefined,
|
|
279
|
+
): Promise<WebSocket> => {
|
|
280
|
+
const { WebSocket } = await dynamicImports;
|
|
281
|
+
|
|
282
|
+
// Build the WebSocket URL with normalized path
|
|
283
|
+
const wsEndpoint = managerEndpoint
|
|
284
|
+
.replace(/^http:/, "ws:")
|
|
285
|
+
.replace(/^https:/, "wss:");
|
|
286
|
+
// Normalize path to match raw HTTP behavior
|
|
287
|
+
const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
|
|
288
|
+
const url = `${wsEndpoint}/registry/actors/raw/websocket/${normalizedPath}`;
|
|
289
|
+
|
|
290
|
+
logger().debug("rewriting websocket url", {
|
|
291
|
+
from: path,
|
|
292
|
+
to: url,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// Pass data via WebSocket protocol subprotocols
|
|
296
|
+
const protocolList: string[] = [];
|
|
297
|
+
protocolList.push(
|
|
298
|
+
`query.${encodeURIComponent(JSON.stringify(actorQuery))}`,
|
|
299
|
+
);
|
|
300
|
+
protocolList.push(`encoding.${encoding}`);
|
|
301
|
+
if (params) {
|
|
302
|
+
protocolList.push(
|
|
303
|
+
`conn_params.${encodeURIComponent(JSON.stringify(params))}`,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// HACK: See packages/drivers/cloudflare-workers/src/websocket.ts
|
|
308
|
+
protocolList.push("rivetkit");
|
|
309
|
+
|
|
310
|
+
// Add user protocols
|
|
311
|
+
if (protocols) {
|
|
312
|
+
if (Array.isArray(protocols)) {
|
|
313
|
+
protocolList.push(...protocols);
|
|
314
|
+
} else {
|
|
315
|
+
protocolList.push(protocols);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Create WebSocket connection
|
|
320
|
+
logger().debug("opening raw websocket", { url });
|
|
321
|
+
return new WebSocket(url, protocolList) as any;
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
return driver;
|
|
326
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Registry } from "@/registry/mod";
|
|
2
|
+
import {
|
|
3
|
+
type Client,
|
|
4
|
+
type ClientOptions,
|
|
5
|
+
createClientWithDriver,
|
|
6
|
+
} from "./client";
|
|
7
|
+
import { createHttpClientDriver } from "./http-client-driver";
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
ActorDefinition,
|
|
11
|
+
AnyActorDefinition,
|
|
12
|
+
} from "@/actor/definition";
|
|
13
|
+
export type { Transport } from "@/actor/protocol/old";
|
|
14
|
+
export type { Encoding } from "@/actor/protocol/serde";
|
|
15
|
+
export {
|
|
16
|
+
ActorClientError,
|
|
17
|
+
ActorError,
|
|
18
|
+
InternalError,
|
|
19
|
+
MalformedResponseMessage,
|
|
20
|
+
ManagerError,
|
|
21
|
+
} from "@/client/errors";
|
|
22
|
+
export type { CreateRequest } from "@/manager/protocol/query";
|
|
23
|
+
export type { ActorActionFunction } from "./actor-common";
|
|
24
|
+
export type { ActorConn, EventUnsubscribe } from "./actor-conn";
|
|
25
|
+
export { ActorConnRaw } from "./actor-conn";
|
|
26
|
+
export type { ActorHandle } from "./actor-handle";
|
|
27
|
+
export { ActorHandleRaw } from "./actor-handle";
|
|
28
|
+
export type {
|
|
29
|
+
ActorAccessor,
|
|
30
|
+
Client,
|
|
31
|
+
ClientOptions,
|
|
32
|
+
ClientRaw,
|
|
33
|
+
CreateOptions,
|
|
34
|
+
ExtractActorsFromRegistry,
|
|
35
|
+
ExtractRegistryFromClient,
|
|
36
|
+
GetOptions,
|
|
37
|
+
GetWithIdOptions,
|
|
38
|
+
QueryOptions,
|
|
39
|
+
Region,
|
|
40
|
+
} from "./client";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates a client with the actor accessor proxy.
|
|
44
|
+
*
|
|
45
|
+
* @template A The actor application type.
|
|
46
|
+
* @param {string} managerEndpoint - The manager endpoint.
|
|
47
|
+
* @param {ClientOptions} [opts] - Options for configuring the client.
|
|
48
|
+
* @returns {Client<A>} - A proxied client that supports the `client.myActor.connect()` syntax.
|
|
49
|
+
*/
|
|
50
|
+
export function createClient<A extends Registry<any>>(
|
|
51
|
+
endpoint: string,
|
|
52
|
+
opts?: ClientOptions,
|
|
53
|
+
): Client<A> {
|
|
54
|
+
const driver = createHttpClientDriver(endpoint);
|
|
55
|
+
return createClientWithDriver<A>(driver, opts);
|
|
56
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { ActorQuery } from "@/manager/protocol/query";
|
|
2
|
+
import type { ClientDriver } from "./client";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Shared implementation for raw HTTP fetch requests
|
|
6
|
+
*/
|
|
7
|
+
export async function rawHttpFetch(
|
|
8
|
+
driver: ClientDriver,
|
|
9
|
+
actorQuery: ActorQuery,
|
|
10
|
+
params: unknown,
|
|
11
|
+
input: string | URL | Request,
|
|
12
|
+
init?: RequestInit,
|
|
13
|
+
): Promise<Response> {
|
|
14
|
+
// Extract path and merge init options
|
|
15
|
+
let path: string;
|
|
16
|
+
let mergedInit: RequestInit = init || {};
|
|
17
|
+
|
|
18
|
+
if (typeof input === "string") {
|
|
19
|
+
path = input;
|
|
20
|
+
} else if (input instanceof URL) {
|
|
21
|
+
path = input.pathname + input.search;
|
|
22
|
+
} else if (input instanceof Request) {
|
|
23
|
+
// Extract path from Request URL
|
|
24
|
+
const url = new URL(input.url);
|
|
25
|
+
path = url.pathname + url.search;
|
|
26
|
+
// Merge Request properties with init
|
|
27
|
+
const requestHeaders = new Headers(input.headers);
|
|
28
|
+
const initHeaders = new Headers(init?.headers || {});
|
|
29
|
+
|
|
30
|
+
// Merge headers - init headers override request headers
|
|
31
|
+
const mergedHeaders = new Headers(requestHeaders);
|
|
32
|
+
for (const [key, value] of initHeaders) {
|
|
33
|
+
mergedHeaders.set(key, value);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
mergedInit = {
|
|
37
|
+
method: input.method,
|
|
38
|
+
body: input.body,
|
|
39
|
+
mode: input.mode,
|
|
40
|
+
credentials: input.credentials,
|
|
41
|
+
redirect: input.redirect,
|
|
42
|
+
referrer: input.referrer,
|
|
43
|
+
referrerPolicy: input.referrerPolicy,
|
|
44
|
+
integrity: input.integrity,
|
|
45
|
+
keepalive: input.keepalive,
|
|
46
|
+
signal: input.signal,
|
|
47
|
+
...mergedInit, // init overrides Request properties
|
|
48
|
+
headers: mergedHeaders, // headers must be set after spread to ensure proper merge
|
|
49
|
+
};
|
|
50
|
+
// Add duplex if body is present
|
|
51
|
+
if (mergedInit.body) {
|
|
52
|
+
(mergedInit as any).duplex = "half";
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
throw new TypeError("Invalid input type for fetch");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Use the driver's raw HTTP method - just pass the sub-path
|
|
59
|
+
return await driver.rawHttpRequest(
|
|
60
|
+
undefined,
|
|
61
|
+
actorQuery,
|
|
62
|
+
// Force JSON so it's readable by the user
|
|
63
|
+
"json",
|
|
64
|
+
params,
|
|
65
|
+
path,
|
|
66
|
+
mergedInit,
|
|
67
|
+
undefined,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Shared implementation for raw WebSocket connections
|
|
73
|
+
*/
|
|
74
|
+
export async function rawWebSocket(
|
|
75
|
+
driver: ClientDriver,
|
|
76
|
+
actorQuery: ActorQuery,
|
|
77
|
+
params: unknown,
|
|
78
|
+
path?: string,
|
|
79
|
+
protocols?: string | string[],
|
|
80
|
+
): Promise<any> {
|
|
81
|
+
// Use the driver's raw WebSocket method
|
|
82
|
+
return await driver.rawWebSocket(
|
|
83
|
+
undefined,
|
|
84
|
+
actorQuery,
|
|
85
|
+
// Force JSON so it's readable by the user
|
|
86
|
+
"json",
|
|
87
|
+
params,
|
|
88
|
+
path || "",
|
|
89
|
+
protocols,
|
|
90
|
+
undefined,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//import { exec as execCallback } from "node:child_process";
|
|
2
|
+
//import { setupLogging } from "@/common//log";
|
|
3
|
+
//import type { ClientOptions } from "./client";
|
|
4
|
+
//import { InternalError } from "./errors";
|
|
5
|
+
//import { Client } from "./mod.ts";
|
|
6
|
+
//
|
|
7
|
+
///**
|
|
8
|
+
// * Uses the Rivet CLI to read the manager endpoint to connect to. This allows
|
|
9
|
+
// * for writing tests that run locally without hardcoding the manager endpoint.
|
|
10
|
+
// */
|
|
11
|
+
//export async function readEndpointFromCli(): Promise<string> {
|
|
12
|
+
// // Read endpoint
|
|
13
|
+
// const cliPath = process.env.RIVET_CLI_PATH ?? "rivet";
|
|
14
|
+
//
|
|
15
|
+
// try {
|
|
16
|
+
// const { stdout, stderr } = await new Promise<{
|
|
17
|
+
// stdout: string;
|
|
18
|
+
// stderr: string;
|
|
19
|
+
// }>((resolve, reject) => {
|
|
20
|
+
// execCallback(`${cliPath} manager endpoint`, (error, stdout, stderr) => {
|
|
21
|
+
// if (error) reject(error);
|
|
22
|
+
// else resolve({ stdout, stderr });
|
|
23
|
+
// });
|
|
24
|
+
// });
|
|
25
|
+
//
|
|
26
|
+
// if (stderr) {
|
|
27
|
+
// throw new Error(stderr);
|
|
28
|
+
// }
|
|
29
|
+
//
|
|
30
|
+
// // Decode output
|
|
31
|
+
// return stdout.trim();
|
|
32
|
+
// } catch (error) {
|
|
33
|
+
// throw new InternalError(`Read endpoint failed: ${error}`);
|
|
34
|
+
// }
|
|
35
|
+
//}
|
|
36
|
+
//
|
|
37
|
+
//export class TestClient extends Client {
|
|
38
|
+
// public constructor(opts?: ClientOptions) {
|
|
39
|
+
// // Setup logging automatically
|
|
40
|
+
// setupLogging();
|
|
41
|
+
//
|
|
42
|
+
// super(readEndpointFromCli(), opts);
|
|
43
|
+
// }
|
|
44
|
+
//}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as cbor from "cbor-x";
|
|
2
|
+
import invariant from "invariant";
|
|
3
|
+
import { assertUnreachable } from "@/common/utils";
|
|
4
|
+
import type { VersionedDataHandler } from "@/common/versioned-data";
|
|
5
|
+
import type { Encoding } from "@/mod";
|
|
6
|
+
import type { HttpResponseError } from "@/schemas/client-protocol/mod";
|
|
7
|
+
import { HTTP_RESPONSE_ERROR_VERSIONED } from "@/schemas/client-protocol/versioned";
|
|
8
|
+
import {
|
|
9
|
+
contentTypeForEncoding,
|
|
10
|
+
deserializeWithEncoding,
|
|
11
|
+
serializeWithEncoding,
|
|
12
|
+
} from "@/serde";
|
|
13
|
+
import { httpUserAgent } from "@/utils";
|
|
14
|
+
import { ActorError, HttpRequestError } from "./errors";
|
|
15
|
+
import { logger } from "./log";
|
|
16
|
+
|
|
17
|
+
export type WebSocketMessage = string | Blob | ArrayBuffer | Uint8Array;
|
|
18
|
+
|
|
19
|
+
export function messageLength(message: WebSocketMessage): number {
|
|
20
|
+
if (message instanceof Blob) {
|
|
21
|
+
return message.size;
|
|
22
|
+
}
|
|
23
|
+
if (message instanceof ArrayBuffer) {
|
|
24
|
+
return message.byteLength;
|
|
25
|
+
}
|
|
26
|
+
if (message instanceof Uint8Array) {
|
|
27
|
+
return message.byteLength;
|
|
28
|
+
}
|
|
29
|
+
if (typeof message === "string") {
|
|
30
|
+
return message.length;
|
|
31
|
+
}
|
|
32
|
+
assertUnreachable(message);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface HttpRequestOpts<RequestBody, ResponseBody> {
|
|
36
|
+
method: string;
|
|
37
|
+
url: string;
|
|
38
|
+
headers: Record<string, string>;
|
|
39
|
+
body?: RequestBody;
|
|
40
|
+
encoding: Encoding;
|
|
41
|
+
skipParseResponse?: boolean;
|
|
42
|
+
signal?: AbortSignal;
|
|
43
|
+
customFetch?: (req: Request) => Promise<Response>;
|
|
44
|
+
requestVersionedDataHandler: VersionedDataHandler<RequestBody>;
|
|
45
|
+
responseVersionedDataHandler: VersionedDataHandler<ResponseBody>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function sendHttpRequest<
|
|
49
|
+
RequestBody = unknown,
|
|
50
|
+
ResponseBody = unknown,
|
|
51
|
+
>(opts: HttpRequestOpts<RequestBody, ResponseBody>): Promise<ResponseBody> {
|
|
52
|
+
logger().debug("sending http request", {
|
|
53
|
+
url: opts.url,
|
|
54
|
+
encoding: opts.encoding,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Serialize body
|
|
58
|
+
let contentType: string | undefined;
|
|
59
|
+
let bodyData: string | Uint8Array | undefined;
|
|
60
|
+
if (opts.method === "POST" || opts.method === "PUT") {
|
|
61
|
+
invariant(opts.body !== undefined, "missing body");
|
|
62
|
+
contentType = contentTypeForEncoding(opts.encoding);
|
|
63
|
+
bodyData = serializeWithEncoding<RequestBody>(
|
|
64
|
+
opts.encoding,
|
|
65
|
+
opts.body,
|
|
66
|
+
opts.requestVersionedDataHandler,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Send request
|
|
71
|
+
let response: Response;
|
|
72
|
+
try {
|
|
73
|
+
// Make the HTTP request
|
|
74
|
+
response = await (opts.customFetch ?? fetch)(
|
|
75
|
+
new Request(opts.url, {
|
|
76
|
+
method: opts.method,
|
|
77
|
+
headers: {
|
|
78
|
+
...opts.headers,
|
|
79
|
+
...(contentType
|
|
80
|
+
? {
|
|
81
|
+
"Content-Type": contentType,
|
|
82
|
+
}
|
|
83
|
+
: {}),
|
|
84
|
+
"User-Agent": httpUserAgent(),
|
|
85
|
+
},
|
|
86
|
+
body: bodyData,
|
|
87
|
+
credentials: "include",
|
|
88
|
+
signal: opts.signal,
|
|
89
|
+
}),
|
|
90
|
+
);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
throw new HttpRequestError(`Request failed: ${error}`, {
|
|
93
|
+
cause: error,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Parse response error
|
|
98
|
+
if (!response.ok) {
|
|
99
|
+
// Attempt to parse structured data
|
|
100
|
+
const bufferResponse = await response.arrayBuffer();
|
|
101
|
+
let responseData: HttpResponseError;
|
|
102
|
+
try {
|
|
103
|
+
responseData = deserializeWithEncoding(
|
|
104
|
+
opts.encoding,
|
|
105
|
+
new Uint8Array(bufferResponse),
|
|
106
|
+
HTTP_RESPONSE_ERROR_VERSIONED,
|
|
107
|
+
);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
//logger().warn("failed to cleanly parse error, this is likely because a non-structured response is being served", {
|
|
110
|
+
// error: stringifyError(error),
|
|
111
|
+
//});
|
|
112
|
+
|
|
113
|
+
// Error is not structured
|
|
114
|
+
const textResponse = new TextDecoder("utf-8", { fatal: false }).decode(
|
|
115
|
+
bufferResponse,
|
|
116
|
+
);
|
|
117
|
+
throw new HttpRequestError(
|
|
118
|
+
`${response.statusText} (${response.status}):\n${textResponse}`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Throw structured error
|
|
123
|
+
throw new ActorError(
|
|
124
|
+
responseData.code,
|
|
125
|
+
responseData.message,
|
|
126
|
+
responseData.metadata
|
|
127
|
+
? cbor.decode(new Uint8Array(responseData.metadata))
|
|
128
|
+
: undefined,
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Some requests don't need the success response to be parsed, so this can speed things up
|
|
133
|
+
if (opts.skipParseResponse) {
|
|
134
|
+
return undefined as ResponseBody;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Parse the response based on encoding
|
|
138
|
+
try {
|
|
139
|
+
const buffer = new Uint8Array(await response.arrayBuffer());
|
|
140
|
+
return deserializeWithEncoding(
|
|
141
|
+
opts.encoding,
|
|
142
|
+
buffer,
|
|
143
|
+
opts.responseVersionedDataHandler,
|
|
144
|
+
);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
throw new HttpRequestError(`Failed to parse response: ${error}`, {
|
|
147
|
+
cause: error,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|