nuxt-cf-jobs 0.0.2

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.
Files changed (34) hide show
  1. package/README.md +331 -0
  2. package/dist/module.d.mts +73 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +380 -0
  5. package/dist/runtime/server/app.d.ts +80 -0
  6. package/dist/runtime/server/app.js +81 -0
  7. package/dist/runtime/server/d1.d.ts +119 -0
  8. package/dist/runtime/server/d1.js +259 -0
  9. package/dist/runtime/server/dev.d.ts +39 -0
  10. package/dist/runtime/server/dev.js +93 -0
  11. package/dist/runtime/server/dispatch.d.ts +25 -0
  12. package/dist/runtime/server/dispatch.js +66 -0
  13. package/dist/runtime/server/index.d.ts +12 -0
  14. package/dist/runtime/server/index.js +12 -0
  15. package/dist/runtime/server/outbox.d.ts +220 -0
  16. package/dist/runtime/server/outbox.js +246 -0
  17. package/dist/runtime/server/payload.d.ts +3 -0
  18. package/dist/runtime/server/payload.js +3 -0
  19. package/dist/runtime/server/plugins/dev-queues.d.ts +2 -0
  20. package/dist/runtime/server/plugins/dev-queues.js +25 -0
  21. package/dist/runtime/server/policy.d.ts +10 -0
  22. package/dist/runtime/server/policy.js +49 -0
  23. package/dist/runtime/server/queue.d.ts +211 -0
  24. package/dist/runtime/server/queue.js +495 -0
  25. package/dist/runtime/server/registry.d.ts +79 -0
  26. package/dist/runtime/server/registry.js +82 -0
  27. package/dist/runtime/server/schema.d.ts +965 -0
  28. package/dist/runtime/server/schema.js +80 -0
  29. package/dist/runtime/server/testing.d.ts +34 -0
  30. package/dist/runtime/server/testing.js +61 -0
  31. package/dist/runtime/server/types.d.ts +123 -0
  32. package/dist/runtime/server/types.js +0 -0
  33. package/dist/types.d.mts +3 -0
  34. package/package.json +109 -0
