@supergrowthai/tq 1.0.11 → 1.0.13

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 (100) hide show
  1. package/README.md +338 -20
  2. package/dist/AsyncActions-BOO1ikWz.cjs +241 -0
  3. package/dist/AsyncActions-BOO1ikWz.cjs.map +1 -0
  4. package/dist/AsyncActions-CZYO8ShR.js +242 -0
  5. package/dist/AsyncActions-CZYO8ShR.js.map +1 -0
  6. package/dist/{PrismaAdapter-CvM_XNtE.cjs → PrismaAdapter-CUIWhjms.cjs} +57 -81
  7. package/dist/PrismaAdapter-CUIWhjms.cjs.map +1 -0
  8. package/dist/{PrismaAdapter-Dy7MV090.js → PrismaAdapter-D5ACKPbS.js} +57 -81
  9. package/dist/PrismaAdapter-D5ACKPbS.js.map +1 -0
  10. package/dist/adapters/index.cjs +1 -1
  11. package/dist/adapters/index.mjs +1 -1
  12. package/dist/client-BxG7LzLv.cjs +90 -0
  13. package/dist/client-BxG7LzLv.cjs.map +1 -0
  14. package/dist/client-dvHNt8qU.js +91 -0
  15. package/dist/client-dvHNt8qU.js.map +1 -0
  16. package/dist/core/Actions.cjs +184 -16
  17. package/dist/core/Actions.cjs.map +1 -1
  18. package/dist/core/Actions.mjs +184 -16
  19. package/dist/core/Actions.mjs.map +1 -1
  20. package/dist/core/async/AsyncActions.cjs +4 -98
  21. package/dist/core/async/AsyncActions.cjs.map +1 -1
  22. package/dist/core/async/AsyncActions.mjs +4 -98
  23. package/dist/core/async/AsyncActions.mjs.map +1 -1
  24. package/dist/core/async/AsyncTaskManager.cjs +133 -22
  25. package/dist/core/async/AsyncTaskManager.cjs.map +1 -1
  26. package/dist/core/async/AsyncTaskManager.mjs +133 -22
  27. package/dist/core/async/AsyncTaskManager.mjs.map +1 -1
  28. package/dist/index.cjs +517 -35
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.mjs +517 -35
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/src/adapters/ITaskStorageAdapter.d.cts +0 -5
  33. package/dist/src/adapters/ITaskStorageAdapter.d.ts +0 -5
  34. package/dist/src/adapters/InMemoryAdapter.d.cts +0 -2
  35. package/dist/src/adapters/InMemoryAdapter.d.ts +0 -2
  36. package/dist/src/adapters/MongoDbAdapter.d.cts +0 -2
  37. package/dist/src/adapters/MongoDbAdapter.d.ts +0 -2
  38. package/dist/src/adapters/PrismaAdapter.d.cts +0 -2
  39. package/dist/src/adapters/PrismaAdapter.d.ts +0 -2
  40. package/dist/src/adapters/types.d.cts +7 -0
  41. package/dist/src/adapters/types.d.ts +7 -0
  42. package/dist/src/core/Actions.d.cts +25 -2
  43. package/dist/src/core/Actions.d.ts +25 -2
  44. package/dist/src/core/TaskHandler.d.cts +13 -5
  45. package/dist/src/core/TaskHandler.d.ts +13 -5
  46. package/dist/src/core/TaskRunner.d.cts +16 -1
  47. package/dist/src/core/TaskRunner.d.ts +16 -1
  48. package/dist/src/core/async/AsyncActions.d.cts +20 -1
  49. package/dist/src/core/async/AsyncActions.d.ts +20 -1
  50. package/dist/src/core/async/AsyncTaskManager.d.cts +36 -4
  51. package/dist/src/core/async/AsyncTaskManager.d.ts +36 -4
  52. package/dist/src/core/async/async-task-manager.d.cts +21 -3
  53. package/dist/src/core/async/async-task-manager.d.ts +21 -3
  54. package/dist/src/core/async/retry-utils.d.cts +15 -0
  55. package/dist/src/core/async/retry-utils.d.ts +15 -0
  56. package/dist/src/core/base/interfaces.d.cts +10 -2
  57. package/dist/src/core/base/interfaces.d.ts +10 -2
  58. package/dist/src/core/entity/IEntityProjectionProvider.d.cts +45 -0
  59. package/dist/src/core/entity/IEntityProjectionProvider.d.ts +45 -0
  60. package/dist/src/core/entity/index.d.cts +1 -0
  61. package/dist/src/core/entity/index.d.ts +1 -0
  62. package/dist/src/core/flow/FlowMiddleware.d.cts +26 -0
  63. package/dist/src/core/flow/FlowMiddleware.d.ts +26 -0
  64. package/dist/src/core/flow/IFlowBarrierProvider.d.cts +46 -0
  65. package/dist/src/core/flow/IFlowBarrierProvider.d.ts +46 -0
  66. package/dist/src/core/flow/InMemoryFlowBarrierProvider.d.cts +10 -0
  67. package/dist/src/core/flow/InMemoryFlowBarrierProvider.d.ts +10 -0
  68. package/dist/src/core/flow/index.d.cts +4 -0
  69. package/dist/src/core/flow/index.d.ts +4 -0
  70. package/dist/src/core/flow/types.d.cts +82 -0
  71. package/dist/src/core/flow/types.d.ts +82 -0
  72. package/dist/src/core/lifecycle.d.cts +9 -4
  73. package/dist/src/core/lifecycle.d.ts +9 -4
  74. package/dist/src/core/log-context.d.cts +10 -0
  75. package/dist/src/core/log-context.d.ts +10 -0
  76. package/dist/src/index.d.cts +4 -0
  77. package/dist/src/index.d.ts +4 -0
  78. package/dist/src/test/adapter-consistency.test.d.cts +11 -0
  79. package/dist/src/test/adapter-consistency.test.d.ts +11 -0
  80. package/dist/src/test/immediate-mode-bugs.test.d.cts +11 -0
  81. package/dist/src/test/immediate-mode-bugs.test.d.ts +11 -0
  82. package/dist/src/test/rfc-001-result-persistence.test.d.cts +17 -0
  83. package/dist/src/test/rfc-001-result-persistence.test.d.ts +17 -0
  84. package/dist/src/test/rfc-002-flow-orchestration.test.d.cts +24 -0
  85. package/dist/src/test/rfc-002-flow-orchestration.test.d.ts +24 -0
  86. package/dist/src/test/rfc-003-entity-projection.test.d.cts +14 -0
  87. package/dist/src/test/rfc-003-entity-projection.test.d.ts +14 -0
  88. package/dist/src/test/rfc-004-async-hardening.test.d.cts +14 -0
  89. package/dist/src/test/rfc-004-async-hardening.test.d.ts +14 -0
  90. package/dist/src/test/rfc-005-log-context.test.d.cts +14 -0
  91. package/dist/src/test/rfc-005-log-context.test.d.ts +14 -0
  92. package/dist/src/test/tq-fixes.test.d.cts +17 -0
  93. package/dist/src/test/tq-fixes.test.d.ts +17 -0
  94. package/package.json +2 -2
  95. package/dist/PrismaAdapter-CvM_XNtE.cjs.map +0 -1
  96. package/dist/PrismaAdapter-Dy7MV090.js.map +0 -1
  97. package/dist/client-BAiCkZv7.js +0 -52
  98. package/dist/client-BAiCkZv7.js.map +0 -1
  99. package/dist/client-DgdG7pT6.cjs +0 -51
  100. package/dist/client-DgdG7pT6.cjs.map +0 -1
