|
1 | | -import { type ActionFunctionArgs } from "@remix-run/server-runtime"; |
2 | 1 | import { z } from "zod"; |
3 | 2 | import { $replica } from "~/db.server"; |
4 | 3 | import { getRequestAbortSignal } from "~/services/httpAsyncStorage.server"; |
5 | 4 | import { getRealtimeStreamInstance } from "~/services/realtime/v1StreamsGlobal.server"; |
6 | 5 | import { anyResource, createLoaderApiRoute } from "~/services/routeBuilders/apiBuilder.server"; |
7 | 6 | import { runStore } from "~/v3/runStore.server"; |
8 | | -import { controlPlaneResolver } from "~/v3/runOpsMigration/controlPlaneResolver.server"; |
9 | 7 |
|
10 | 8 | const ParamsSchema = z.object({ |
11 | 9 | runId: z.string(), |
12 | 10 | streamId: z.string(), |
13 | 11 | }); |
14 | 12 |
|
15 | | -// Plain action for backwards compatibility with older clients that don't send auth headers |
16 | | -export async function action({ request, params }: ActionFunctionArgs) { |
17 | | - const parsedParams = ParamsSchema.safeParse(params); |
18 | | - |
19 | | - if (!parsedParams.success) { |
20 | | - return new Response("Invalid parameters", { status: 400 }); |
21 | | - } |
22 | | - |
23 | | - const { runId, streamId } = parsedParams.data; |
24 | | - |
25 | | - // Look up the run without environment scoping for backwards compatibility |
26 | | - const run = await runStore.findRun( |
27 | | - { |
28 | | - friendlyId: runId, |
29 | | - }, |
30 | | - { |
31 | | - select: { |
32 | | - id: true, |
33 | | - friendlyId: true, |
34 | | - streamBasinName: true, |
35 | | - runtimeEnvironmentId: true, |
36 | | - }, |
37 | | - }, |
38 | | - $replica |
39 | | - ); |
40 | | - |
41 | | - if (!run) { |
42 | | - return new Response("Run not found", { status: 404 }); |
43 | | - } |
44 | | - |
45 | | - const environment = await controlPlaneResolver.resolveAuthenticatedEnv(run.runtimeEnvironmentId); |
46 | | - |
47 | | - if (!environment) { |
48 | | - return new Response("Run not found", { status: 404 }); |
49 | | - } |
50 | | - |
51 | | - // Extract client ID from header, default to "default" if not provided |
52 | | - const clientId = request.headers.get("X-Client-Id") || "default"; |
53 | | - const streamVersion = request.headers.get("X-Stream-Version") || "v1"; |
54 | | - |
55 | | - if (!request.body) { |
56 | | - return new Response("No body provided", { status: 400 }); |
57 | | - } |
58 | | - |
59 | | - const resumeFromChunk = request.headers.get("X-Resume-From-Chunk"); |
60 | | - let resumeFromChunkNumber: number | undefined = undefined; |
61 | | - if (resumeFromChunk) { |
62 | | - const parsed = parseInt(resumeFromChunk, 10); |
63 | | - if (isNaN(parsed) || parsed < 0) { |
64 | | - return new Response(`Invalid X-Resume-From-Chunk header value: ${resumeFromChunk}`, { |
65 | | - status: 400, |
66 | | - }); |
67 | | - } |
68 | | - resumeFromChunkNumber = parsed; |
69 | | - } |
70 | | - |
71 | | - const realtimeStream = getRealtimeStreamInstance(environment, streamVersion, { |
72 | | - run, |
73 | | - }); |
74 | | - |
75 | | - return realtimeStream.ingestData( |
76 | | - request.body, |
77 | | - run.friendlyId, |
78 | | - streamId, |
79 | | - clientId, |
80 | | - resumeFromChunkNumber |
81 | | - ); |
82 | | -} |
83 | | - |
84 | 13 | export const loader = createLoaderApiRoute( |
85 | 14 | { |
86 | 15 | params: ParamsSchema, |
|
0 commit comments