import type { Run } from './runtime/run.js';
import type { Serializable } from './schemas.js';
/**
 * An object that can be awaited to receive a value.
 */
interface Thenable<T> {
    then: Promise<T>['then'];
}
/**
 * A `Request` that can be responded to within a workflow
 * step function by calling the `respondWith()` method.
 */
export interface RequestWithResponse extends Request {
    respondWith: (response: Response) => Promise<void>;
}
/**
 * A hook that can be awaited and/or iterated over to receive
 * a value within a workflow from an external system.
 *
 * Hooks implement the TC39 Explicit Resource Management proposal,
 * allowing them to be used with the `using` keyword for automatic disposal.
 */
export interface Hook<T = any> extends AsyncIterable<T>, Thenable<T> {
    /**
     * The token used to identify this hook.
     */
    token: string;
    /**
     * Returns a promise that resolves with the conflicting {@link Run} if
     * another active hook already owns this hook's token, or `null` once
     * the hook has been registered and is ready to receive payloads.
     *
     * Calling `createHook()` alone does not register the hook — registration
     * only happens when the workflow suspends. Awaiting `getConflict()`
     * suspends the workflow to commit the hook registration, so it can be
     * used to claim the token (and detect token conflicts early) without
     * waiting for payload data.
     *
     * When a conflict is detected, the resolved `Run` is the run that
     * currently owns the token. The workflow can decide how to handle the
     * duplicate in code: return or log `conflict.runId`, inspect
     * `await conflict.status`, await `conflict.returnValue`, or cancel the
     * owner with `await conflict.cancel()` and continue in the current run.
     *
     * Note that awaiting the hook's payload (`await hook`) when the token is
     * already owned by another active hook still rejects with
     * `HookConflictError`. In the rare case where the conflicting run cannot
     * be identified (a `hook_conflict` event persisted by an old world that
     * did not record the owning run's ID), `getConflict()` also rejects with
     * `HookConflictError` rather than resolving with an incomplete value.
     *
     * @example
     * ```ts
     * using hook = createHook({ token: `order:${orderId}` });
     * const conflict = await hook.getConflict();
     * if (conflict) {
     *   // another run already owns this token
     *   return { dedupedTo: conflict.runId };
     * }
     * // token is now claimed, without waiting for payload data
     * ```
     */
    getConflict(): Promise<Run<unknown> | null>;
    /**
     * Disposes the hook, releasing its token for reuse by other workflows.
     *
     * After calling `dispose()`, the hook will no longer receive any events.
     * This is useful when you want to explicitly release a hook token before
     * the workflow completes, allowing another workflow to register a hook
     * with the same token.
     *
     * @example
     * ```ts
     * const hook = createHook<{ message: string }>({ token: 'my-token' });
     *
     * for await (const payload of hook) {
     *   if (payload.message === 'done') {
     *     hook.dispose(); // Release the token early
     *     break;
     *   }
     * }
     * ```
     */
    dispose(): void;
    /**
     * Implements the TC39 Explicit Resource Management proposal.
     * Called automatically when using the `using` keyword.
     *
     * @example
     * ```ts
     * {
     *   using hook = createHook<{ message: string }>({ token: 'my-token' });
     *   const payload = await hook;
     *   // hook is automatically disposed when the block exits
     * }
     * ```
     */
    [Symbol.dispose](): void;
}
/**
 * A webhook that can be used to suspend and resume the workflow run
 * upon receiving an HTTP request to the specified URL.
 *
 * @see {@link createWebhook}
 * @see https://developer.mozilla.org/en-US/docs/Web/API/Request
 */
export interface Webhook<T extends Request> extends Hook<T> {
    /**
     * The URL that external systems can call to send data to the workflow.
     */
    url: string;
}
export interface HookOptions {
    /**
     * Unique token that is used to associate with the hook.
     *
     * When specifying an explicit token, the token should be constructed
     * with information that the dispatching side can reliably reconstruct
     * the token with the information it has available.
     *
     * Deterministic tokens are intended for use with `createHook()` and
     * server-side `resumeHook()` only. For webhooks (`createWebhook()`),
     * tokens are always randomly generated to prevent unauthorized access
     * to the public webhook endpoint.
     *
     * If not provided, a randomly generated token will be assigned.
     *
     * @example
     *
     * ```ts
     * // Explicit token for a Slack bot (one workflow run per channel)
     * const hook = createHook<SlackMessage>({
     *   token: `slack_webhook:${channelId}`,
     * });
     * ```
     */
    token?: string;
    /**
     * Additional user-defined data to include with the hook payload.
     *
     * @example
     *
     * ```ts
     * const hook = createHook<{ name: string }>({
     *   metadata: {
     *     type: "cat",
     *     color: "orange",
     *   },
     * });
     * ```
     */
    metadata?: Serializable;
    /**
     * Whether this hook can be resumed via the public webhook endpoint.
     *
     * When `true`, the hook can be triggered by sending an HTTP request to the
     * public `/.well-known/workflow/v1/webhook/{token}` URL. This is automatically
     * set when using `createWebhook()`.
     *
     * When `false` (the default), the hook can only be resumed server-side
     * via `resumeHook()`.
     *
     * @default false
     */
    isWebhook?: boolean;
}
export interface WebhookOptions extends Omit<HookOptions, 'token' | 'isWebhook'> {
    /**
     * If set to a `Response` object, the webhook will automatically
     * respond with the specified response.
     *
     * If set to `"manual"`, each individual request will need to
     * be responded to manually from within the workflow by calling the
     * `respondWith()` method.
     *
     * If not set then the webhook will automatically respond with
     * a `202 Accepted` response.
     */
    respondWith?: Response | 'manual';
}
/**
 * Creates a {@link Hook} that can be used to suspend and resume the workflow run with a payload.
 *
 * Hooks allow external systems to send arbitrary serializable data into a workflow.
 *
 * @param options - Configuration options for the hook.
 * @returns A `Hook` that can be awaited to receive one or more payloads.
 *
 * @example
 *
 * ```ts
 * export async function workflowWithHook() {
 *   "use workflow";
 *
 *   const hook = createHook<{ message: string }>();
 *   console.log('Hook token:', hook.token);
 *
 *   const payload = await hook;
 *   console.log('Received:', payload.message);
 * }
 * ```
 */
export declare function createHook<T = any>(options?: HookOptions): Hook<T>;
/**
 * Creates a {@link Webhook} that can be used to suspend and resume the workflow
 * run upon receiving an HTTP request to the specified URL.
 *
 * Webhooks will result in a {@link https://developer.mozilla.org/en-US/docs/Web/API/Request | Request} object
 * that can be interacted with in workflow functions.
 */
export declare function createWebhook(options: WebhookOptions & {
    respondWith: 'manual';
}): Webhook<RequestWithResponse>;
export declare function createWebhook(options?: WebhookOptions): Webhook<Request>;
export {};
//# sourceMappingURL=create-hook.d.ts.map