@@ -0,0 +1,211 @@
1
+ import type { JobRegistryLike } from './dispatch.js';
2
+ import type { DurableJobFailureRepository } from './outbox.js';
3
+ import type { AnyJobDefinition, JobPayloadOf } from './registry.js';
4
+ import type { CloudflareQueue, CloudflareQueueSendBatchMessage, DispatchableJob, JobContext, JobControlResult, JobDefinition, QueueBindingsConfig, QueuePayload, QueueSendOptions } from './types.js';
5
+ export declare const CF_QUEUE_MAX_BATCH_SIZE = 100;
6
+ export declare const CF_QUEUE_MAX_BATCH_BYTES: number;
7
+ export declare const CF_QUEUE_MAX_MESSAGE_BYTES: number;
8
+ export declare const CF_QUEUE_MAX_DELAY_SECONDS = 43200;
9
+ export interface SendBackpressureOptions {
10
+ maxRetries?: number;
11
+ baseDelayMs?: number;
12
+ maxDelayMs?: number;
13
+ onError?: (input: {
14
+ error: unknown;
15
+ attempt: number;
16
+ willRetry: boolean;
17
+ }) => void | Promise<void>;
18
+ }
19
+ export declare function withSendBackpressure<R>(fn: () => Promise<R>, opts: SendBackpressureOptions | undefined): Promise<R>;
20
+ export declare function sendBatchChunked<T>(cfQueue: CloudflareQueue<T>, messages: T[], opts?: QueueSendOptions & SendBackpressureOptions): Promise<void>;
21
+ export declare function sendBatchMessagesChunked<T>(cfQueue: CloudflareQueue<T>, messages: Array<CloudflareQueueSendBatchMessage<T>>, opts?: SendBackpressureOptions): Promise<void>;
22
+ export type QueueSource = Record<string, unknown> | {
23
+ context?: {
24
+ cloudflare?: {
25
+ env?: Record<string, unknown>;
26
+ } | unknown;
27
+ } | unknown;
28
+ };
29
+ export interface JobQueuePublisher<Job extends AnyJobDefinition> {
30
+ send: (payload: JobPayloadOf<Job>, opts?: QueueSendOptions & SendBackpressureOptions) => Promise<boolean>;
31
+ sendBatch: (payloads: Array<JobPayloadOf<Job>>, opts?: QueueSendOptions & SendBackpressureOptions) => Promise<boolean>;
32
+ sendBatchMessages: (messages: Array<{
33
+ payload: JobPayloadOf<Job>;
34
+ delaySeconds?: number;
35
+ contentType?: import('./types').QueueMessageContentType;
36
+ }>, opts?: SendBackpressureOptions) => Promise<boolean>;
37
+ }
38
+ export interface QueueBindingValidationIssue {
39
+ jobName: string;
40
+ queue: string;
41
+ reason: 'missing-binding';
42
+ }
43
+ export declare function validateJobQueueBindings(queues: QueueBindingsConfig, jobs: readonly Pick<AnyJobDefinition, 'name' | 'queue'>[]): QueueBindingValidationIssue[];
44
+ export declare function assertJobQueueBindings(queues: QueueBindingsConfig, jobs: readonly Pick<AnyJobDefinition, 'name' | 'queue'>[]): void;
45
+ /**
46
+ * Resolves the Cloudflare runtime env from a Nitro task context where no `H3Event` is available.
47
+ *
48
+ * Nitro tasks (`defineTask`) run without an event, so Cloudflare bindings must be threaded through
49
+ * `globalThis.__env__`. This helper reads that shim and returns the env (or `undefined`).
50
+ */
51
+ export declare function resolveNitroTaskEnv(): Record<string, unknown> | undefined;
52
+ export declare function resolveQueueSourceEnv(source: QueueSource | undefined): Record<string, unknown> | undefined;
53
+ export declare function createJobQueue<const Job extends AnyJobDefinition>(source: QueueSource | undefined, queues: QueueBindingsConfig, definition: Job): JobQueuePublisher<Job>;
54
+ export declare function resolveQueueBindingName(queues: QueueBindingsConfig, queueName: string): string | undefined;
55
+ export declare function resolveCloudflareQueueName(queues: QueueBindingsConfig, queueName: string): string;
56
+ export declare function resolveLogicalQueueName(queues: QueueBindingsConfig, cloudflareQueueName: string): string | undefined;
57
+ export declare function resolveQueueJobType(queues: QueueBindingsConfig, queueName: string): string | undefined;
58
+ export declare function getQueueBinding<T>(env: Record<string, unknown> | undefined, binding: string | undefined): CloudflareQueue<T> | undefined;
59
+ export declare function getQueueBindingByName<T>(env: Record<string, unknown> | undefined, queues: QueueBindingsConfig, queueName: string): CloudflareQueue<T> | undefined;
60
+ export declare function sendQueueMessage<T>(env: Record<string, unknown> | undefined, binding: string, message: T, opts?: QueueSendOptions & SendBackpressureOptions): Promise<boolean>;
61
+ export declare function sendQueueBatch<T>(env: Record<string, unknown> | undefined, binding: string, messages: T[], opts?: QueueSendOptions & SendBackpressureOptions): Promise<boolean>;
62
+ export declare function sendNamedQueueMessage<T>(env: Record<string, unknown> | undefined, queues: QueueBindingsConfig, queueName: string, message: T, opts?: QueueSendOptions & SendBackpressureOptions): Promise<boolean>;
63
+ export declare function sendNamedQueueBatch<T>(env: Record<string, unknown> | undefined, queues: QueueBindingsConfig, queueName: string, messages: T[], opts?: QueueSendOptions & SendBackpressureOptions): Promise<boolean>;
64
+ export interface DlqPublisher<T = Record<string, unknown>> {
65
+ send: (message: T, opts?: QueueSendOptions & SendBackpressureOptions) => Promise<boolean>;
66
+ }
67
+ export declare function createDlqPublisher<T = Record<string, unknown>, Env extends Record<string, unknown> = Record<string, unknown>>(env: Env | undefined, binding: string): DlqPublisher<T>;
68
+ export declare function shouldSendToDlq(input: {
69
+ attempts: number;
70
+ maxAttempts?: number;
71
+ }): boolean;
72
+ export declare function resolveDlqBinding(queues: QueueBindingsConfig, logicalQueue: string): string | undefined;
73
+ export interface QueueConsumerConfigIssue {
74
+ queue: string;
75
+ jobName?: string;
76
+ reason: 'tries-exceeds-max-retries' | 'dlq-binding-missing';
77
+ detail: string;
78
+ }
79
+ export declare function validateQueueConsumerConfig(queues: QueueBindingsConfig, jobs: readonly AnyJobDefinition[]): QueueConsumerConfigIssue[];
80
+ export interface QueueShapeIssue {
81
+ queue: string;
82
+ reason: 'missing-binding' | 'dlq-pair-incomplete' | 'duplicate-binding' | 'duplicate-cf-queue-name';
83
+ detail: string;
84
+ }
85
+ export declare function validateQueueBindingShape(queues: QueueBindingsConfig): QueueShapeIssue[];
86
+ /**
87
+ * Identity helper that pins the literal types of a queues config and runs structural validation eagerly.
88
+ * Throws on shape issues (duplicate bindings, half-configured DLQ pairs) so misconfig fails fast.
89
+ *
90
+ * @example
91
+ * export const queues = defineCfJobsQueues({
92
+ * default: 'QUEUE_DEFAULT',
93
+ * critical: { binding: 'QUEUE_CRITICAL', queueName: 'critical-prod', maxRetries: 5 },
94
+ * } as const)
95
+ */
96
+ export declare function defineCfJobsQueues<const T extends QueueBindingsConfig>(queues: T): T;
97
+ export declare function registerQueueConsumer<T, Env extends Record<string, unknown>>(nitroApp: {
98
+ hooks: {
99
+ hook: (name: any, handler: any) => void;
100
+ };
101
+ }, queueName: string, handler: (payload: QueuePayload<T, Env>) => Promise<void>, queues?: QueueBindingsConfig): void;
102
+ export interface RegisteredQueueConsumerMessage<T = Record<string, unknown>> {
103
+ id?: string;
104
+ body: T;
105
+ attempts: number;
106
+ timestamp?: Date | number;
107
+ ack: () => void;
108
+ retry: (opts?: {
109
+ delaySeconds?: number;
110
+ }) => void;
111
+ }
112
+ export interface RegisteredQueueConsumerBatch<T = Record<string, unknown>> {
113
+ queue: string;
114
+ messages: Array<RegisteredQueueConsumerMessage<T>>;
115
+ ackAll?: () => void;
116
+ retryAll?: (opts?: {
117
+ delaySeconds?: number;
118
+ }) => void;
119
+ }
120
+ export interface RegisteredQueueConsumerPayload<Env extends Record<string, unknown>> {
121
+ batch: RegisteredQueueConsumerBatch;
122
+ env: Env;
123
+ }
124
+ export interface DlqMessageInput<Env extends Record<string, unknown>> {
125
+ env: Env;
126
+ batch: RegisteredQueueConsumerBatch;
127
+ message: RegisteredQueueConsumerMessage;
128
+ /** Parsed `_task` from the message body, when present. */
129
+ taskName?: string;
130
+ /** Parsed `jobId` from the message body, when present. */
131
+ jobId?: string;
132
+ }
133
+ export interface DlqQueueHandler<Env extends Record<string, unknown>> {
134
+ /** When true, the message is persisted via `dlqRepository.recordFailure` (if configured). */
135
+ persist?: boolean;
136
+ /** Custom per-message handler. Runs after `persist` (if enabled). Errors are propagated. */
137
+ onMessage?: (input: DlqMessageInput<Env>) => void | Promise<void>;
138
+ }
139
+ export type DlqQueuesOption<Env extends Record<string, unknown>> = readonly string[] | ((cfQueueName: string) => boolean) | Record<string, DlqQueueHandler<Env>>;
140
+ export interface RegisteredQueueConsumerContextInput<Env extends Record<string, unknown>> {
141
+ env: Env;
142
+ batch: RegisteredQueueConsumerBatch;
143
+ message: RegisteredQueueConsumerMessage;
144
+ logicalQueue: string;
145
+ taskName: string;
146
+ definition: JobDefinition<string, unknown, string, Env, unknown, unknown>;
147
+ job: DispatchableJob;
148
+ control: JobControlResult;
149
+ payload: Record<string, unknown>;
150
+ }
151
+ export interface RegisteredQueueConsumerHookInput<Env extends Record<string, unknown>> {
152
+ env: Env;
153
+ batch: RegisteredQueueConsumerBatch;
154
+ message: RegisteredQueueConsumerMessage;
155
+ logicalQueue?: string;
156
+ taskName?: string;
157
+ definition?: AnyJobDefinition;
158
+ job?: DispatchableJob;
159
+ }
160
+ export interface RegisterRegisteredQueueConsumerOptions<Env extends Record<string, unknown>, Db, Logger> {
161
+ registry: JobRegistryLike<Env, Db, Logger> & {
162
+ jobs?: readonly AnyJobDefinition[];
163
+ };
164
+ queues: QueueBindingsConfig | (() => QueueBindingsConfig);
165
+ createContext: (input: RegisteredQueueConsumerContextInput<Env>) => JobContext<Env, Db, Logger> | Promise<JobContext<Env, Db, Logger>>;
166
+ getJobId?: (input: RegisteredQueueConsumerHookInput<Env> & {
167
+ payload: Record<string, unknown>;
168
+ }) => string;
169
+ getSiteId?: (payload: Record<string, unknown>) => string | null | undefined;
170
+ getUserId?: (payload: Record<string, unknown>) => number | null | undefined;
171
+ retryDelaySeconds?: (input: RegisteredQueueConsumerHookInput<Env> & {
172
+ error: unknown;
173
+ }) => number;
174
+ dlqQueues?: DlqQueuesOption<Env>;
175
+ /** Forward exhausted messages to a DLQ. If unspecified, falls back to the binding resolved from `queues[logical].deadLetterQueueBinding`/`deadLetterQueue`. */
176
+ dlqBinding?: string | ((input: {
177
+ logicalQueue: string;
178
+ definition?: AnyJobDefinition;
179
+ }) => string | undefined);
180
+ /**
181
+ * Repository used to persist exhausted DLQ messages when `dlqQueues` is set to the
182
+ * `Record<string, { persist: true }>` form. Cloudflare's wrangler `dead_letter_queue` directive
183
+ * only forwards messages CF-side; you still need a `cloudflare:queue` consumer for the DLQ to
184
+ * persist them, which this option provides.
185
+ */
186
+ dlqRepository?: DurableJobFailureRepository;
187
+ /** Delay (s) applied when unknown-queue messages are returned to the queue. Defaults to 60. */
188
+ unknownQueueRetryDelaySeconds?: number;
189
+ /** In-memory dedup cache size for the lightweight (non-durable) consumer path. Set to 0 to disable. */
190
+ dedupCacheSize?: number;
191
+ onMissingQueue?: (input: RegisteredQueueConsumerHookInput<Env>) => void | Promise<void>;
192
+ onInvalidPayload?: (input: RegisteredQueueConsumerHookInput<Env> & {
193
+ error?: string;
194
+ validationError?: unknown;
195
+ }) => void | Promise<void>;
196
+ onDispatchError?: (input: RegisteredQueueConsumerHookInput<Env> & {
197
+ error: unknown;
198
+ }) => void | Promise<void>;
199
+ onDlq?: (input: RegisteredQueueConsumerHookInput<Env>) => void | Promise<void>;
200
+ onDuplicate?: (input: RegisteredQueueConsumerHookInput<Env>) => void | Promise<void>;
201
+ }
202
+ export declare function registerRegisteredQueueConsumer<Env extends Record<string, unknown>, Db, Logger>(nitroApp: {
203
+ hooks: {
204
+ hook: (name: any, handler: any) => void;
205
+ };
206
+ }, opts: RegisterRegisteredQueueConsumerOptions<Env, Db, Logger>): void;
207
+ export declare function processRegisteredQueueBatch<Env extends Record<string, unknown>, Db, Logger>(payload: RegisteredQueueConsumerPayload<Env>, opts: RegisterRegisteredQueueConsumerOptions<Env, Db, Logger>): Promise<void>;
208
+ export declare function exponentialBackoff(attempts: number, opts?: {
209
+ baseSeconds?: number;
210
+ maxSeconds?: number;
211
+ }): number;