chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:32:57 +08:00
commit cd420f9332
4811 changed files with 884702 additions and 0 deletions
+717
View File
@@ -0,0 +1,717 @@
# @trigger.dev/react-hooks
## 4.5.3
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.3`
## 4.5.2
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.2`
## 4.5.1
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.1`
## 4.5.0
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.0`
## 4.5.0-rc.7
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.0-rc.7`
## 4.5.0-rc.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.0-rc.6`
## 4.5.0-rc.5
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.0-rc.5`
## 4.5.0-rc.4
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.0-rc.4`
## 4.5.0-rc.3
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.0-rc.3`
## 4.5.0-rc.2
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.0-rc.2`
## 4.5.0-rc.1
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.0-rc.1`
## 4.5.0-rc.0
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.5.0-rc.0`
## 4.4.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.6`
## 4.4.5
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.5`
## 4.4.4
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.4`
## 4.4.3
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.3`
## 4.4.2
### Patch Changes
- Add input streams for bidirectional communication with running tasks. Define typed input streams with `streams.input<T>({ id })`, then consume inside tasks via `.wait()` (suspends the process), `.once()` (waits for next message), or `.on()` (subscribes to a continuous stream). Send data from backends with `.send(runId, data)` or from frontends with the new `useInputStreamSend` React hook. ([#3146](https://github.com/triggerdotdev/trigger.dev/pull/3146))
Upgrade S2 SDK from 0.17 to 0.22 with support for custom endpoints (s2-lite) via the new `endpoints` configuration, `AppendRecord.string()` API, and `maxInflightBytes` session option.
- Updated dependencies:
- `@trigger.dev/core@4.4.2`
## 4.4.1
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.4.1`
## 4.4.0
### Patch Changes
- Fix `onComplete` callback firing prematurely when the realtime stream disconnects before the run finishes. ([#2929](https://github.com/triggerdotdev/trigger.dev/pull/2929))
- Updated dependencies:
- `@trigger.dev/core@4.4.0`
## 4.3.3
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.3.3`
## 4.3.2
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.3.2`
## 4.3.1
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.3.1`
## 4.3.0
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.3.0`
## 4.2.0
### Patch Changes
- fix: prevent infinite useEffect when passing an array of tags to useRealtimeRunsWithTag ([#2705](https://github.com/triggerdotdev/trigger.dev/pull/2705))
- Updated dependencies:
- `@trigger.dev/core@4.2.0`
## 4.1.2
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.1.2`
## 4.1.1
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.1.1`
## 4.1.0
### Minor Changes
- Realtime streams v2 ([#2632](https://github.com/triggerdotdev/trigger.dev/pull/2632))
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.1.0`
## 4.0.7
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.7`
## 4.0.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.6`
## 4.0.5
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.5`
## 4.0.4
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.4`
## 4.0.3
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.3`
## 4.0.2
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.2`
## 4.0.1
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.1`
## 4.0.0
### Major Changes
- Trigger.dev v4 release. Please see our upgrade to v4 docs to view the full changelog: https://trigger.dev/docs/upgrade-to-v4 ([#1869](https://github.com/triggerdotdev/trigger.dev/pull/1869))
### Patch Changes
- Run Engine 2.0 (alpha) ([#1575](https://github.com/triggerdotdev/trigger.dev/pull/1575))
- Added the ability to specify a "createdAt" filter when subscribing to tags in our useRealtime hooks: ([#2158](https://github.com/triggerdotdev/trigger.dev/pull/2158))
```tsx
// Only subscribe to runs created in the last 10 hours
useRealtimeRunWithTags("my-tag", { createdAt: "10h" });
```
You can also now choose to skip subscribing to specific columns by specifying the `skipColumns` option:
```tsx
useRealtimeRun(run.id, { skipColumns: ["usageDurationMs"] });
```
- Fixes an issue with realtime when re-subscribing to a run, that would temporarily display stale data and the changes. Now when re-subscribing to a run only the latest changes will be vended ([#2162](https://github.com/triggerdotdev/trigger.dev/pull/2162))
- Updated dependencies:
- `@trigger.dev/core@4.0.0`
## 4.0.0-v4-beta.28
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.28`
## 4.0.0-v4-beta.27
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.27`
## 4.0.0-v4-beta.26
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.26`
## 4.0.0-v4-beta.25
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.25`
## 4.0.0-v4-beta.24
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.24`
## 4.0.0-v4-beta.23
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.23`
## 4.0.0-v4-beta.22
### Patch Changes
- Added the ability to specify a "createdAt" filter when subscribing to tags in our useRealtime hooks: ([#2158](https://github.com/triggerdotdev/trigger.dev/pull/2158))
```tsx
// Only subscribe to runs created in the last 10 hours
useRealtimeRunWithTags("my-tag", { createdAt: "10h" });
```
You can also now choose to skip subscribing to specific columns by specifying the `skipColumns` option:
```tsx
useRealtimeRun(run.id, { skipColumns: ["usageDurationMs"] });
```
- Fixes an issue with realtime when re-subscribing to a run, that would temporarily display stale data and the changes. Now when re-subscribing to a run only the latest changes will be vended ([#2162](https://github.com/triggerdotdev/trigger.dev/pull/2162))
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.22`
## 4.0.0-v4-beta.21
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.21`
## 4.0.0-v4-beta.20
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.20`
## 4.0.0-v4-beta.19
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.19`
## 4.0.0-v4-beta.18
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.18`
## 4.0.0-v4-beta.17
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.17`
## 4.0.0-v4-beta.16
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.16`
## 4.0.0-v4-beta.15
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.15`
## 4.0.0-v4-beta.14
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.14`
## 4.0.0-v4-beta.13
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.13`
## 4.0.0-v4-beta.12
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.12`
## 4.0.0-v4-beta.11
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.11`
## 4.0.0-v4-beta.10
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.10`
## 4.0.0-v4-beta.9
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.9`
## 4.0.0-v4-beta.8
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.8`
## 4.0.0-v4-beta.7
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.7`
## 4.0.0-v4-beta.6
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.6`
## 4.0.0-v4-beta.5
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.5`
## 4.0.0-v4-beta.4
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.4`
## 4.0.0-v4-beta.3
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.3`
## 4.0.0-v4-beta.2
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.2`
## 4.0.0-v4-beta.1
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.1`
## 4.0.0-v4-beta.0
### Major Changes
- Trigger.dev v4 release. Please see our upgrade to v4 docs to view the full changelog: https://trigger.dev/docs/upgrade-to-v4 ([#1869](https://github.com/triggerdotdev/trigger.dev/pull/1869))
### Patch Changes
- Run Engine 2.0 (alpha) ([#1575](https://github.com/triggerdotdev/trigger.dev/pull/1575))
- Updated dependencies:
- `@trigger.dev/core@4.0.0-v4-beta.0`
## 3.3.17
### Patch Changes
- Add support for two-phase deployments and task version pinning ([#1739](https://github.com/triggerdotdev/trigger.dev/pull/1739))
- Updated dependencies:
- `@trigger.dev/core@3.3.17`
## 3.3.16
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.16`
## 3.3.15
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.15`
## 3.3.14
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.14`
## 3.3.13
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.13`
## 3.3.12
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.12`
## 3.3.11
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.11`
## 3.3.10
### Patch Changes
- Make sure useRealtimeRun onComplete hook fires at the correct time ([#1599](https://github.com/triggerdotdev/trigger.dev/pull/1599))
- Handle errors thrown by requests in Realtime react hooks ([#1599](https://github.com/triggerdotdev/trigger.dev/pull/1599))
- Updated dependencies:
- `@trigger.dev/core@3.3.10`
## 3.3.9
### Patch Changes
- Adding ability to update parent run metadata from child runs/tasks ([#1563](https://github.com/triggerdotdev/trigger.dev/pull/1563))
- Updated dependencies:
- `@trigger.dev/core@3.3.9`
## 3.3.8
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.8`
## 3.3.7
### Patch Changes
- Now compatible with React 19 ([#1559](https://github.com/triggerdotdev/trigger.dev/pull/1559))
- - Fixes an issue in streams where "chunks" could get split across multiple reads ([#1549](https://github.com/triggerdotdev/trigger.dev/pull/1549))
- Fixed stopping the run subscription after a run is finished, when using useRealtimeRun or useRealtimeRunWithStreams
- Added an `onComplete` callback to `useRealtimeRun` and `useRealtimeRunWithStreams`
- Optimized the run subscription to reduce unnecessary updates
- Updated dependencies:
- `@trigger.dev/core@3.3.7`
## 3.3.6
### Patch Changes
- Realtime streams now powered by electric. Also, this change fixes a realtime bug that was causing too many re-renders, even on records that didn't change ([#1541](https://github.com/triggerdotdev/trigger.dev/pull/1541))
- Updated dependencies:
- `@trigger.dev/core@3.3.6`
## 3.3.5
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.5`
## 3.3.4
### Patch Changes
- Add trigger options to all trigger hooks ([#1528](https://github.com/triggerdotdev/trigger.dev/pull/1528))
- Updated dependencies:
- `@trigger.dev/core@3.3.4`
## 3.3.3
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.3`
## 3.3.2
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.3.2`
## 3.3.1
### Patch Changes
- Public access token scopes with just tags or just a batch can now access runs that have those tags or are in the batch. Previously, the only way to access a run was to have a specific scope for that exact run. ([#1511](https://github.com/triggerdotdev/trigger.dev/pull/1511))
- Updated dependencies:
- `@trigger.dev/core@3.3.1`
## 3.3.0
### Minor Changes
- Improved Batch Triggering: ([#1502](https://github.com/triggerdotdev/trigger.dev/pull/1502))
- The new Batch Trigger endpoint is now asynchronous and supports up to 500 runs per request.
- The new endpoint also supports triggering multiple different tasks in a single batch request (support in the SDK coming soon).
- The existing `batchTrigger` method now supports the new endpoint, and shouldn't require any changes to your code.
- Idempotency keys now expire after 24 hours, and you can customize the expiration time when creating a new key by using the `idempotencyKeyTTL` parameter:
```ts
await myTask.batchTrigger([{ payload: { foo: "bar" } }], {
idempotencyKey: "my-key",
idempotencyKeyTTL: "60s",
});
// Works for individual items as well:
await myTask.batchTrigger([
{
payload: { foo: "bar" },
options: { idempotencyKey: "my-key", idempotencyKeyTTL: "60s" },
},
]);
// And `trigger`:
await myTask.trigger(
{ foo: "bar" },
{ idempotencyKey: "my-key", idempotencyKeyTTL: "60s" },
);
```
### Breaking Changes
- We've removed the `idempotencyKey` option from `triggerAndWait` and `batchTriggerAndWait`, because it can lead to permanently frozen runs in deployed tasks. We're working on upgrading our entire system to support idempotency keys on these methods, and we'll re-add the option once that's complete.
### Patch Changes
- Added ability to subscribe to a batch of runs using runs.subscribeToBatch ([#1502](https://github.com/triggerdotdev/trigger.dev/pull/1502))
- Updated dependencies:
- `@trigger.dev/core@3.3.0`
## 3.2.2
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.2.2`
## 3.2.1
### Patch Changes
- React hooks now all accept accessToken and baseURL options so the use of the Provider is no longer necessary ([#1486](https://github.com/triggerdotdev/trigger.dev/pull/1486))
- Upgrade zod to latest (3.23.8) ([#1484](https://github.com/triggerdotdev/trigger.dev/pull/1484))
- Realtime streams ([#1470](https://github.com/triggerdotdev/trigger.dev/pull/1470))
- Updated dependencies:
- `@trigger.dev/core@3.2.1`
## 3.2.0
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.2.0`
## 3.1.2
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.1.2`
## 3.1.1
### Patch Changes
- useBatch renamed to useRealtimeBatch ([#1447](https://github.com/triggerdotdev/trigger.dev/pull/1447))
- Updated dependencies:
- `@trigger.dev/core@3.1.1`
## 3.1.0
### Minor Changes
- Access run status updates in realtime, from your server or from your frontend ([#1402](https://github.com/triggerdotdev/trigger.dev/pull/1402))
### Patch Changes
- Updated dependencies:
- `@trigger.dev/core@3.1.0`
+1
View File
@@ -0,0 +1 @@
## trigger.dev react hooks
+75
View File
@@ -0,0 +1,75 @@
{
"name": "@trigger.dev/react-hooks",
"version": "4.5.3",
"description": "trigger.dev react hooks",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/triggerdotdev/trigger.dev",
"directory": "packages/react-hooks"
},
"type": "module",
"files": [
"dist"
],
"tshy": {
"selfLink": false,
"main": true,
"module": true,
"project": "./tsconfig.json",
"exports": {
"./package.json": "./package.json",
".": "./src/index.ts"
},
"sourceDialects": [
"@triggerdotdev/source"
]
},
"scripts": {
"clean": "rimraf dist .tshy .tshy-build .turbo",
"build": "tshy && pnpm run update-version",
"dev": "tshy --watch",
"typecheck": "tsc --noEmit",
"update-version": "tsx ../../scripts/updateVersion.ts",
"check-exports": "attw --pack ."
},
"dependencies": {
"@trigger.dev/core": "workspace:^4.5.3",
"swr": "^2.2.5"
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.15.4",
"@types/react": "*",
"@types/react-dom": "*",
"rimraf": "^6.0.1",
"tshy": "^3.0.2",
"tsx": "4.17.0"
},
"peerDependencies": {
"react": "^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^18.0 || ^19.0 || ^19.0.0-rc"
},
"engines": {
"node": ">=18.20.0"
},
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"@triggerdotdev/source": "./src/index.ts",
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"types": "./dist/commonjs/index.d.ts",
"default": "./dist/commonjs/index.js"
}
}
},
"main": "./dist/commonjs/index.js",
"types": "./dist/commonjs/index.d.ts",
"module": "./dist/esm/index.js"
}
+10
View File
@@ -0,0 +1,10 @@
"use client";
import React from "react";
import { createContextAndHook } from "./utils/createContextAndHook.js";
import type { ApiClientConfiguration } from "@trigger.dev/core/v3";
const [TriggerAuthContext, useTriggerAuthContext, useTriggerAuthContextOptional] =
createContextAndHook<ApiClientConfiguration>("TriggerAuthContext");
export { TriggerAuthContext, useTriggerAuthContext, useTriggerAuthContextOptional };
@@ -0,0 +1,68 @@
"use client";
import type { ApiRequestOptions } from "@trigger.dev/core/v3";
import { ApiClient } from "@trigger.dev/core/v3";
import { useTriggerAuthContextOptional } from "../contexts.js";
/**
* Configuration options for creating an API client instance.
*/
export type UseApiClientOptions = {
/** Optional access token for authentication */
accessToken?: string;
/** Optional base URL for the API endpoints */
baseURL?: string;
/** Optional preview branch name for preview environments */
previewBranch?: string;
/** Optional additional request configuration */
requestOptions?: ApiRequestOptions;
/**
* Enable or disable the API client instance.
*
* Set enabled to false if you don't have an accessToken and don't want to throw an error.
*/
enabled?: boolean;
};
/**
* Hook to create an API client instance using authentication context or provided options.
*
* @param {UseApiClientOptions} [options] - Configuration options for the API client
* @returns {ApiClient} An initialized API client instance
* @throws {Error} When no access token is available in either context or options
*
* @example
* ```ts
* // Using context authentication
* const apiClient = useApiClient();
*
* // Using custom options
* const apiClient = useApiClient({
* accessToken: "your-access-token",
* baseURL: "https://api.my-trigger.com",
* requestOptions: { retry: { maxAttempts: 10 } }
* });
* ```
*/
export function useApiClient(options?: UseApiClientOptions): ApiClient | undefined {
const auth = useTriggerAuthContextOptional();
const baseUrl = options?.baseURL ?? auth?.baseURL ?? "https://api.trigger.dev";
const accessToken = options?.accessToken ?? auth?.accessToken;
const previewBranch = options?.previewBranch ?? auth?.previewBranch;
if (!accessToken) {
if (options?.enabled === false) {
return undefined;
}
throw new Error("Missing accessToken in TriggerAuthContext or useApiClient options");
}
const requestOptions: ApiRequestOptions = {
...auth?.requestOptions,
...options?.requestOptions,
};
return new ApiClient(baseUrl, accessToken, previewBranch, requestOptions);
}
@@ -0,0 +1,61 @@
"use client";
import useSWRMutation from "swr/mutation";
import type { UseApiClientOptions } from "./useApiClient.js";
import { useApiClient } from "./useApiClient.js";
export interface InputStreamSendInstance<TData> {
/** Send data to the input stream */
send: (data: TData) => void;
/** Whether a send is currently in progress */
isLoading: boolean;
/** Any error that occurred during the last send */
error?: Error;
/** Whether the hook is ready to send (has runId and access token) */
isReady: boolean;
}
/**
* Hook to send data to an input stream on a running task.
*
* @template TData - The type of data to send
* @param streamId - The input stream identifier
* @param runId - The run to send input stream data to
* @param options - API client options (e.g. accessToken)
*
* @example
* ```tsx
* const { send, isLoading } = useInputStreamSend("my-stream", runId, { accessToken });
* send({ message: "hello" });
* ```
*/
export function useInputStreamSend<TData>(
streamId: string,
runId?: string,
options?: UseApiClientOptions
): InputStreamSendInstance<TData> {
const apiClient = useApiClient(options);
async function sendToStream(key: string, { arg }: { arg: { data: TData } }) {
if (!apiClient) {
throw new Error("Could not send to input stream: Missing access token");
}
if (!runId) {
throw new Error("Could not send to input stream: Missing run ID");
}
return await apiClient.sendInputStream(runId, streamId, arg.data);
}
const mutation = useSWRMutation(runId ? `input-stream:${runId}:${streamId}` : null, sendToStream);
return {
send: (data) => {
mutation.trigger({ data });
},
isLoading: mutation.isMutating,
isReady: !!runId && !!apiClient,
error: mutation.error,
};
}
File diff suppressed because it is too large Load Diff
+60
View File
@@ -0,0 +1,60 @@
"use client";
import type { AnyTask, RetrieveRunResult } from "@trigger.dev/core/v3";
import type { CommonTriggerHookOptions } from "../utils/trigger-swr.js";
import { useSWR } from "../utils/trigger-swr.js";
import { useApiClient } from "./useApiClient.js";
/**
* Custom hook to retrieve and manage the state of a run by its ID.
*
* @template TTask - The type of the task associated with the run.
* @param {string} runId - The unique identifier of the run to retrieve.
* @param {CommonTriggerHookOptions} [options] - Optional configuration for the hook's behavior.
* @returns {Object} An object containing the run data, error, loading state, validation state, and error state.
* @returns {RetrieveRunResult<TTask> | undefined} run - The retrieved run data.
* @returns {Error | undefined} error - The error object if an error occurred.
* @returns {boolean} isLoading - Indicates if the run data is currently being loaded.
* @returns {boolean} isValidating - Indicates if the run data is currently being validated.
* @returns {boolean} isError - Indicates if an error occurred during the retrieval of the run data.
*/
export function useRun<TTask extends AnyTask>(
runId: string,
options?: CommonTriggerHookOptions
): {
run: RetrieveRunResult<TTask> | undefined;
error: Error | undefined;
isLoading: boolean;
isValidating: boolean;
isError: boolean;
} {
const apiClient = useApiClient(options);
const {
data: run,
error,
isLoading,
isValidating,
} = useSWR<RetrieveRunResult<TTask>>(
runId,
() => {
if (!apiClient) {
throw new Error("Could not call useRun: Missing access token");
}
return apiClient.retrieveRun(runId);
},
{
revalidateOnReconnect: options?.revalidateOnReconnect,
refreshInterval: (run) => {
if (!run) return options?.refreshInterval ?? 0;
if (run.isCompleted) return 0;
return options?.refreshInterval ?? 0;
},
revalidateOnFocus: options?.revalidateOnFocus,
}
);
return { run, error, isLoading, isValidating, isError: !!error };
}
@@ -0,0 +1,224 @@
"use client";
import {
type InferRunTypes,
type RunHandleFromTypes,
type AnyTask,
type TaskIdentifier,
type TaskPayload,
makeIdempotencyKey,
stringifyIO,
type TriggerOptions,
type RealtimeRunSkipColumns,
} from "@trigger.dev/core/v3";
import useSWRMutation from "swr/mutation";
import { type UseApiClientOptions, useApiClient } from "./useApiClient.js";
import {
type UseRealtimeRunInstance,
type UseRealtimeRunWithStreamsInstance,
useRealtimeRun,
useRealtimeRunWithStreams,
} from "./useRealtime.js";
/**
* Base interface for task trigger instances.
*
* @template TTask - The type of the task
*/
export interface TriggerInstance<TTask extends AnyTask> {
/** Function to submit the task with a payload */
submit: (payload: TaskPayload<TTask>, options?: TriggerOptions) => void;
/** Whether the task is currently being submitted */
isLoading: boolean;
/** The handle returned after successful task submission */
handle?: RunHandleFromTypes<InferRunTypes<TTask>>;
/** Any error that occurred during submission */
error?: Error;
}
export type UseTaskTriggerOptions = UseApiClientOptions;
/**
* Hook to trigger a task and manage its initial execution state.
*
* @template TTask - The type of the task
* @param {TaskIdentifier<TTask>} id - The identifier of the task to trigger
* @param {UseTaskTriggerOptions} [options] - Configuration options for the task trigger
* @returns {TriggerInstance<TTask>} An object containing the submit function, loading state, handle, and any errors
*
* @example
* ```ts
* import type { myTask } from './path/to/task';
* const { submit, isLoading, handle, error } = useTaskTrigger<typeof myTask>('my-task-id');
*
* // Submit the task with payload
* submit({ foo: 'bar' });
* ```
*/
export function useTaskTrigger<TTask extends AnyTask>(
id: TaskIdentifier<TTask>,
options?: UseTaskTriggerOptions
): TriggerInstance<TTask> {
const apiClient = useApiClient(options);
async function triggerTask(
id: string,
{
arg: { payload, options },
}: { arg: { payload: TaskPayload<TTask>; options?: TriggerOptions } }
) {
if (!apiClient) {
throw new Error("Could not trigger task in useTaskTrigger: Missing access token");
}
const payloadPacket = await stringifyIO(payload);
const handle = await apiClient.triggerTask(id, {
payload: payloadPacket.data,
options: {
queue: options?.queue ? { name: options.queue } : undefined,
concurrencyKey: options?.concurrencyKey,
payloadType: payloadPacket.dataType,
idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
delay: options?.delay,
ttl: options?.ttl,
tags: options?.tags,
maxAttempts: options?.maxAttempts,
metadata: options?.metadata,
maxDuration: options?.maxDuration,
lockToVersion: options?.version,
},
});
return { ...handle, taskIdentifier: id };
}
const mutation = useSWRMutation(id as string, triggerTask);
return {
submit: (payload, options) => {
// trigger the task with the given payload
mutation.trigger({ payload, options });
},
isLoading: mutation.isMutating,
handle: mutation.data as RunHandleFromTypes<InferRunTypes<TTask>>,
error: mutation.error,
};
}
/**
* Configuration options for task triggers with realtime updates.
*/
export type UseRealtimeTaskTriggerOptions = UseTaskTriggerOptions & {
/** Whether the realtime subscription is enabled */
enabled?: boolean;
/** Optional throttle time in milliseconds for stream updates */
experimental_throttleInMs?: number;
/**
* Skip columns from the subscription.
*
* @default []
*/
skipColumns?: RealtimeRunSkipColumns;
};
export type RealtimeTriggerInstanceWithStreams<
TTask extends AnyTask,
TStreams extends Record<string, any> = Record<string, any>,
> = UseRealtimeRunWithStreamsInstance<TTask, TStreams> & {
submit: (payload: TaskPayload<TTask>, options?: TriggerOptions) => void;
isLoading: boolean;
handle?: RunHandleFromTypes<InferRunTypes<TTask>>;
};
/**
* Hook to trigger a task and subscribe to its realtime updates including stream data.
*
* @template TTask - The type of the task
* @template TStreams - The type of the streams data
* @param {TaskIdentifier<TTask>} id - The identifier of the task to trigger
* @param {UseRealtimeTaskTriggerOptions} [options] - Configuration options for the task trigger and realtime updates
* @returns {RealtimeTriggerInstanceWithStreams<TTask, TStreams>} An object containing the submit function, loading state,
* handle, run state, streams data, and error handling
*
* @example
* ```ts
* import type { myTask } from './path/to/task';
* const { submit, run, streams, error } = useRealtimeTaskTriggerWithStreams<
* typeof myTask,
* { output: string }
* >('my-task-id');
*
* // Submit and monitor the task with streams
* submit({ foo: 'bar' });
* ```
*/
export function useRealtimeTaskTriggerWithStreams<
TTask extends AnyTask,
TStreams extends Record<string, any> = Record<string, any>,
>(
id: TaskIdentifier<TTask>,
options?: UseRealtimeTaskTriggerOptions
): RealtimeTriggerInstanceWithStreams<TTask, TStreams> {
const triggerInstance = useTaskTrigger<TTask>(id, options);
const realtimeInstance = useRealtimeRunWithStreams<TTask, TStreams>(triggerInstance.handle?.id, {
...options,
id: triggerInstance.handle?.id,
accessToken: triggerInstance.handle?.publicAccessToken ?? options?.accessToken,
});
return {
...realtimeInstance,
...triggerInstance,
};
}
export type RealtimeTriggerInstance<TTask extends AnyTask> = UseRealtimeRunInstance<TTask> & {
submit: (payload: TaskPayload<TTask>, options?: TriggerOptions) => void;
isLoading: boolean;
handle?: RunHandleFromTypes<InferRunTypes<TTask>>;
};
/**
* Hook to trigger a task and subscribe to its realtime updates.
*
* @template TTask - The type of the task
* @param {TaskIdentifier<TTask>} id - The identifier of the task to trigger
* @param {UseRealtimeTaskTriggerOptions} [options] - Configuration options for the task trigger and realtime updates
* @returns {RealtimeTriggerInstance<TTask>} An object containing the submit function, loading state,
* handle, run state, and error handling
*
* @example
* ```ts
* import type { myTask } from './path/to/task';
* const { submit, run, error, stop } = useRealtimeTaskTrigger<typeof myTask>('my-task-id');
*
* // Submit and monitor the task
* submit({ foo: 'bar' });
*
* // Stop monitoring when needed
* stop();
* ```
*/
export function useRealtimeTaskTrigger<TTask extends AnyTask>(
id: TaskIdentifier<TTask>,
options?: UseRealtimeTaskTriggerOptions
): RealtimeTriggerInstance<TTask> {
const triggerInstance = useTaskTrigger<TTask>(id, options);
const realtimeInstance = useRealtimeRun<TTask>(triggerInstance.handle?.id, {
...options,
id: triggerInstance.handle?.id,
accessToken: triggerInstance.handle?.publicAccessToken ?? options?.accessToken,
});
return {
submit: triggerInstance.submit,
isLoading: triggerInstance.isLoading,
handle: triggerInstance.handle,
run: realtimeInstance.run,
error: realtimeInstance.error ?? triggerInstance.error,
stop: realtimeInstance.stop,
};
}
@@ -0,0 +1,75 @@
"use client";
import useSWRMutation from "swr/mutation";
import type { UseApiClientOptions } from "./useApiClient.js";
import { useApiClient } from "./useApiClient.js";
/**
* Base interface for task trigger instances.
*
* @template TOutput - The type of the output
*/
export interface WaitTokenInstance<TOutput> {
/** Function to complete the waitpoint with an output */
complete: (output: TOutput) => void;
/** Whether the waitpoint is currently being completed */
isLoading: boolean;
/** Whether the waitpoint has been completed */
isCompleted: boolean;
/** Any error that occurred during completion */
error?: Error;
/** Whether the waitpoint is ready to be completed */
isReady: boolean;
}
/**
* Hook to complete a waitpoint and manage its completion state.
*
* @template TOutput - The type of the output
* @param {string} waitpointId - The identifier of the waitpoint to complete
* @returns {WaitTokenInstance<TOutput>} An object containing the complete function, loading state, isCompleted, and any errors
*
* @example
* ```ts
* import type { myTask } from './path/to/task';
* const { complete, isLoading, isCompleted, error } = useWaitToken('waitpoint-id');
*
* // Complete the waitpoint with an output
* complete({ foo: 'bar' });
* ```
*/
export function useWaitToken<TOutput>(
waitpointId?: string,
options?: UseApiClientOptions
): WaitTokenInstance<TOutput> {
const apiClient = useApiClient(options);
async function completeWaitpoint(id: string, { arg: { output } }: { arg: { output: TOutput } }) {
if (!apiClient) {
throw new Error("Could not complete waitpoint in useWaitToken: Missing access token");
}
if (!waitpointId) {
throw new Error("Could not complete waitpoint in useWaitToken: Missing waitpoint ID");
}
const result = await apiClient.completeWaitpointToken(waitpointId, {
data: output,
});
return result;
}
const mutation = useSWRMutation(waitpointId, completeWaitpoint);
return {
complete: (output) => {
// trigger the task with the given payload
mutation.trigger({ output });
},
isLoading: mutation.isMutating,
isCompleted: !!mutation.data?.success,
isReady: !!waitpointId,
error: mutation.error,
};
}
+7
View File
@@ -0,0 +1,7 @@
export * from "./contexts.js";
export * from "./hooks/useApiClient.js";
export * from "./hooks/useRun.js";
export * from "./hooks/useRealtime.js";
export * from "./hooks/useTaskTrigger.js";
export * from "./hooks/useWaitToken.js";
export * from "./hooks/useInputStreamSend.js";
@@ -0,0 +1,45 @@
"use client";
import React from "react";
export function assertContextExists(
contextVal: unknown,
msgOrCtx: string | React.Context<any>
): asserts contextVal {
if (!contextVal) {
throw typeof msgOrCtx === "string"
? new Error(msgOrCtx)
: new Error(`${msgOrCtx.displayName} not found`);
}
}
type Options = { assertCtxFn?: (v: unknown, msg: string) => void };
type ContextOf<T> = React.Context<T | undefined>;
type UseCtxFn<T> = () => T;
/**
* Creates and returns a Context and two hooks that return the context value.
* The Context type is derived from the type passed in by the user.
* The first hook returned guarantees that the context exists so the returned value is always CtxValue
* The second hook makes no guarantees, so the returned value can be CtxValue | undefined
*/
export const createContextAndHook = <CtxVal>(
displayName: string,
options?: Options
): [ContextOf<CtxVal>, UseCtxFn<CtxVal>, UseCtxFn<CtxVal | Partial<CtxVal>>] => {
const { assertCtxFn = assertContextExists } = options || {};
const Ctx = React.createContext<CtxVal | undefined>(undefined);
Ctx.displayName = displayName;
const useCtx = () => {
const ctx = React.useContext(Ctx);
assertCtxFn(ctx, `${displayName} not found`);
return ctx as CtxVal;
};
const useCtxWithoutGuarantee = () => {
const ctx = React.useContext(Ctx);
return ctx ? ctx : {};
};
return [Ctx, useCtx, useCtxWithoutGuarantee];
};
@@ -0,0 +1,58 @@
// Reusable throttle utility
export type ThrottledQueue<T> = {
add: (item: T) => void;
flush: () => Promise<void>;
isEmpty: () => boolean;
};
export function createThrottledQueue<T>(
onFlush: (items: T[]) => Promise<void>,
throttleInMs?: number
): ThrottledQueue<T> {
let queue: T[] = [];
let lastFlushTime = 0;
let flushPromise: Promise<void> | null = null;
const scheduleFlush = async () => {
// If no throttle specified or there's already a flush in progress, return
if (!throttleInMs) {
// Immediately flush when no throttling is specified
const itemsToFlush = [...queue];
queue = [];
await onFlush(itemsToFlush);
return;
}
if (queue.length === 0 || flushPromise) return;
const now = Date.now();
const timeUntilNextFlush = Math.max(0, lastFlushTime + throttleInMs - now);
if (timeUntilNextFlush === 0) {
const itemsToFlush = [...queue];
queue = [];
lastFlushTime = now;
flushPromise = onFlush(itemsToFlush).finally(() => {
flushPromise = null;
// Check if more items accumulated during flush
scheduleFlush();
});
} else {
setTimeout(scheduleFlush, timeUntilNextFlush);
}
};
return {
add: (item: T) => {
queue.push(item);
scheduleFlush();
},
flush: async () => {
if (queue.length === 0) return;
const itemsToFlush = [...queue];
queue = [];
await onFlush(itemsToFlush);
},
isEmpty: () => queue.length === 0,
};
}
@@ -0,0 +1,26 @@
"use client";
import type { ApiRequestOptions } from "@trigger.dev/core/v3";
// eslint-disable-next-line import/export
export * from "swr";
// eslint-disable-next-line import/export
export { default as useSWR, SWRConfig } from "swr";
export type CommonTriggerHookOptions = {
/**
* Poll for updates at the specified interval (in milliseconds). Polling is not recommended for most use-cases. Use the Realtime hooks instead.
*/
refreshInterval?: number;
/** Revalidate the data when the browser regains a network connection. */
revalidateOnReconnect?: boolean;
/** Revalidate the data when the window regains focus. */
revalidateOnFocus?: boolean;
/** Optional access token for authentication */
accessToken?: string;
/** Optional base URL for the API endpoints */
baseURL?: string;
/** Optional additional request configuration */
requestOptions?: ApiRequestOptions;
};
+10
View File
@@ -0,0 +1,10 @@
{
"extends": "../../.configs/tsconfig.base.json",
"compilerOptions": {
"isolatedDeclarations": false,
"composite": true,
"sourceMap": true,
"stripInternal": true
},
"include": ["./src/**/*.ts", "./src/**/*.tsx"]
}