flowli 0.3.0 → 0.4.0

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.
package/README.md CHANGED
@@ -20,6 +20,7 @@ Define jobs once. Run them anywhere.
20
20
  - [Context vs Meta](#context-vs-meta)
21
21
  - [Async Execution](#async-execution)
22
22
  - [Runner](#runner)
23
+ - [Inspection And Observability](#inspection-and-observability)
23
24
  - [Async Semantics](#async-semantics)
24
25
  - [Reusable Predeclared Jobs](#reusable-predeclared-jobs)
25
26
  - [Hono](#hono)
@@ -460,6 +461,53 @@ await runner.stop();
460
461
 
461
462
  `createRunner()` consumes an existing runtime. It does not recreate jobs or rebuild context.
462
463
 
464
+ ## Inspection And Observability
465
+
466
+ Flowli now exposes a read-side inspection surface on the runtime:
467
+
468
+ ```ts
469
+ const job = await flowli.inspect.getJob("job_123");
470
+ const schedule = await flowli.inspect.getSchedule("daily-report");
471
+ const counts = await flowli.inspect.getQueueCounts();
472
+ const queuedJobs = await flowli.inspect.getJobsByState("queued", {
473
+ limit: 25,
474
+ });
475
+ const schedules = await flowli.inspect.getSchedules({
476
+ limit: 25,
477
+ });
478
+ ```
479
+
480
+ This gives you enough visibility to:
481
+
482
+ - inspect retry metadata like `failureCount`, `lastFailedAt`, and `nextRetryAt`
483
+ - power operational logs and lightweight admin pages
484
+ - debug delayed, failed, and completed work without reaching into Redis directly
485
+
486
+ The runner also supports lifecycle hooks for observability:
487
+
488
+ ```ts
489
+ const runner = createRunner({
490
+ flowli,
491
+ hooks: {
492
+ onJobStarted(jobId, jobName) {
493
+ logger.info({ event: "job.started", jobId, jobName });
494
+ },
495
+ onJobRetryScheduled(jobId, jobName, retryAt, error) {
496
+ logger.warn({
497
+ event: "job.retry_scheduled",
498
+ jobId,
499
+ jobName,
500
+ retryAt,
501
+ error,
502
+ });
503
+ },
504
+ onLeaseRecovered(jobId, jobName) {
505
+ logger.warn({ event: "job.lease_recovered", jobId, jobName });
506
+ },
507
+ },
508
+ });
509
+ ```
510
+
463
511
  ## Async Semantics
464
512
 
465
513
  Persisted execution in Flowli is:
@@ -1 +1,4 @@
1
+ /**
2
+ * The `flowli/bun-redis` entrypoint provides the Bun Redis-backed driver adapter.
3
+ */
1
4
  export { type BunRedisDriverOptions, type BunRedisLikeClient, bunRedisDriver, } from "./drivers/bun-redis.js";
@@ -3,6 +3,11 @@ type DefineJobsFunction = {
3
3
  <const TJobs extends JobsRecord, TContext extends FlowliContextRecord>(options: DefineJobsFactoryOptions<TJobs, TContext>): FlowliRuntime<TJobs, TContext>;
4
4
  withContext<TContext extends FlowliContextRecord>(): <const TJobs extends JobsRecord>(options: DefineJobsOptions<EnsureJobContexts<TJobs, TContext>, TContext>) => FlowliRuntime<EnsureJobContexts<TJobs, TContext>, TContext>;
5
5
  };
6
+ /**
7
+ * Creates a Flowli runtime from a runtime-scoped context, a jobs registry, and
8
+ * an optional async driver.
9
+ */
6
10
  export declare const defineJobs: DefineJobsFunction;
11
+ /** Returns the non-public runtime internals used by integrations and tests. */
7
12
  export declare function getFlowliRuntimeInternals<TJobs extends JobsRecord, TContext extends FlowliContextRecord>(runtime: FlowliRuntime<TJobs, TContext>): FlowliRuntimeInternals<TJobs, TContext>;
8
13
  export {};
@@ -1,21 +1,27 @@
1
1
  import type { StandardSchemaIssue } from "./types.js";
2
+ /** Base error type for all Flowli-specific failures. */
2
3
  export declare class FlowliError extends Error {
3
4
  readonly code: string;
4
5
  constructor(code: string, message: string);
5
6
  }
7
+ /** Raised when Flowli definitions or registry shape are invalid. */
6
8
  export declare class FlowliDefinitionError extends FlowliError {
7
9
  constructor(message: string);
8
10
  }
11
+ /** Raised when input or meta validation fails against the configured schema. */
9
12
  export declare class FlowliValidationError extends FlowliError {
10
13
  readonly issues: ReadonlyArray<StandardSchemaIssue>;
11
14
  constructor(message: string, issues: ReadonlyArray<StandardSchemaIssue>);
12
15
  }
16
+ /** Raised when a strategy is used in an invalid way for the current runtime. */
13
17
  export declare class FlowliStrategyError extends FlowliError {
14
18
  constructor(message: string);
15
19
  }
20
+ /** Raised when a driver is missing or behaves incompatibly. */
16
21
  export declare class FlowliDriverError extends FlowliError {
17
22
  constructor(message: string);
18
23
  }
24
+ /** Raised when schedule registration or cron handling fails. */
19
25
  export declare class FlowliSchedulingError extends FlowliError {
20
26
  constructor(message: string);
21
27
  }
@@ -1,9 +1,13 @@
1
1
  import type { FlowliContextRecord, JobDefinition, JobOptions, StandardSchemaV1 } from "./types.js";
2
+ /** A job factory already bound to a specific Flowli context type. */
2
3
  type JobFactory = {
3
4
  <TInputSchema extends StandardSchemaV1<any, any>, TMetaSchema extends StandardSchemaV1<any, any> | undefined, TResult>(name: string, options: JobOptions<TInputSchema, TMetaSchema, FlowliContextRecord, TResult>): JobDefinition<TInputSchema, TMetaSchema, FlowliContextRecord, TResult>;
4
5
  withContext<TContext extends FlowliContextRecord>(): <TInputSchema extends StandardSchemaV1<any, any>, TMetaSchema extends StandardSchemaV1<any, any> | undefined, TResult>(name: string, options: JobOptions<TInputSchema, TMetaSchema, TContext, TResult>) => JobDefinition<TInputSchema, TMetaSchema, TContext, TResult>;
5
6
  };
7
+ /** The typed factory signature returned when a runtime binds `ctx` shape. */
6
8
  export type ContextualJobFactory<TContext extends FlowliContextRecord> = <TInputSchema extends StandardSchemaV1<any, any>, TMetaSchema extends StandardSchemaV1<any, any> | undefined, TResult>(name: string, options: JobOptions<TInputSchema, TMetaSchema, TContext, TResult>) => JobDefinition<TInputSchema, TMetaSchema, TContext, TResult>;
9
+ /** Defines a Flowli job with typed input, optional meta, and a handler. */
7
10
  export declare const job: JobFactory;
11
+ /** Creates a contextual `job()` factory for runtime-first authoring flows. */
8
12
  export declare function createContextualJobFactory<TContext extends FlowliContextRecord>(): ContextualJobFactory<TContext>;
9
13
  export {};
@@ -1,3 +1,4 @@
1
+ /** A normalized validation issue reported by a Standard Schema-compatible validator. */
1
2
  export interface StandardSchemaIssue {
2
3
  message: string;
3
4
  path?: ReadonlyArray<unknown>;
@@ -9,6 +10,7 @@ export interface StandardSchemaFailure {
9
10
  readonly issues: ReadonlyArray<StandardSchemaIssue>;
10
11
  }
11
12
  export type StandardSchemaResult<TValue> = StandardSchemaSuccess<TValue> | StandardSchemaFailure;
13
+ /** The minimal Standard Schema v1 contract Flowli consumes for validation and inference. */
12
14
  export interface StandardSchemaV1<Input = unknown, Output = Input> {
13
15
  readonly "~standard": {
14
16
  readonly version: number;
@@ -22,37 +24,46 @@ export interface StandardSchemaV1<Input = unknown, Output = Input> {
22
24
  }
23
25
  export type InferInput<TSchema extends StandardSchemaV1<any, any>> = TSchema extends StandardSchemaV1<infer TInput, any> ? TInput : never;
24
26
  export type InferOutput<TSchema extends StandardSchemaV1<any, any>> = TSchema extends StandardSchemaV1<any, infer TOutput> ? TOutput : never;
27
+ /** The shared runtime-scoped dependency object passed to Flowli job handlers as `ctx`. */
25
28
  export interface FlowliContextRecord {
26
29
  readonly [key: PropertyKey]: unknown;
27
30
  }
31
+ /** A static context object or lazy resolver used when constructing a Flowli runtime. */
28
32
  export type FlowliContextResolver<TContext extends FlowliContextRecord> = TContext | (() => TContext | Promise<TContext>);
29
33
  export type ResolveContext<TResolver> = TResolver extends () => infer TResult ? Awaited<TResult> : TResolver extends FlowliContextRecord ? TResolver : never;
34
+ /** Shared retry and persistence defaults that can be applied globally or per job. */
30
35
  export interface JobDefaults {
31
36
  readonly maxAttempts?: number;
32
37
  readonly backoff?: BackoffOptions;
33
38
  }
39
+ /** Configures a randomized multiplier for retry backoff delay. */
34
40
  export interface BackoffJitterOptions {
35
41
  readonly minRatio: number;
36
42
  readonly maxRatio: number;
37
43
  }
44
+ /** Defines how retries are delayed for persisted async execution. */
38
45
  export interface BackoffOptions {
39
46
  readonly type: "fixed" | "exponential";
40
47
  readonly delayMs: number;
41
48
  readonly maxDelayMs?: number;
42
49
  readonly jitter?: boolean | BackoffJitterOptions;
43
50
  }
51
+ /** Per-invocation options shared by all execution strategies. */
44
52
  export interface FlowliInvocationOptions<TMeta> {
45
53
  readonly meta?: TMeta;
46
54
  }
47
55
  export interface PersistedInvocationOptions<TMeta> extends FlowliInvocationOptions<TMeta>, JobDefaults {
48
56
  }
57
+ /** The payload required to register a recurring schedule for a job. */
49
58
  export interface ScheduleInvocation<TInput, TMeta> {
50
59
  readonly key?: string;
51
60
  readonly cron: string;
52
61
  readonly input: TInput;
53
62
  readonly meta?: TMeta;
54
63
  }
64
+ /** A supported delay literal or numeric millisecond delay. */
55
65
  export type DelayValue = number | `${number}${"ms" | "s" | "m" | "h" | "d"}`;
66
+ /** The receipt returned when a job is persisted for async execution. */
56
67
  export interface JobReceipt {
57
68
  readonly id: string;
58
69
  readonly name: string;
@@ -60,18 +71,24 @@ export interface JobReceipt {
60
71
  readonly scheduledFor: number;
61
72
  readonly attemptsMade: number;
62
73
  }
74
+ /** The receipt returned when a recurring schedule is registered. */
63
75
  export interface ScheduleReceipt {
64
76
  readonly key: string;
65
77
  readonly name: string;
66
78
  readonly cron: string;
67
79
  readonly nextRunAt: number;
68
80
  }
81
+ /** The persisted lifecycle states a job can move through in Flowli. */
69
82
  export type JobState = "queued" | "active" | "completed" | "failed" | "scheduled";
83
+ /** The inspectable persisted job states exposed by `flowli.inspect`. */
84
+ export type InspectableJobState = Exclude<JobState, "scheduled">;
85
+ /** The typed arguments delivered to a Flowli job handler. */
70
86
  export interface JobHandlerArgs<TInput, TContext, TMeta> {
71
87
  readonly input: TInput;
72
88
  readonly ctx: TContext;
73
89
  readonly meta: TMeta | undefined;
74
90
  }
91
+ /** A fully-defined Flowli job produced by `job()` or a contextual job factory. */
75
92
  export interface JobDefinition<TInputSchema extends StandardSchemaV1<any, any>, TMetaSchema extends StandardSchemaV1<any, any> | undefined, TContext extends FlowliContextRecord, TResult> {
76
93
  readonly __flowli: "job";
77
94
  readonly name: string;
@@ -82,6 +99,7 @@ export interface JobDefinition<TInputSchema extends StandardSchemaV1<any, any>,
82
99
  readonly description?: string;
83
100
  readonly tags?: ReadonlyArray<string>;
84
101
  }
102
+ /** Options accepted by `job()` when defining a job. */
85
103
  export interface JobOptions<TInputSchema extends StandardSchemaV1<any, any>, TMetaSchema extends StandardSchemaV1<any, any> | undefined, TContext extends FlowliContextRecord, TResult> {
86
104
  readonly input: TInputSchema;
87
105
  readonly meta?: TMetaSchema;
@@ -97,46 +115,80 @@ export type JobsRecord = {
97
115
  export type JobInput<TJob extends AnyJobDefinition> = InferOutput<TJob["input"]>;
98
116
  export type JobMeta<TJob extends AnyJobDefinition> = NonNullable<TJob["meta"]> extends StandardSchemaV1<any, any> ? InferOutput<NonNullable<TJob["meta"]>> : undefined;
99
117
  export type JobResult<TJob extends AnyJobDefinition> = Awaited<ReturnType<TJob["handler"]>>;
118
+ /** The internal driver contract implemented by Redis-backed adapters. */
100
119
  export interface FlowliDriver {
101
120
  readonly kind: string;
102
121
  enqueue(record: PersistedJobRecord): Promise<JobReceipt>;
103
122
  registerSchedule(record: ScheduleRecord): Promise<ScheduleReceipt>;
104
- recoverExpiredLeases(now: number): Promise<number>;
123
+ recoverExpiredLeases(now: number): Promise<ReadonlyArray<PersistedJobRecord>>;
105
124
  acquireNextReady(now: number, leaseMs: number): Promise<AcquiredJobRecord | null>;
106
125
  renewLease(jobId: string, token: string, leaseMs: number): Promise<boolean>;
107
126
  markCompleted(acquired: AcquiredJobRecord, finishedAt: number): Promise<void>;
108
127
  markFailed(acquired: AcquiredJobRecord, finishedAt: number, error: PersistedJobError): Promise<MarkFailedResult>;
109
128
  materializeDueSchedules(now: number, leaseMs: number): Promise<number>;
129
+ getJob(id: string): Promise<PersistedJobRecord | null>;
130
+ getSchedule(key: string): Promise<ScheduleRecord | null>;
131
+ getQueueCounts(): Promise<FlowliQueueCounts>;
132
+ getJobsByState(state: InspectableJobState, options?: FlowliInspectListOptions): Promise<ReadonlyArray<PersistedJobRecord>>;
133
+ getSchedules(options?: FlowliInspectListOptions): Promise<ReadonlyArray<ScheduleRecord>>;
110
134
  }
135
+ /** Options for defining a runtime from an already-declared jobs object. */
111
136
  export interface DefineJobsOptions<TJobs extends JobsRecord, TContext extends FlowliContextRecord> {
112
137
  readonly jobs: TJobs;
113
138
  readonly context: FlowliContextResolver<TContext>;
114
139
  readonly driver?: FlowliDriver;
115
140
  readonly defaults?: JobDefaults;
116
141
  }
142
+ /** The builder object supplied to runtime-first `defineJobs({ jobs })`. */
117
143
  export interface DefineJobsBuilder<TContext extends FlowliContextRecord> {
118
144
  readonly job: <TInputSchema extends StandardSchemaV1<any, any>, TMetaSchema extends StandardSchemaV1<any, any> | undefined, TResult>(name: string, options: JobOptions<TInputSchema, TMetaSchema, TContext, TResult>) => JobDefinition<TInputSchema, TMetaSchema, TContext, TResult>;
119
145
  }
146
+ /** Options for the runtime-first `defineJobs({ jobs: ({ job }) => ... })` API. */
120
147
  export interface DefineJobsFactoryOptions<TJobs extends JobsRecord, TContext extends FlowliContextRecord> {
121
148
  readonly jobs: (builder: DefineJobsBuilder<TContext>) => TJobs;
122
149
  readonly context: FlowliContextResolver<TContext>;
123
150
  readonly driver?: FlowliDriver;
124
151
  readonly defaults?: JobDefaults;
125
152
  }
153
+ /** Ensures reusable predeclared jobs are compatible with runtime context. */
126
154
  export type EnsureJobContexts<TJobs extends JobsRecord, TContext extends FlowliContextRecord> = {
127
155
  readonly [TKey in keyof TJobs]: TJobs[TKey] extends JobDefinition<StandardSchemaV1<any, any>, StandardSchemaV1<any, any> | undefined, infer TJobContext, unknown> ? TContext extends TJobContext ? TJobs[TKey] : never : never;
128
156
  };
157
+ /** The public surface exposed for each Flowli job on the runtime. */
129
158
  export interface FlowliJobSurface<TJob extends AnyJobDefinition> {
130
159
  run(input: JobInput<TJob>, options?: FlowliInvocationOptions<JobMeta<TJob>>): Promise<JobResult<TJob>>;
131
160
  enqueue(input: JobInput<TJob>, options?: PersistedInvocationOptions<JobMeta<TJob>>): Promise<JobReceipt>;
132
161
  delay(delay: DelayValue, input: JobInput<TJob>, options?: PersistedInvocationOptions<JobMeta<TJob>>): Promise<JobReceipt>;
133
162
  schedule(invocation: ScheduleInvocation<JobInput<TJob>, JobMeta<TJob>>): Promise<ScheduleReceipt>;
134
163
  }
164
+ /** List options for read-side inspection queries. */
165
+ export interface FlowliInspectListOptions {
166
+ readonly limit?: number;
167
+ }
168
+ /** Aggregate queue counts returned by the inspect surface. */
169
+ export interface FlowliQueueCounts {
170
+ readonly queued: number;
171
+ readonly active: number;
172
+ readonly completed: number;
173
+ readonly failed: number;
174
+ readonly schedules: number;
175
+ }
176
+ /** Read-side inspection helpers for persisted jobs and schedules. */
177
+ export interface FlowliInspectSurface {
178
+ getJob(id: string): Promise<PersistedJobRecord | null>;
179
+ getSchedule(key: string): Promise<ScheduleRecord | null>;
180
+ getQueueCounts(): Promise<FlowliQueueCounts>;
181
+ getJobsByState(state: InspectableJobState, options?: FlowliInspectListOptions): Promise<ReadonlyArray<PersistedJobRecord>>;
182
+ getSchedules(options?: FlowliInspectListOptions): Promise<ReadonlyArray<ScheduleRecord>>;
183
+ }
184
+ /** The Flowli runtime returned by `defineJobs()`. */
135
185
  export type FlowliRuntime<TJobs extends JobsRecord, TContext extends FlowliContextRecord> = {
136
186
  readonly [TKey in keyof TJobs]: FlowliJobSurface<TJobs[TKey]>;
137
187
  } & {
188
+ readonly inspect: FlowliInspectSurface;
138
189
  readonly [FLOWLI_RUNTIME_SYMBOL]: FlowliRuntimeInternals<TJobs, TContext>;
139
190
  };
191
+ /** The hidden runtime internals attached to a Flowli runtime instance. */
140
192
  export interface FlowliRuntimeInternals<TJobs extends JobsRecord, TContext extends FlowliContextRecord> {
141
193
  readonly jobs: TJobs;
142
194
  readonly jobsByName: Map<string, AnyJobDefinition>;
@@ -144,6 +196,7 @@ export interface FlowliRuntimeInternals<TJobs extends JobsRecord, TContext exten
144
196
  readonly driver?: FlowliDriver;
145
197
  readonly defaults: JobDefaults;
146
198
  }
199
+ /** The internal symbol used to attach Flowli runtime internals to an instance. */
147
200
  export declare const FLOWLI_RUNTIME_SYMBOL: unique symbol;
148
201
  export interface PersistedJobError {
149
202
  readonly code: string;
@@ -1,5 +1,6 @@
1
1
  import type { FlowliDriver } from "../core/types.js";
2
2
  import { type RedisCommandAdapter } from "./shared.js";
3
+ /** The subset of a Bun Redis client Flowli requires. */
3
4
  export interface BunRedisLikeClient {
4
5
  get(key: string): Promise<string | null>;
5
6
  set(key: string, value: string, options?: {
@@ -16,9 +17,12 @@ export interface BunRedisLikeClient {
16
17
  };
17
18
  }): Promise<string[]>;
18
19
  }
20
+ /** Options for creating the `flowli/bun-redis` driver. */
19
21
  export interface BunRedisDriverOptions {
20
22
  readonly client: BunRedisLikeClient;
21
23
  readonly prefix?: string;
22
24
  }
25
+ /** Creates a Flowli driver backed by a Bun Redis-compatible client. */
23
26
  export declare function bunRedisDriver(options: BunRedisDriverOptions): FlowliDriver;
27
+ /** Adapts Bun Redis commands to Flowli's shared Redis driver contract. */
24
28
  export declare function createBunRedisAdapter(client: BunRedisLikeClient): RedisCommandAdapter;
@@ -1,5 +1,6 @@
1
1
  import type { FlowliDriver } from "../core/types.js";
2
2
  import { type RedisCommandAdapter } from "./shared.js";
3
+ /** The subset of an ioredis client Flowli requires. */
3
4
  export interface IoredisLikeClient {
4
5
  get(key: string): Promise<string | null>;
5
6
  set(key: string, value: string, modeOrOptions?: "PX" | "NX" | undefined, ttlOrMode?: number | "NX" | "PX", maybeMode?: "NX" | "PX"): Promise<"OK" | null>;
@@ -8,9 +9,12 @@ export interface IoredisLikeClient {
8
9
  zrem(key: string, member: string): Promise<number>;
9
10
  zrangebyscore(key: string, min: number | string, max: number | string, limitToken?: "LIMIT", offset?: number, count?: number): Promise<string[]>;
10
11
  }
12
+ /** Options for creating the `flowli/ioredis` driver. */
11
13
  export interface IoredisDriverOptions {
12
14
  readonly client: IoredisLikeClient;
13
15
  readonly prefix?: string;
14
16
  }
17
+ /** Creates a Flowli driver backed by an ioredis-compatible client. */
15
18
  export declare function ioredisDriver(options: IoredisDriverOptions): FlowliDriver;
19
+ /** Adapts ioredis commands to Flowli's shared Redis driver contract. */
16
20
  export declare function createIoredisAdapter(client: IoredisLikeClient): RedisCommandAdapter;
@@ -1,5 +1,6 @@
1
1
  import type { FlowliDriver } from "../core/types.js";
2
2
  import { type RedisCommandAdapter } from "./shared.js";
3
+ /** The subset of a node-redis client Flowli requires. */
3
4
  export interface NodeRedisLikeClient {
4
5
  get(key: string): Promise<string | null>;
5
6
  set(key: string, value: string, options?: {
@@ -19,9 +20,12 @@ export interface NodeRedisLikeClient {
19
20
  };
20
21
  }): Promise<string[]>;
21
22
  }
23
+ /** Options for creating the `flowli/redis` driver. */
22
24
  export interface RedisDriverOptions {
23
25
  readonly client: NodeRedisLikeClient;
24
26
  readonly prefix?: string;
25
27
  }
28
+ /** Creates a Flowli driver backed by a node-redis-compatible client. */
26
29
  export declare function redisDriver(options: RedisDriverOptions): FlowliDriver;
30
+ /** Adapts node-redis commands to Flowli's shared Redis driver contract. */
27
31
  export declare function createNodeRedisAdapter(client: NodeRedisLikeClient): RedisCommandAdapter;
package/dist/hono.d.ts CHANGED
@@ -1 +1,5 @@
1
+ /**
2
+ * The `flowli/hono` entrypoint provides middleware helpers for attaching an
3
+ * existing Flowli runtime to Hono context.
4
+ */
1
5
  export { type HonoFlowliVariables, type HonoJobsOptions, type HonoLikeContext, type HonoLikeNext, honoJobs, } from "./integrations/hono.js";
package/dist/index.d.ts CHANGED
@@ -1,4 +1,8 @@
1
+ /**
2
+ * Flowli's root entrypoint exports the typed jobs runtime, core errors, and
3
+ * essential public types without pulling in driver or framework code.
4
+ */
1
5
  export { defineJobs } from "./core/define-jobs.js";
2
6
  export { FlowliDefinitionError, FlowliDriverError, FlowliError, FlowliSchedulingError, FlowliStrategyError, FlowliValidationError, } from "./core/errors.js";
3
7
  export { createContextualJobFactory, job } from "./core/job.js";
4
- export type { BackoffJitterOptions, BackoffOptions, DefineJobsBuilder, DelayValue, FlowliContextRecord, FlowliContextResolver, FlowliDriver, FlowliInvocationOptions, FlowliJobSurface, FlowliRuntime, JobDefaults, JobDefinition, JobHandlerArgs, JobReceipt, ScheduleInvocation, ScheduleReceipt, StandardSchemaIssue, StandardSchemaV1, } from "./core/types.js";
8
+ export type { BackoffJitterOptions, BackoffOptions, DefineJobsBuilder, DelayValue, FlowliContextRecord, FlowliContextResolver, FlowliDriver, FlowliInspectListOptions, FlowliInspectSurface, FlowliInvocationOptions, FlowliJobSurface, FlowliQueueCounts, FlowliRuntime, InspectableJobState, JobDefaults, JobDefinition, JobHandlerArgs, JobReceipt, ScheduleInvocation, ScheduleReceipt, StandardSchemaIssue, StandardSchemaV1, } from "./core/types.js";
@@ -1,10 +1,15 @@
1
1
  import type { FlowliContextRecord, FlowliRuntime, JobsRecord } from "../core/types.js";
2
+ /** The minimal Hono context contract required by `honoJobs()`. */
2
3
  export interface HonoLikeContext {
3
4
  set(key: string, value: unknown): void;
4
5
  }
6
+ /** The continuation callback shape used by Hono middleware. */
5
7
  export type HonoLikeNext = () => Promise<unknown>;
8
+ /** Options for attaching a Flowli runtime to Hono context. */
6
9
  export interface HonoJobsOptions<TKey extends string = "flowli"> {
7
10
  readonly key?: TKey;
8
11
  }
12
+ /** The typed variables shape added to Hono context by `honoJobs()`. */
9
13
  export type HonoFlowliVariables<TFlowli, TKey extends string = "flowli"> = Record<TKey, TFlowli>;
14
+ /** Creates Hono middleware that attaches an existing Flowli runtime to `c`. */
10
15
  export declare function honoJobs<TJobs extends JobsRecord, TContext extends FlowliContextRecord, TKey extends string = "flowli">(flowli: FlowliRuntime<TJobs, TContext>, options?: HonoJobsOptions<TKey>): (context: HonoLikeContext, next: HonoLikeNext) => Promise<void>;
@@ -1,18 +1,26 @@
1
1
  import type { FlowliContextRecord, FlowliRuntime, JobsRecord } from "../core/types.js";
2
+ /** A minimal route params record compatible with Next.js route handlers. */
2
3
  export type NextRouteParams = Record<string, string | ReadonlyArray<string> | undefined>;
4
+ /** The request context object supplied by Next.js route handlers. */
3
5
  export interface NextRouteContext<TParams extends NextRouteParams = NextRouteParams> {
4
6
  readonly params?: TParams | Promise<TParams>;
5
7
  }
8
+ /** Arguments passed to a `nextRoute()` handler. */
6
9
  export interface NextRouteHandlerArgs<TFlowli, TParams extends NextRouteParams = NextRouteParams, TRequest extends Request = Request> {
7
10
  readonly request: TRequest;
8
11
  readonly context: NextRouteContext<TParams>;
9
12
  readonly params: TParams | undefined;
10
13
  readonly flowli: TFlowli;
11
14
  }
15
+ /** A typed handler for the `nextRoute()` integration helper. */
12
16
  export type NextRouteHandler<TFlowli, TParams extends NextRouteParams = NextRouteParams, TRequest extends Request = Request, TResult = Response> = (args: NextRouteHandlerArgs<TFlowli, TParams, TRequest>) => TResult | Promise<TResult>;
17
+ /** Tools injected into a `nextAction()` handler. */
13
18
  export interface NextActionTools<TFlowli> {
14
19
  readonly flowli: TFlowli;
15
20
  }
21
+ /** A typed handler for the `nextAction()` integration helper. */
16
22
  export type NextActionHandler<TFlowli, TArgs extends ReadonlyArray<unknown>, TResult> = (tools: NextActionTools<TFlowli>, ...args: TArgs) => TResult | Promise<TResult>;
23
+ /** Wraps a Next.js route handler with access to an existing Flowli runtime. */
17
24
  export declare function nextRoute<TJobs extends JobsRecord, TContext extends FlowliContextRecord, TParams extends NextRouteParams = NextRouteParams, TRequest extends Request = Request, TResult = Response>(flowli: FlowliRuntime<TJobs, TContext>, handler: NextRouteHandler<FlowliRuntime<TJobs, TContext>, TParams, TRequest, TResult>): (request: TRequest, context?: NextRouteContext<TParams>) => Promise<Awaited<TResult>>;
25
+ /** Wraps a Next.js server action with access to an existing Flowli runtime. */
18
26
  export declare function nextAction<TJobs extends JobsRecord, TContext extends FlowliContextRecord, TArgs extends ReadonlyArray<unknown>, TResult>(flowli: FlowliRuntime<TJobs, TContext>, handler: NextActionHandler<FlowliRuntime<TJobs, TContext>, TArgs, TResult>): (...args: TArgs) => Promise<Awaited<TResult>>;
@@ -1,20 +1,28 @@
1
1
  import type { FlowliContextRecord, FlowliRuntime, JobsRecord } from "../core/types.js";
2
+ /** A minimal params record compatible with TanStack Start server routes. */
2
3
  export type TanStackStartRouteParams = Record<string, string | ReadonlyArray<string> | undefined>;
4
+ /** The generic server route context provided by TanStack Start. */
3
5
  export interface TanStackStartRouteContext {
4
6
  readonly [key: PropertyKey]: unknown;
5
7
  }
8
+ /** Arguments passed to a `tanstackStartRoute()` handler. */
6
9
  export interface TanStackStartRouteHandlerArgs<TFlowli, TParams extends TanStackStartRouteParams = TanStackStartRouteParams, TContext extends TanStackStartRouteContext = TanStackStartRouteContext, TRequest extends Request = Request> {
7
10
  readonly request: TRequest;
8
11
  readonly params: TParams;
9
12
  readonly context: TContext;
10
13
  readonly flowli: TFlowli;
11
14
  }
15
+ /** A typed handler for TanStack Start route integration. */
12
16
  export type TanStackStartRouteHandler<TFlowli, TParams extends TanStackStartRouteParams = TanStackStartRouteParams, TContext extends TanStackStartRouteContext = TanStackStartRouteContext, TRequest extends Request = Request, TResult = Response> = (args: TanStackStartRouteHandlerArgs<TFlowli, TParams, TContext, TRequest>) => TResult | Promise<TResult>;
17
+ /** Tools injected into a TanStack Start server function handler. */
13
18
  export interface TanStackStartServerFnTools<TFlowli> {
14
19
  readonly flowli: TFlowli;
15
20
  }
16
21
  type StripFlowli<TArgs extends object> = Omit<TArgs, keyof TanStackStartServerFnTools<unknown>>;
22
+ /** A typed handler for TanStack Start server function integration. */
17
23
  export type TanStackStartServerFnHandler<TFlowli, TArgs extends TanStackStartServerFnTools<TFlowli>, TResult> = (args: TArgs) => TResult | Promise<TResult>;
24
+ /** Wraps a TanStack Start route with access to an existing Flowli runtime. */
18
25
  export declare function tanstackStartRoute<TJobs extends JobsRecord, TContext extends FlowliContextRecord, TParams extends TanStackStartRouteParams = TanStackStartRouteParams, TRouteContext extends TanStackStartRouteContext = TanStackStartRouteContext, TRequest extends Request = Request, TResult = Response>(flowli: FlowliRuntime<TJobs, TContext>, handler: TanStackStartRouteHandler<FlowliRuntime<TJobs, TContext>, TParams, TRouteContext, TRequest, TResult>): (args: Omit<TanStackStartRouteHandlerArgs<FlowliRuntime<TJobs, TContext>, TParams, TRouteContext, TRequest>, "flowli">) => Promise<Awaited<TResult>>;
26
+ /** Wraps a TanStack Start server function with Flowli runtime access. */
19
27
  export declare function tanstackStartServerFn<TJobs extends JobsRecord, TContext extends FlowliContextRecord, TArgs extends TanStackStartServerFnTools<FlowliRuntime<TJobs, TContext>>, TResult>(flowli: FlowliRuntime<TJobs, TContext>, handler: TanStackStartServerFnHandler<FlowliRuntime<TJobs, TContext>, TArgs, TResult>): (args: StripFlowli<TArgs>) => Promise<Awaited<TResult>>;
20
28
  export {};
package/dist/ioredis.d.ts CHANGED
@@ -1 +1,4 @@
1
+ /**
2
+ * The `flowli/ioredis` entrypoint provides the ioredis-backed driver adapter.
3
+ */
1
4
  export { type IoredisDriverOptions, type IoredisLikeClient, ioredisDriver, } from "./drivers/ioredis.js";
package/dist/next.d.ts CHANGED
@@ -1 +1,5 @@
1
+ /**
2
+ * The `flowli/next` entrypoint provides lightweight helpers for Next.js route
3
+ * handlers and server actions.
4
+ */
1
5
  export { type NextActionHandler, type NextActionTools, type NextRouteContext, type NextRouteHandler, type NextRouteHandlerArgs, type NextRouteParams, nextAction, nextRoute, } from "./integrations/next.js";
package/dist/redis.d.ts CHANGED
@@ -1 +1,4 @@
1
+ /**
2
+ * The `flowli/redis` entrypoint provides the node-redis-backed driver adapter.
3
+ */
1
4
  export { type NodeRedisLikeClient, type RedisDriverOptions, redisDriver, } from "./drivers/redis.js";
@@ -1,3 +1,4 @@
1
1
  import type { FlowliContextRecord, JobsRecord } from "../core/types.js";
2
2
  import type { FlowliRunner, RunnerOptions } from "./types.js";
3
+ /** Creates an explicit runner for queued, delayed, and scheduled Flowli jobs. */
3
4
  export declare function createRunner<TJobs extends JobsRecord, TContext extends FlowliContextRecord>(options: RunnerOptions<TJobs, TContext>): FlowliRunner;
@@ -1,10 +1,13 @@
1
- import type { FlowliContextRecord, FlowliRuntime, JobsRecord, PersistedJobError } from "../core/types.js";
1
+ import type { FlowliContextRecord, FlowliRuntime, JobsRecord, PersistedJobError, PersistedJobRecord } from "../core/types.js";
2
+ /** Lifecycle hooks emitted by the Flowli runner during async execution. */
2
3
  export interface RunnerHooks {
3
4
  readonly onJobStarted?: (jobId: string, jobName: string) => void | Promise<void>;
4
5
  readonly onJobCompleted?: (jobId: string, jobName: string) => void | Promise<void>;
5
6
  readonly onJobFailed?: (jobId: string, jobName: string, error: PersistedJobError) => void | Promise<void>;
6
7
  readonly onJobRetryScheduled?: (jobId: string, jobName: string, retryAt: number, error: PersistedJobError) => void | Promise<void>;
8
+ readonly onLeaseRecovered?: (jobId: string, jobName: string, record: PersistedJobRecord) => void | Promise<void>;
7
9
  }
10
+ /** Options for constructing a Flowli runner from an existing runtime. */
8
11
  export interface RunnerOptions<TJobs extends JobsRecord, TContext extends FlowliContextRecord> {
9
12
  readonly flowli: FlowliRuntime<TJobs, TContext>;
10
13
  readonly concurrency?: number;
@@ -13,6 +16,7 @@ export interface RunnerOptions<TJobs extends JobsRecord, TContext extends Flowli
13
16
  readonly maxJobsPerTick?: number;
14
17
  readonly hooks?: RunnerHooks;
15
18
  }
19
+ /** The explicit async processor returned by `createRunner()`. */
16
20
  export interface FlowliRunner {
17
21
  readonly running: boolean;
18
22
  runOnce(): Promise<number>;
package/dist/runner.d.ts CHANGED
@@ -1,2 +1,6 @@
1
+ /**
2
+ * The `flowli/runner` entrypoint provides the explicit async processor used to
3
+ * execute queued, delayed, and scheduled work.
4
+ */
1
5
  export { createRunner } from "./runner/create-runner.js";
2
6
  export type { FlowliRunner, RunnerHooks, RunnerOptions, } from "./runner/types.js";
@@ -0,0 +1,2 @@
1
+ import type { FlowliContextRecord, FlowliInspectSurface, FlowliRuntimeInternals, JobsRecord } from "../core/types.js";
2
+ export declare function createInspectSurface<TJobs extends JobsRecord, TContext extends FlowliContextRecord>(internals: FlowliRuntimeInternals<TJobs, TContext>): FlowliInspectSurface;
@@ -1 +1,5 @@
1
+ /**
2
+ * The `flowli/tanstack-start` entrypoint provides helpers for TanStack Start
3
+ * server routes and server functions.
4
+ */
1
5
  export { type TanStackStartRouteContext, type TanStackStartRouteHandler, type TanStackStartRouteHandlerArgs, type TanStackStartRouteParams, type TanStackStartServerFnHandler, type TanStackStartServerFnTools, tanstackStartRoute, tanstackStartServerFn, } from "./integrations/tanstack-start.js";
package/jsr.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://jsr.io/schema/config-file.v1.json",
3
3
  "name": "@alialnaghmoush/flowli",
4
- "version": "0.3.0",
4
+ "version": "0.4.0",
5
5
  "exports": {
6
6
  ".": "./src/index.ts",
7
7
  "./ioredis": "./src/ioredis.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Flowli is a jobs runtime with a code-first API, first-class execution strategies, runtime-scoped context injection, and pluggable Redis drivers.",
5
5
  "keywords": [
6
6
  "jobs",