@@ -1,4 +1,13 @@
1
1
  import { CronTask } from '../../adapters';
2
+ /**
3
+ * Result returned from shutdown() describing what happened during grace period
4
+ */
5
+ export interface ShutdownResult {
6
+ /** Number of tasks that completed during the grace period */
7
+ completedDuringGrace: number;
8
+ /** Task IDs that were still running when grace period expired */
9
+ abandonedTaskIds: string[];
10
+ }
2
11
  /**
3
12
  * Interface for managing async tasks that exceed timeout thresholds
4
13
  * Implementation should be in tq package to access executor configs
@@ -8,18 +17,27 @@ export interface IAsyncTaskManager<T = any, ID = any> {
8
17
  * Hand off a running task to async management
9
18
  * @param message The message that is still being processed
10
19
  * @param runningPromise The promise of the still-running task
11
- * @returns true if accepted, false if queue is full
20
+ * @param taskTimeout Optional per-task timeout override in ms
21
+ * @returns true if accepted, false if queue is full or duplicate
12
22
  */
13
- handoffTask(message: CronTask<ID>, runningPromise: Promise<void>): boolean;
23
+ handoffTask(message: CronTask<ID>, runningPromise: Promise<void>, taskTimeout?: number): boolean;
14
24
  /**
15
25
  * Gracefully shutdown the async task manager
26
+ * Waits for in-flight promises up to grace period, then returns status
16
27
  */
17
- shutdown(abortSignal?: AbortSignal): Promise<void>;
28
+ shutdown(abortSignal?: AbortSignal): Promise<ShutdownResult>;
18
29
  isHandedOff(taskId: ID): boolean;
19
30
  canAcceptTask(): boolean;
