Skip to content

Commit 85b3605

Browse files
committed
Move the stream subscription stuff to the API client, expose it through runs.fetchStream
1 parent 01c2ca9 commit 85b3605

File tree

4 files changed

+38
-94
lines changed

4 files changed

+38
-94
lines changed

packages/core/src/v3/apiClient/index.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
RunSubscription,
5151
TaskRunShape,
5252
runShapeStream,
53+
SSEStreamSubscriptionFactory,
5354
} from "./runStream.js";
5455
import {
5556
CreateEnvironmentVariableParams,
@@ -681,6 +682,23 @@ export class ApiClient {
681682
});
682683
}
683684

685+
async fetchStream<T>(
686+
runId: string,
687+
streamKey: string,
688+
options?: { signal?: AbortSignal; baseUrl?: string }
689+
): Promise<AsyncIterableStream<T>> {
690+
const streamFactory = new SSEStreamSubscriptionFactory(options?.baseUrl ?? this.baseUrl, {
691+
headers: this.getHeaders(),
692+
signal: options?.signal,
693+
});
694+
695+
const subscription = streamFactory.createSubscription(runId, streamKey);
696+
697+
const stream = await subscription.subscribe();
698+
699+
return stream as AsyncIterableStream<T>;
700+
}
701+
684702
async generateJWTClaims(requestOptions?: ZodFetchOptions): Promise<Record<string, any>> {
685703
return zodfetch(
686704
z.record(z.any()),

packages/core/src/v3/apiClient/runStream.ts

Lines changed: 4 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,7 @@ export function runShapeStream<TRunTypes extends AnyRunTypes>(
8989
): RunSubscription<TRunTypes> {
9090
const abortController = new AbortController();
9191

92-
const version1 = new SSEStreamSubscriptionFactory(
93-
getEnvVar("TRIGGER_STREAM_URL", getEnvVar("TRIGGER_API_URL")) ?? "https://api.trigger.dev",
94-
{
95-
headers: options?.headers,
96-
signal: abortController.signal,
97-
}
98-
);
99-
100-
const version2 = new ElectricStreamSubscriptionFactory(
92+
const streamFactory = new SSEStreamSubscriptionFactory(
10193
getEnvVar("TRIGGER_STREAM_URL", getEnvVar("TRIGGER_API_URL")) ?? "https://api.trigger.dev",
10294
{
10395
headers: options?.headers,
@@ -124,7 +116,7 @@ export function runShapeStream<TRunTypes extends AnyRunTypes>(
124116
const $options: RunSubscriptionOptions = {
125117
runShapeStream: runStreamInstance.stream,
126118
stopRunShapeStream: () => runStreamInstance.stop(30 * 1000),
127-
streamFactory: new VersionedStreamSubscriptionFactory(version1, version2),
119+
streamFactory: streamFactory,
128120
abortController,
129121
...options,
130122
};
@@ -138,12 +130,7 @@ export interface StreamSubscription {
138130
}
139131

140132
export interface StreamSubscriptionFactory {
141-
createSubscription(
142-
metadata: Record<string, unknown>,
143-
runId: string,
144-
streamKey: string,
145-
baseUrl?: string
146-
): StreamSubscription;
133+
createSubscription(runId: string, streamKey: string, baseUrl?: string): StreamSubscription;
147134
}
148135

149136
// Real implementation for production
@@ -194,12 +181,7 @@ export class SSEStreamSubscriptionFactory implements StreamSubscriptionFactory {
194181
private options: { headers?: Record<string, string>; signal?: AbortSignal }
195182
) {}
196183

197-
createSubscription(
198-
metadata: Record<string, unknown>,
199-
runId: string,
200-
streamKey: string,
201-
baseUrl?: string
202-
): StreamSubscription {
184+
createSubscription(runId: string, streamKey: string, baseUrl?: string): StreamSubscription {
203185
if (!runId || !streamKey) {
204186
throw new Error("runId and streamKey are required");
205187
}
@@ -238,63 +220,6 @@ export class ElectricStreamSubscription implements StreamSubscription {
238220
}
239221
}
240222

241-
export class ElectricStreamSubscriptionFactory implements StreamSubscriptionFactory {
242-
constructor(
243-
private baseUrl: string,
244-
private options: { headers?: Record<string, string>; signal?: AbortSignal }
245-
) {}
246-
247-
createSubscription(
248-
metadata: Record<string, unknown>,
249-
runId: string,
250-
streamKey: string,
251-
baseUrl?: string
252-
): StreamSubscription {
253-
if (!runId || !streamKey) {
254-
throw new Error("runId and streamKey are required");
255-
}
256-
257-
return new ElectricStreamSubscription(
258-
`${baseUrl ?? this.baseUrl}/realtime/v2/streams/${runId}/${streamKey}`,
259-
this.options
260-
);
261-
}
262-
}
263-
264-
export class VersionedStreamSubscriptionFactory implements StreamSubscriptionFactory {
265-
constructor(
266-
private version1: StreamSubscriptionFactory,
267-
private version2: StreamSubscriptionFactory
268-
) {}
269-
270-
createSubscription(
271-
metadata: Record<string, unknown>,
272-
runId: string,
273-
streamKey: string,
274-
baseUrl?: string
275-
): StreamSubscription {
276-
if (!runId || !streamKey) {
277-
throw new Error("runId and streamKey are required");
278-
}
279-
280-
const version =
281-
typeof metadata.$$streamsVersion === "string" ? metadata.$$streamsVersion : "v1";
282-
283-
const $baseUrl =
284-
typeof metadata.$$streamsBaseUrl === "string" ? metadata.$$streamsBaseUrl : baseUrl;
285-
286-
if (version === "v1") {
287-
return this.version1.createSubscription(metadata, runId, streamKey, $baseUrl);
288-
}
289-
290-
if (version === "v2") {
291-
return this.version2.createSubscription(metadata, runId, streamKey, $baseUrl);
292-
}
293-
294-
throw new Error(`Unknown stream version: ${version}`);
295-
}
296-
}
297-
298223
export interface RunShapeProvider {
299224
onShape(callback: (shape: SubscribeRunRawShape) => Promise<void>): Promise<() => void>;
300225
}
@@ -385,7 +310,6 @@ export class RunSubscription<TRunTypes extends AnyRunTypes> {
385310
activeStreams.add(streamKey);
386311

387312
const subscription = this.options.streamFactory.createSubscription(
388-
run.metadata,
389313
run.id,
390314
streamKey,
391315
this.options.client?.baseUrl

packages/core/src/v3/runMetadata/manager.ts

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import { JSONHeroPath } from "@jsonhero/path";
21
import { dequal } from "dequal/lite";
32
import { DeserializedJson } from "../../schemas/json.js";
4-
import { ApiRequestOptions } from "../zodfetch.js";
5-
import { RunMetadataManager, RunMetadataUpdater } from "./types.js";
6-
import { MetadataStream } from "./metadataStream.js";
73
import { ApiClient } from "../apiClient/index.js";
4+
import { AsyncIterableStream } from "../apiClient/stream.js";
85
import { FlushedRunMetadata, RunMetadataChangeOperation } from "../schemas/common.js";
6+
import { ApiRequestOptions } from "../zodfetch.js";
7+
import { MetadataStream } from "./metadataStream.js";
98
import { applyMetadataOperations } from "./operations.js";
10-
import { SSEStreamSubscriptionFactory } from "../apiClient/runStream.js";
11-
import { AsyncIterableStream } from "../apiClient/stream.js";
9+
import { RunMetadataManager, RunMetadataUpdater } from "./types.js";
1210

1311
const MAXIMUM_ACTIVE_STREAMS = 5;
1412
const MAXIMUM_TOTAL_STREAMS = 10;
@@ -208,14 +206,7 @@ export class StandardMetadataManager implements RunMetadataManager {
208206

209207
const $baseUrl = typeof baseUrl === "string" ? baseUrl : this.streamsBaseUrl;
210208

211-
const streamFactory = new SSEStreamSubscriptionFactory($baseUrl, {
212-
headers: this.apiClient.getHeaders(),
213-
signal,
214-
});
215-
216-
const subscription = streamFactory.createSubscription(this.store ?? {}, this.runId, key);
217-
218-
return (await subscription.subscribe()) as AsyncIterableStream<T>;
209+
return this.apiClient.fetchStream<T>(this.runId, key, { baseUrl: $baseUrl, signal });
219210
}
220211

221212
private async doStream<T>(

packages/trigger-sdk/src/v3/runs.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {
1313
RunSubscription,
1414
TaskRunShape,
1515
AnyBatchedRunHandle,
16+
AsyncIterableStream,
1617
} from "@trigger.dev/core/v3";
1718
import {
1819
ApiPromise,
@@ -51,6 +52,7 @@ export const runs = {
5152
subscribeToRun,
5253
subscribeToRunsWithTag,
5354
subscribeToBatch: subscribeToRunsInBatch,
55+
fetchStream,
5456
};
5557

5658
export type ListRunsItem = ListRunResponseItem;
@@ -465,3 +467,12 @@ function subscribeToRunsInBatch<TTasks extends AnyTask>(
465467

466468
return apiClient.subscribeToBatch<InferRunTypes<TTasks>>(batchId);
467469
}
470+
471+
/**
472+
* Fetches a stream of data from a run's stream key.
473+
*/
474+
async function fetchStream<T>(runId: string, streamKey: string): Promise<AsyncIterableStream<T>> {
475+
const apiClient = apiClientManager.clientOrThrow();
476+
477+
return await apiClient.fetchStream(runId, streamKey);
478+
}

0 commit comments

Comments
 (0)