20
31
  getMetrics(): {
21
32
  activeTaskCount: number;
22
33
  totalHandedOff: number;
34
+ totalCompleted: number;
35
+ totalRejected: number;
36
+ totalTimedOut: number;
37
+ oldestTaskMs: number;
38
+ utilizationPercent: number;
39
+ maxTasks: number;
23
40
  [key: string]: unknown;
24
41
  };
42
+ resetCounters(): void;
25
43
  }
@@ -0,0 +1,15 @@
1
+ import { CronTask } from '../../adapters';
2
+ export interface RetryDecision<ID = any> {
3
+ action: 'retry' | 'fail';
4
+ retryTask?: CronTask<ID>;
5
+ }
6
+ /**
7
+ * Compute whether a failed task should be retried and produce the retry-ready task.
8
+ *
9
+ * Mirrors the logic in TaskHandler.postProcessTasks() but usable from the async path.
10
+ *
11
+ * @param task The failed task
12
+ * @param maxRetries Maximum retry attempts for this task type
13
+ * @returns RetryDecision — either { action: 'retry', retryTask } or { action: 'fail' }
14
+ */
15
+ export declare function computeRetryDecision<ID>(task: CronTask<ID>, maxRetries: number): RetryDecision<ID>;
@@ -0,0 +1,15 @@
1
+ import { CronTask } from '../../adapters';
2
+ export interface RetryDecision<ID = any> {
3
+ action: 'retry' | 'fail';
4
+ retryTask?: CronTask<ID>;
5
+ }
6
+ /**
7
+ * Compute whether a failed task should be retried and produce the retry-ready task.
8
+ *
9
+ * Mirrors the logic in TaskHandler.postProcessTasks() but usable from the async path.
10
+ *
11
+ * @param task The failed task
12
+ * @param maxRetries Maximum retry attempts for this task type
13
+ * @returns RetryDecision — either { action: 'retry', retryTask } or { action: 'fail' }
14
+ */
15
+ export declare function computeRetryDecision<ID>(task: CronTask<ID>, maxRetries: number): RetryDecision<ID>;
@@ -1,5 +1,7 @@
1
1
  import { CronTask } from '../../adapters';
2
2
  import { MessageType, TypedMessage } from '@supergrowthai/mq';
3
+ import { Logger } from '@supergrowthai/utils';
4
+ import { StartFlowInput } from '../flow/types.js';
3
5
  /**
4
6
  * Type helper to extract the correct CronTask type based on message type
5
7
  */
@@ -12,11 +14,17 @@ interface IBaseExecutor {
12
14
  handoffTimeout: number;
13
15
  maxConcurrentAsync?: number;
14
16
  };
17
+ /** Optional static partition key for ordering guarantees (e.g., return payload.user_id) */
18
+ getPartitionKey?: (task: CronTask<any>) => string;
15
19
  }
16
20
  export type ExecutorActions<ID = any> = {
17
21
  addTasks(task: CronTask<ID>[]): void;
18
- fail(task: CronTask<ID>): void;
19
- success(task: CronTask<ID>): void;
22
+ fail(task: CronTask<ID>, error?: Error | string, meta?: Record<string, unknown>): void;
23
+ success(task: CronTask<ID>, result?: unknown): void;
24
+ /** Fan-out/fan-in flow orchestration (RFC-002) */
25
+ startFlow(input: StartFlowInput): string;
26
+ /** Child logger scoped to this task's log_context (RFC-005) */
27
+ readonly log: Logger;
20
28
  };
21
29
  export interface IMultiTaskExecutor<ID = any, T extends MessageType = MessageType> extends IBaseExecutor {
22
30
  multiple: true;
@@ -1,5 +1,7 @@
1
1
  import { CronTask } from '../../adapters';
2
2
  import { MessageType, TypedMessage } from '@supergrowthai/mq';
3
+ import { Logger } from '@supergrowthai/utils';
4
+ import { StartFlowInput } from '../flow/types.js';
3
5
  /**
4
6
  * Type helper to extract the correct CronTask type based on message type
5
7
  */
@@ -12,11 +14,17 @@ interface IBaseExecutor {
12
14
  handoffTimeout: number;
13
15
  maxConcurrentAsync?: number;
14
16
  };
17
+ /** Optional static partition key for ordering guarantees (e.g., return payload.user_id) */
18
+ getPartitionKey?: (task: CronTask<any>) => string;
15
19
  }
16
20
  export type ExecutorActions<ID = any> = {
17
21
  addTasks(task: CronTask<ID>[]): void;
18
- fail(task: CronTask<ID>): void;
19
- success(task: CronTask<ID>): void;
22
+ fail(task: CronTask<ID>, error?: Error | string, meta?: Record<string, unknown>): void;
23
+ success(task: CronTask<ID>, result?: unknown): void;
24
+ /** Fan-out/fan-in flow orchestration (RFC-002) */
25
+ startFlow(input: StartFlowInput): string;
26
+ /** Child logger scoped to this task's log_context (RFC-005) */
27
+ readonly log: Logger;
20
28
  };
21
29
  export interface IMultiTaskExecutor<ID = any, T extends MessageType = MessageType> extends IBaseExecutor {
22
30
  multiple: true;
@@ -0,0 +1,45 @@
1
+ import { CronTask } from '../../adapters/types.js';
2
+ export type EntityTaskProjectionStatus = 'scheduled' | 'processing' | 'executed' | 'failed';
3
+ export interface EntityTaskProjection<ID = any> {
4
+ task_id: ID;
5
+ entity_id: string;
6
+ entity_type: string;
7
+ task_type: string;
8
+ queue_id: string;
9
+ status: EntityTaskProjectionStatus;
10
+ payload?: unknown;
11
+ error?: string;
12
+ result?: unknown;
13
+ created_at: Date;
14
+ updated_at: Date;
15
+ }
16
+ /**
17
+ * Provider interface for persisting entity-task projections.
18
+ * Implementations might write to a database table, cache, or external service.
19
+ */
20
+ export interface IEntityProjectionProvider<ID = any> {
21
+ upsertProjections(entries: EntityTaskProjection<ID>[]): Promise<void>;
22
+ }
23
+ /**
24
+ * Configuration for entity projection behavior.
25
+ */
26
+ export interface EntityProjectionConfig {
27
+ /** Include task payload in projection (default: false for performance) */
28
+ includePayload?: boolean;
29
+ }
30
+ /**
31
+ * Sync entity projections to the provider. Non-fatal — logs and continues on error.
32
+ */
33
+ export declare function syncProjections<ID>(projections: EntityTaskProjection<ID>[], provider: IEntityProjectionProvider<ID> | undefined, logger: {
34
+ error(msg: string): void;
35
+ }): Promise<void>;
36
+ /**
37
+ * Build a single projection entry from a CronTask and target status.
38
+ * Returns null if the task has no entity binding.
39
+ * Throws if entity is present but task has no ID — fail-fast for developer errors.
40
+ */
41
+ export declare function buildProjection<ID>(task: CronTask<ID>, status: EntityTaskProjectionStatus, options?: {
42
+ includePayload?: boolean;
43
+ error?: string;
44
+ result?: unknown;
45
+ }): EntityTaskProjection<ID> | null;
@@ -0,0 +1,45 @@
1
+ import { CronTask } from '../../adapters/types.js';
2
+ export type EntityTaskProjectionStatus = 'scheduled' | 'processing' | 'executed' | 'failed';
3
+ export interface EntityTaskProjection<ID = any> {
4
+ task_id: ID;
5
+ entity_id: string;
6
+ entity_type: string;
7
+ task_type: string;
8
+ queue_id: string;
9
+ status: EntityTaskProjectionStatus;
10
+ payload?: unknown;
11
+ error?: string;
12
+ result?: unknown;
13
+ created_at: Date;
14
+ updated_at: Date;
15
+ }
16
+ /**
17
+ * Provider interface for persisting entity-task projections.
18
+ * Implementations might write to a database table, cache, or external service.
19
+ */
20
+ export interface IEntityProjectionProvider<ID = any> {
21
+ upsertProjections(entries: EntityTaskProjection<ID>[]): Promise<void>;
22
+ }
23
+ /**
24
+ * Configuration for entity projection behavior.
25
+ */
26
+ export interface EntityProjectionConfig {
27
+ /** Include task payload in projection (default: false for performance) */
28
+ includePayload?: boolean;
29
+ }
30
+ /**
31
+ * Sync entity projections to the provider. Non-fatal — logs and continues on error.
32
+ */
33
+ export declare function syncProjections<ID>(projections: EntityTaskProjection<ID>[], provider: IEntityProjectionProvider<ID> | undefined, logger: {
34
+ error(msg: string): void;
35
+ }): Promise<void>;
36
+ /**
37
+ * Build a single projection entry from a CronTask and target status.
38
+ * Returns null if the task has no entity binding.
39
+ * Throws if entity is present but task has no ID — fail-fast for developer errors.
40
+ */
41
+ export declare function buildProjection<ID>(task: CronTask<ID>, status: EntityTaskProjectionStatus, options?: {
42
+ includePayload?: boolean;
43
+ error?: string;
44
+ result?: unknown;
45
+ }): EntityTaskProjection<ID> | null;
@@ -0,0 +1 @@
1
+ export * from './IEntityProjectionProvider.js';
@@ -0,0 +1 @@
1
+ export * from './IEntityProjectionProvider.js';
@@ -0,0 +1,26 @@
1
+ import { CronTask } from '../../adapters/types.js';
2
+ import { IFlowBarrierProvider } from './IFlowBarrierProvider.js';
3
+ import { EntityTaskProjection } from '../entity/IEntityProjectionProvider.js';
4
+ export interface FlowPostProcessInput<ID> {
5
+ successTasks: CronTask<ID>[];
6
+ failedTasks: CronTask<ID>[];
7
+ }
8
+ export interface FlowPostProcessResult<ID> {
9
+ joinTasks: CronTask<ID>[];
10
+ projections: EntityTaskProjection<ID>[];
11
+ }
12
+ export declare class FlowMiddleware<ID> {
13
+ private readonly barrierProvider;
14
+ private readonly generateId;
15
+ constructor(barrierProvider: IFlowBarrierProvider, generateId: () => ID);
16
+ /**
17
+ * Process completed tasks for flow orchestration.
18
+ * Called from TaskHandler.postProcessTasks after markFailed/markSuccess.
19
+ *
20
+ * @param input Categorized terminal tasks — success and final-failed (no retries left)
21
+ * @returns Join tasks to dispatch and entity projections to sync
22
+ */
23
+ onPostProcess(input: FlowPostProcessInput<ID>): Promise<FlowPostProcessResult<ID>>;
24
+ private buildStepResults;
25
+ private buildJoinTask;
26
+ }
@@ -0,0 +1,26 @@
1
+ import { CronTask } from '../../adapters/types.js';
2
+ import { IFlowBarrierProvider } from './IFlowBarrierProvider.js';
3
+ import { EntityTaskProjection } from '../entity/IEntityProjectionProvider.js';
4
+ export interface FlowPostProcessInput<ID> {
5
+ successTasks: CronTask<ID>[];
6
+ failedTasks: CronTask<ID>[];
7
+ }
8
+ export interface FlowPostProcessResult<ID> {
9
+ joinTasks: CronTask<ID>[];
10
+ projections: EntityTaskProjection<ID>[];
11
+ }
12
+ export declare class FlowMiddleware<ID> {
13
+ private readonly barrierProvider;
14
+ private readonly generateId;
15
+ constructor(barrierProvider: IFlowBarrierProvider, generateId: () => ID);
16
+ /**
17
+ * Process completed tasks for flow orchestration.
18
+ * Called from TaskHandler.postProcessTasks after markFailed/markSuccess.
19
+ *
20
+ * @param input Categorized terminal tasks — success and final-failed (no retries left)
21
+ * @returns Join tasks to dispatch and entity projections to sync
22
+ */
23
+ onPostProcess(input: FlowPostProcessInput<ID>): Promise<FlowPostProcessResult<ID>>;
24
+ private buildStepResults;
25
+ private buildJoinTask;
26
+ }
@@ -0,0 +1,46 @@
1
+ import { FlowStepResult } from './types.js';
2
+ /** Result of a batchDecrementAndCheck call */
3
+ export interface BarrierDecrementResult {
4
+ /**
5
+ * Number of steps remaining after this decrement.
6
+ * 0 = barrier met (all steps done).
7
+ * -1 = flow was already aborted or completed (late arrival).
8
+ */
9
+ remaining: number;
10
+ }
11
+ /**
12
+ * Provider interface for flow barrier operations.
13
+ * Implementations must guarantee HSETNX-style dedup:
14
+ * a step_index can only decrement the counter once.
15
+ */
16
+ export interface IFlowBarrierProvider {
17
+ /**
18
+ * Initialize a barrier for a new flow.
19
+ * @param flowId Unique flow identifier
20
+ * @param totalSteps Total number of steps to wait for
21
+ */
22
+ initBarrier(flowId: string, totalSteps: number): Promise<void>;
23
+ /**
24
+ * Record step results and decrement the barrier.
25
+ * Uses HSETNX semantics: duplicate step_index submissions are ignored
26
+ * (counter only decrements by the number of genuinely new steps).
27
+ *
28
+ * @param flowId Flow identifier
29
+ * @param results Step results to record
30
+ * @returns remaining count (0 = complete, -1 = aborted/already complete)
31
+ */
32
+ batchDecrementAndCheck(flowId: string, results: FlowStepResult[]): Promise<BarrierDecrementResult>;
33
+ /**
34
+ * Get all recorded step results for a flow.
35
+ */
36
+ getStepResults(flowId: string): Promise<FlowStepResult[]>;
37
+ /**
38
+ * Mark a flow as aborted. Returns true if this is the first abort call.
39
+ * Subsequent calls return false (idempotent).
40
+ */
41
+ markAborted(flowId: string): Promise<boolean>;
42
+ /**
43
+ * Check if a flow's barrier has been fully met (remaining = 0).
44
+ */
45
+ isComplete(flowId: string): Promise<boolean>;
46
+ }
@@ -0,0 +1,46 @@
1
+ import { FlowStepResult } from './types.js';
2
+ /** Result of a batchDecrementAndCheck call */
3
+ export interface BarrierDecrementResult {
4
+ /**
5
+ * Number of steps remaining after this decrement.
6
+ * 0 = barrier met (all steps done).
7
+ * -1 = flow was already aborted or completed (late arrival).
8
+ */
9
+ remaining: number;
10
+ }
11
+ /**
12
+ * Provider interface for flow barrier operations.
13
+ * Implementations must guarantee HSETNX-style dedup:
14
+ * a step_index can only decrement the counter once.
15
+ */
16
+ export interface IFlowBarrierProvider {
17
+ /**
18
+ * Initialize a barrier for a new flow.
19
+ * @param flowId Unique flow identifier
20
+ * @param totalSteps Total number of steps to wait for
21
+ */
22
+ initBarrier(flowId: string, totalSteps: number): Promise<void>;
23
+ /**
24
+ * Record step results and decrement the barrier.
25
+ * Uses HSETNX semantics: duplicate step_index submissions are ignored
26
+ * (counter only decrements by the number of genuinely new steps).
27
+ *
28
+ * @param flowId Flow identifier
29
+ * @param results Step results to record
30
+ * @returns remaining count (0 = complete, -1 = aborted/already complete)
31
+ */
32
+ batchDecrementAndCheck(flowId: string, results: FlowStepResult[]): Promise<BarrierDecrementResult>;
33
+ /**
34
+ * Get all recorded step results for a flow.
35
+ */
36
+ getStepResults(flowId: string): Promise<FlowStepResult[]>;
37
+ /**
38
+ * Mark a flow as aborted. Returns true if this is the first abort call.
39
+ * Subsequent calls return false (idempotent).
40
+ */
41
+ markAborted(flowId: string): Promise<boolean>;
42
+ /**
43
+ * Check if a flow's barrier has been fully met (remaining = 0).
44
+ */
45
+ isComplete(flowId: string): Promise<boolean>;
46
+ }
@@ -0,0 +1,10 @@
1
+ import { FlowStepResult } from './types.js';
2
+ import { BarrierDecrementResult, IFlowBarrierProvider } from './IFlowBarrierProvider.js';
3
+ export declare class InMemoryFlowBarrierProvider implements IFlowBarrierProvider {
4
+ private readonly barriers;
5
+ initBarrier(flowId: string, totalSteps: number): Promise<void>;
6
+ batchDecrementAndCheck(flowId: string, results: FlowStepResult[]): Promise<BarrierDecrementResult>;
7
+ getStepResults(flowId: string): Promise<FlowStepResult[]>;
8
+ markAborted(flowId: string): Promise<boolean>;
9
+ isComplete(flowId: string): Promise<boolean>;
10
+ }
@@ -0,0 +1,10 @@
1
+ import { FlowStepResult } from './types.js';
2
+ import { BarrierDecrementResult, IFlowBarrierProvider } from './IFlowBarrierProvider.js';
3
+ export declare class InMemoryFlowBarrierProvider implements IFlowBarrierProvider {
4
+ private readonly barriers;
5
+ initBarrier(flowId: string, totalSteps: number): Promise<void>;
6
+ batchDecrementAndCheck(flowId: string, results: FlowStepResult[]): Promise<BarrierDecrementResult>;
7
+ getStepResults(flowId: string): Promise<FlowStepResult[]>;
8
+ markAborted(flowId: string): Promise<boolean>;
9
+ isComplete(flowId: string): Promise<boolean>;
10
+ }
@@ -0,0 +1,4 @@
1
+ export * from './types.js';
2
+ export * from './IFlowBarrierProvider.js';
3
+ export * from './InMemoryFlowBarrierProvider.js';
4
+ export * from './FlowMiddleware.js';
@@ -0,0 +1,4 @@
1
+ export * from './types.js';
2
+ export * from './IFlowBarrierProvider.js';
3
+ export * from './InMemoryFlowBarrierProvider.js';
4
+ export * from './FlowMiddleware.js';
@@ -0,0 +1,82 @@
1
+ /**
2
+ * RFC-002: Flow Orchestration Types
3
+ *
4
+ * Fan-out/fan-in flow orchestration for task queues.
5
+ * An executor calls actions.startFlow(steps, config) to dispatch N parallel
6
+ * step tasks, a barrier tracks their completion, and a join task is dispatched
7
+ * when all steps finish.
8
+ */
9
+ /** Metadata attached to step/join/timeout tasks via metadata.flow_meta */
10
+ export interface FlowMeta {
11
+ /** Unique identifier for this flow instance */
12
+ flow_id: string;
13
+ /** Index of this step within the flow (0-based) */
14
+ step_index: number;
15
+ /** Total number of steps in the flow */
16
+ total_steps: number;
17
+ /** Join task configuration — dispatched when barrier is met */
18
+ join: {
19
+ type: string;
20
+ queue_id: string;
21
+ };
22
+ /** What happens when a step fails */
23
+ failure_policy: 'continue' | 'abort';
24
+ /** True on the join task itself */
25
+ is_join?: boolean;
26
+ /** True on timeout sentinel tasks */
27
+ is_timeout?: boolean;
28
+ /** Entity binding for flow-level projection */
29
+ entity?: {
30
+ id: string;
31
+ type: string;
32
+ };
33
+ }
34
+ /** Result of a single flow step, stored in the barrier */
35
+ export interface FlowStepResult {
36
+ step_index: number;
37
+ status: 'success' | 'fail';
38
+ result?: unknown;
39
+ error?: string;
40
+ }
41
+ /** Aggregated results delivered to the join task via payload.flow_results */
42
+ export interface FlowResults {
43
+ flow_id: string;
44
+ steps: FlowStepResult[];
45
+ /** True if the flow was aborted due to failure_policy: 'abort' */
46
+ aborted?: boolean;
47
+ /** True if the flow timed out before all steps completed */
48
+ timed_out?: boolean;
49
+ }
50
+ /** A single step in a flow */
51
+ export interface FlowStep {
52
+ type: string;
53
+ queue_id: string;
54
+ payload: unknown;
55
+ /** Optional entity binding for this step */
56
+ entity?: {
57
+ id: string;
58
+ type: string;
59
+ };
60
+ }
61
+ /** Configuration for startFlow */
62
+ export interface StartFlowConfig {
63
+ /** Join task configuration */
64
+ join: {
65
+ type: string;
66
+ queue_id: string;
67
+ };
68
+ /** What happens when a step fails: 'continue' (default) or 'abort' */
69
+ failure_policy?: 'continue' | 'abort';
70
+ /** Optional timeout in ms — dispatches a sentinel task */
71
+ timeout_ms?: number;
72
+ /** Optional entity binding for flow-level projection (task_id = flow_id) */
73
+ entity?: {
74
+ id: string;
75
+ type: string;
76
+ };
77
+ }
78
+ /** Input to actions.startFlow() */
79
+ export interface StartFlowInput {
80
+ steps: FlowStep[];
81
+ config: StartFlowConfig;
82
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * RFC-002: Flow Orchestration Types
3
+ *
4
+ * Fan-out/fan-in flow orchestration for task queues.
5
+ * An executor calls actions.startFlow(steps, config) to dispatch N parallel
6
+ * step tasks, a barrier tracks their completion, and a join task is dispatched
7
+ * when all steps finish.
8
+ */
9
+ /** Metadata attached to step/join/timeout tasks via metadata.flow_meta */
10
+ export interface FlowMeta {
11
+ /** Unique identifier for this flow instance */
12
+ flow_id: string;
13
+ /** Index of this step within the flow (0-based) */
14
+ step_index: number;
15
+ /** Total number of steps in the flow */
16
+ total_steps: number;
17
+ /** Join task configuration — dispatched when barrier is met */
18
+ join: {
19
+ type: string;
20
+ queue_id: string;
21
+ };
22
+ /** What happens when a step fails */
23
+ failure_policy: 'continue' | 'abort';
24
+ /** True on the join task itself */
25
+ is_join?: boolean;
26
+ /** True on timeout sentinel tasks */
27
+ is_timeout?: boolean;
28
+ /** Entity binding for flow-level projection */
29
+ entity?: {
30
+ id: string;
31
+ type: string;
32
+ };
33
+ }
34
+ /** Result of a single flow step, stored in the barrier */
35
+ export interface FlowStepResult {
36
+ step_index: number;
37
+ status: 'success' | 'fail';
38
+ result?: unknown;
39
+ error?: string;
40
+ }
41
+ /** Aggregated results delivered to the join task via payload.flow_results */
42
+ export interface FlowResults {
43
+ flow_id: string;
44
+ steps: FlowStepResult[];
45
+ /** True if the flow was aborted due to failure_policy: 'abort' */
46
+ aborted?: boolean;
47
+ /** True if the flow timed out before all steps completed */
48
+ timed_out?: boolean;
49
+ }
50
+ /** A single step in a flow */
51
+ export interface FlowStep {
52
+ type: string;
53
+ queue_id: string;
54
+ payload: unknown;
55
+ /** Optional entity binding for this step */
56
+ entity?: {
57
+ id: string;
58
+ type: string;
59
+ };
60
+ }
61
+ /** Configuration for startFlow */
62
+ export interface StartFlowConfig {
63
+ /** Join task configuration */
64
+ join: {
65
+ type: string;
66
+ queue_id: string;
67
+ };
68
+ /** What happens when a step fails: 'continue' (default) or 'abort' */
69
+ failure_policy?: 'continue' | 'abort';
70
+ /** Optional timeout in ms — dispatches a sentinel task */
71
+ timeout_ms?: number;
72
+ /** Optional entity binding for flow-level projection (task_id = flow_id) */
73
+ entity?: {
74
+ id: string;
75
+ type: string;
76
+ };
77
+ }
78
+ /** Input to actions.startFlow() */
79
+ export interface StartFlowInput {
80
+ steps: FlowStep[];
81
+ config: StartFlowConfig;
82
+ }
@@ -1,7 +1,4 @@
1
- /**
2
- * Task Queue Lifecycle Types
3
- * Provides interfaces for task and worker lifecycle callbacks
4
- */
1
+ import { EntityProjectionConfig, IEntityProjectionProvider } from './entity/IEntityProjectionProvider.js';
5
2
  export interface TaskContext {
6
3
  /** Unique task identifier */
7
4
  task_id: string;
@@ -21,6 +18,8 @@ export interface TaskContext {
21
18
  scheduled_at: Date;
22
19
  /** Worker processing this task */
23
20
  worker_id?: string;
21
+ /** User-provided log correlation context (RFC-005) */
22
+ log_context?: Record<string, string>;
24
23
  }
25
24
  export interface TaskTiming {
26
25
  /** Time spent waiting in queue (ms) */
@@ -130,4 +129,10 @@ export interface TaskHandlerConfig {
130
129
  workerProvider?: IWorkerLifecycleProvider;
131
130
  /** Lifecycle callback configuration */
132
131
  lifecycle?: TaskHandlerLifecycleConfig;
132
+ /** RFC-003: Entity-task projection provider */
133
+ entityProjection?: IEntityProjectionProvider;
134
+ /** RFC-003: Entity projection configuration */
135
+ entityProjectionConfig?: EntityProjectionConfig;
136
+ /** RFC-002: Flow middleware for fan-out/fan-in orchestration */
137
+ flowMiddleware?: import('./flow/FlowMiddleware.js').FlowMiddleware<any>;
133
138
  }
@@ -1,7 +1,4 @@
1
- /**
2
- * Task Queue Lifecycle Types
3
- * Provides interfaces for task and worker lifecycle callbacks
4
- */
1
+ import { EntityProjectionConfig, IEntityProjectionProvider } from './entity/IEntityProjectionProvider.js';
5
2
  export interface TaskContext {
6
3
  /** Unique task identifier */
7
4
  task_id: string;
@@ -21,6 +18,8 @@ export interface TaskContext {
21
18
  scheduled_at: Date;
22
19
  /** Worker processing this task */
23
20
  worker_id?: string;
21
+ /** User-provided log correlation context (RFC-005) */
22
+ log_context?: Record<string, string>;
24
23
  }
25
24
  export interface TaskTiming {
26
25
  /** Time spent waiting in queue (ms) */
@@ -130,4 +129,10 @@ export interface TaskHandlerConfig {
130
129
  workerProvider?: IWorkerLifecycleProvider;
131
130
  /** Lifecycle callback configuration */
132
131
  lifecycle?: TaskHandlerLifecycleConfig;
132
+ /** RFC-003: Entity-task projection provider */
133
+ entityProjection?: IEntityProjectionProvider;
134
+ /** RFC-003: Entity projection configuration */
135
+ entityProjectionConfig?: EntityProjectionConfig;
136
+ /** RFC-002: Flow middleware for fan-out/fan-in orchestration */
137
+ flowMiddleware?: import('./flow/FlowMiddleware.js').FlowMiddleware<any>;
133
138
  }
@@ -0,0 +1,10 @@
1
+ export type LogStore = Record<string, string>;
2
+ /**
3
+ * Run a function within an ALS scope carrying the given log context store.
4
+ * The store is available via getLogContext() inside the callback and cleared after.
5
+ */
6
+ export declare function runWithLogContext<T>(store: LogStore, fn: () => T): T;
7
+ /**
8
+ * Read the current ALS log context store (undefined outside a runWithLogContext scope).
9
+ */
10
+ export declare function getLogContext(): LogStore | undefined;
@@ -0,0 +1,10 @@
1
+ export type LogStore = Record<string, string>;
2
+ /**
3
+ * Run a function within an ALS scope carrying the given log context store.
4
+ * The store is available via getLogContext() inside the callback and cleared after.
5
+ */
6
+ export declare function runWithLogContext<T>(store: LogStore, fn: () => T): T;
7
+ /**
8
+ * Read the current ALS log context store (undefined outside a runWithLogContext scope).
9
+ */
10
+ export declare function getLogContext(): LogStore | undefined;