@pgflow/edge-worker 0.0.8 → 0.0.10-prealpha.1

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 (82) hide show
  1. package/dist/EdgeWorker.d.ts +73 -0
  2. package/dist/EdgeWorker.d.ts.map +1 -0
  3. package/dist/EdgeWorker.js +105 -0
  4. package/dist/core/BatchProcessor.d.ts +13 -0
  5. package/dist/core/BatchProcessor.d.ts.map +1 -0
  6. package/dist/core/BatchProcessor.js +29 -0
  7. package/dist/core/ExecutionController.d.ts +15 -0
  8. package/dist/core/ExecutionController.d.ts.map +1 -0
  9. package/dist/core/ExecutionController.js +34 -0
  10. package/dist/core/Heartbeat.d.ts +13 -0
  11. package/dist/core/Heartbeat.d.ts.map +1 -0
  12. package/dist/core/Heartbeat.js +21 -0
  13. package/dist/core/Queries.d.ts +14 -0
  14. package/dist/core/Queries.d.ts.map +1 -0
  15. package/dist/core/Queries.js +31 -0
  16. package/dist/core/Worker.d.ts +21 -0
  17. package/dist/core/Worker.d.ts.map +1 -0
  18. package/dist/core/Worker.js +79 -0
  19. package/dist/core/WorkerLifecycle.d.ts +26 -0
  20. package/dist/core/WorkerLifecycle.d.ts.map +1 -0
  21. package/dist/core/WorkerLifecycle.js +69 -0
  22. package/dist/core/WorkerState.d.ts +37 -0
  23. package/dist/core/WorkerState.d.ts.map +1 -0
  24. package/dist/core/WorkerState.js +70 -0
  25. package/dist/core/types.d.ts +39 -0
  26. package/dist/core/types.d.ts.map +1 -0
  27. package/dist/core/types.js +1 -0
  28. package/dist/flow/FlowWorkerLifecycle.d.ts +26 -0
  29. package/dist/flow/FlowWorkerLifecycle.d.ts.map +1 -0
  30. package/dist/flow/FlowWorkerLifecycle.js +64 -0
  31. package/dist/flow/StepTaskExecutor.d.ts +28 -0
  32. package/dist/flow/StepTaskExecutor.d.ts.map +1 -0
  33. package/dist/flow/StepTaskExecutor.js +71 -0
  34. package/dist/flow/StepTaskPoller.d.ts +21 -0
  35. package/dist/flow/StepTaskPoller.d.ts.map +1 -0
  36. package/dist/flow/StepTaskPoller.js +34 -0
  37. package/dist/flow/createFlowWorker.d.ts +24 -0
  38. package/dist/flow/createFlowWorker.d.ts.map +1 -0
  39. package/dist/flow/createFlowWorker.js +56 -0
  40. package/dist/flow/types.d.ts +2 -0
  41. package/dist/flow/types.d.ts.map +1 -0
  42. package/dist/flow/types.js +1 -0
  43. package/dist/index.d.ts +10 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +8 -953
  46. package/dist/package.json +33 -0
  47. package/dist/platform/DenoAdapter.d.ts +23 -0
  48. package/dist/platform/DenoAdapter.d.ts.map +1 -0
  49. package/dist/platform/DenoAdapter.js +132 -0
  50. package/dist/platform/createAdapter.d.ts +7 -0
  51. package/dist/platform/createAdapter.d.ts.map +1 -0
  52. package/dist/platform/createAdapter.js +17 -0
  53. package/dist/platform/deno-types.d.ts +13 -0
  54. package/dist/platform/deno-types.d.ts.map +1 -0
  55. package/dist/platform/deno-types.js +6 -0
  56. package/dist/platform/index.d.ts +5 -0
  57. package/dist/platform/index.d.ts.map +1 -0
  58. package/dist/platform/index.js +4 -0
  59. package/dist/platform/types.d.ts +45 -0
  60. package/dist/platform/types.d.ts.map +1 -0
  61. package/dist/platform/types.js +1 -0
  62. package/dist/queue/MessageExecutor.d.ts +43 -0
  63. package/dist/queue/MessageExecutor.d.ts.map +1 -0
  64. package/dist/queue/MessageExecutor.js +95 -0
  65. package/dist/queue/Queue.d.ts +35 -0
  66. package/dist/queue/Queue.d.ts.map +1 -0
  67. package/dist/queue/Queue.js +87 -0
  68. package/dist/queue/ReadWithPollPoller.d.ts +20 -0
  69. package/dist/queue/ReadWithPollPoller.d.ts.map +1 -0
  70. package/dist/queue/ReadWithPollPoller.js +25 -0
  71. package/dist/queue/createQueueWorker.d.ts +74 -0
  72. package/dist/queue/createQueueWorker.d.ts.map +1 -0
  73. package/dist/queue/createQueueWorker.js +47 -0
  74. package/dist/queue/types.d.ts +13 -0
  75. package/dist/queue/types.d.ts.map +1 -0
  76. package/dist/queue/types.js +1 -0
  77. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  78. package/package.json +15 -4
  79. package/dist/CHANGELOG.md +0 -35
  80. package/dist/LICENSE.md +0 -660
  81. package/dist/README.md +0 -46
  82. package/dist/index.js.map +0 -7
@@ -0,0 +1,70 @@
1
+ export var States;
2
+ (function (States) {
3
+ /** The worker has been created but has not yet started. */
4
+ States["Created"] = "created";
5
+ /** The worker is starting but has not yet started processing messages. */
6
+ States["Starting"] = "starting";
7
+ /** The worker is processing messages. */
8
+ States["Running"] = "running";
9
+ /** The worker stopped processing messages but is still releasing resources. */
10
+ States["Stopping"] = "stopping";
11
+ /** The worker has stopped processing messages and released resources
12
+ * and can be discarded. */
13
+ States["Stopped"] = "stopped";
14
+ })(States || (States = {}));
15
+ export const Transitions = {
16
+ [States.Created]: [States.Starting],
17
+ [States.Starting]: [States.Running],
18
+ [States.Running]: [States.Stopping],
19
+ [States.Stopping]: [States.Stopped],
20
+ [States.Stopped]: [], // Terminal state - no valid transitions from here
21
+ };
22
+ export class TransitionError extends Error {
23
+ constructor(options) {
24
+ super(`Cannot transition from ${options.from} to ${options.to}`);
25
+ }
26
+ }
27
+ /**
28
+ * Represents the state of a worker and exposes method for doing allowed transitions
29
+ */
30
+ export class WorkerState {
31
+ logger;
32
+ state = States.Created;
33
+ constructor(logger) {
34
+ this.logger = logger;
35
+ }
36
+ get current() {
37
+ return this.state;
38
+ }
39
+ get isCreated() {
40
+ return this.state === States.Created;
41
+ }
42
+ get isStarting() {
43
+ return this.state === States.Starting;
44
+ }
45
+ get isRunning() {
46
+ return this.state === States.Running;
47
+ }
48
+ get isStopping() {
49
+ return this.state === States.Stopping;
50
+ }
51
+ get isStopped() {
52
+ return this.state === States.Stopped;
53
+ }
54
+ transitionTo(state) {
55
+ this.logger.debug(`[WorkerState] Starting transition to '${state}' (current state: ${this.state})`);
56
+ if (this.state === state) {
57
+ return;
58
+ }
59
+ if (Transitions[this.state].includes(state)) {
60
+ this.state = state;
61
+ this.logger.debug(`[WorkerState] Transitioned to '${state}'`);
62
+ }
63
+ else {
64
+ throw new TransitionError({
65
+ from: this.state,
66
+ to: state,
67
+ });
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,39 @@
1
+ export type { Json } from '@pgflow/core';
2
+ export interface IPoller<IMessage> {
3
+ poll(): Promise<IMessage[]>;
4
+ }
5
+ export interface IExecutor {
6
+ get msgId(): number;
7
+ execute(): Promise<unknown>;
8
+ }
9
+ export interface IMessage {
10
+ msg_id: number;
11
+ }
12
+ export interface ILifecycle {
13
+ acknowledgeStart(workerBootstrap: WorkerBootstrap): Promise<void>;
14
+ acknowledgeStop(): void;
15
+ sendHeartbeat(): Promise<void>;
16
+ get edgeFunctionName(): string | undefined;
17
+ get queueName(): string;
18
+ get isRunning(): boolean;
19
+ get isStopping(): boolean;
20
+ get isStopped(): boolean;
21
+ transitionToStopping(): void;
22
+ }
23
+ export interface IBatchProcessor {
24
+ processBatch(): Promise<void>;
25
+ awaitCompletion(): Promise<void>;
26
+ }
27
+ export type WorkerRow = {
28
+ last_heartbeat_at: string;
29
+ queue_name: string;
30
+ started_at: string;
31
+ stopped_at: string | null;
32
+ worker_id: string;
33
+ function_name: string;
34
+ };
35
+ export interface WorkerBootstrap {
36
+ edgeFunctionName: string;
37
+ workerId: string;
38
+ }
39
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,WAAW,OAAO,CAAC,QAAQ;IAC/B,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,KAAK,IAAI,MAAM,CAAC;IACpB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,gBAAgB,CAAC,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,eAAe,IAAI,IAAI,CAAC;IACxB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/B,IAAI,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAAC;IAC3C,IAAI,SAAS,IAAI,MAAM,CAAC;IACxB,IAAI,SAAS,IAAI,OAAO,CAAC;IACzB,IAAI,UAAU,IAAI,OAAO,CAAC;IAC1B,IAAI,SAAS,IAAI,OAAO,CAAC;IAEzB,oBAAoB,IAAI,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ import type { Queries } from '../core/Queries.js';
2
+ import type { ILifecycle, WorkerBootstrap } from '../core/types.js';
3
+ import type { Logger } from '../platform/types.js';
4
+ import type { AnyFlow } from '@pgflow/dsl';
5
+ /**
6
+ * A specialized WorkerLifecycle for Flow-based workers that is aware of the Flow's step types
7
+ */
8
+ export declare class FlowWorkerLifecycle<TFlow extends AnyFlow> implements ILifecycle {
9
+ private workerState;
10
+ private heartbeat?;
11
+ private logger;
12
+ private queries;
13
+ private workerRow?;
14
+ private flow;
15
+ constructor(queries: Queries, flow: TFlow, logger: Logger);
16
+ acknowledgeStart(workerBootstrap: WorkerBootstrap): Promise<void>;
17
+ acknowledgeStop(): void;
18
+ get edgeFunctionName(): string | undefined;
19
+ get queueName(): string;
20
+ sendHeartbeat(): Promise<void>;
21
+ get isRunning(): boolean;
22
+ get isStopping(): boolean;
23
+ get isStopped(): boolean;
24
+ transitionToStopping(): void;
25
+ }
26
+ //# sourceMappingURL=FlowWorkerLifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlowWorkerLifecycle.d.ts","sourceRoot":"","sources":["../../src/flow/FlowWorkerLifecycle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAa,MAAM,kBAAkB,CAAC;AAC/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;GAEG;AACH,qBAAa,mBAAmB,CAAC,KAAK,SAAS,OAAO,CAAE,YAAW,UAAU;IAC3E,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,IAAI,CAAQ;gBAER,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM;IAOnD,gBAAgB,CAAC,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBvE,eAAe;IAiBf,IAAI,gBAAgB,uBAEnB;IAED,IAAI,SAAS,WAEZ;IAEK,aAAa;IAInB,IAAI,SAAS,YAEZ;IAED,IAAI,UAAU,YAEb;IAED,IAAI,SAAS,YAEZ;IAED,oBAAoB;CAGrB"}
@@ -0,0 +1,64 @@
1
+ import { Heartbeat } from '../core/Heartbeat.js';
2
+ import { States, WorkerState } from '../core/WorkerState.js';
3
+ /**
4
+ * A specialized WorkerLifecycle for Flow-based workers that is aware of the Flow's step types
5
+ */
6
+ export class FlowWorkerLifecycle {
7
+ workerState;
8
+ heartbeat;
9
+ logger;
10
+ queries;
11
+ workerRow;
12
+ flow;
13
+ constructor(queries, flow, logger) {
14
+ this.queries = queries;
15
+ this.flow = flow;
16
+ this.logger = logger;
17
+ this.workerState = new WorkerState(logger);
18
+ }
19
+ async acknowledgeStart(workerBootstrap) {
20
+ this.workerState.transitionTo(States.Starting);
21
+ this.workerRow = await this.queries.onWorkerStarted({
22
+ queueName: this.queueName,
23
+ ...workerBootstrap,
24
+ });
25
+ this.heartbeat = new Heartbeat(5000, this.queries, this.workerRow, this.logger);
26
+ this.workerState.transitionTo(States.Running);
27
+ }
28
+ acknowledgeStop() {
29
+ this.workerState.transitionTo(States.Stopping);
30
+ if (!this.workerRow) {
31
+ throw new Error('Cannot stop worker: workerRow not set');
32
+ }
33
+ try {
34
+ this.logger.debug('Acknowledging worker stop...');
35
+ this.workerState.transitionTo(States.Stopped);
36
+ this.logger.debug('Worker stop acknowledged');
37
+ }
38
+ catch (error) {
39
+ this.logger.debug(`Error acknowledging worker stop: ${error}`);
40
+ throw error;
41
+ }
42
+ }
43
+ get edgeFunctionName() {
44
+ return this.workerRow?.function_name;
45
+ }
46
+ get queueName() {
47
+ return this.flow.slug;
48
+ }
49
+ async sendHeartbeat() {
50
+ await this.heartbeat?.send();
51
+ }
52
+ get isRunning() {
53
+ return this.workerState.isRunning;
54
+ }
55
+ get isStopping() {
56
+ return this.workerState.isStopping;
57
+ }
58
+ get isStopped() {
59
+ return this.workerState.isStopped;
60
+ }
61
+ transitionToStopping() {
62
+ this.workerState.transitionTo(States.Stopping);
63
+ }
64
+ }
@@ -0,0 +1,28 @@
1
+ import type { AnyFlow } from '@pgflow/dsl';
2
+ import type { StepTaskRecord, IPgflowClient } from './types.js';
3
+ import type { IExecutor } from '../core/types.js';
4
+ import type { Logger } from '../platform/types.js';
5
+ /**
6
+ * An executor that processes step tasks using an IPgflowClient
7
+ * with strong typing for the flow's step handlers
8
+ */
9
+ export declare class StepTaskExecutor<TFlow extends AnyFlow> implements IExecutor {
10
+ private readonly flow;
11
+ private readonly task;
12
+ private readonly adapter;
13
+ private readonly signal;
14
+ private logger;
15
+ constructor(flow: TFlow, task: StepTaskRecord<TFlow>, adapter: IPgflowClient<TFlow>, signal: AbortSignal, logger: Logger);
16
+ get msgId(): number;
17
+ execute(): Promise<void>;
18
+ /**
19
+ * Handles the error that occurred during execution.
20
+ *
21
+ * If the error is an AbortError, it means that the worker was aborted and stopping,
22
+ * the task will be picked up by another worker later.
23
+ *
24
+ * Otherwise, it marks the task as failed.
25
+ */
26
+ private handleExecutionError;
27
+ }
28
+ //# sourceMappingURL=StepTaskExecutor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepTaskExecutor.d.ts","sourceRoot":"","sources":["../../src/flow/StepTaskExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AASnD;;;GAGG;AACH,qBAAa,gBAAgB,CAAC,KAAK,SAAS,OAAO,CAAE,YAAW,SAAS;IAIrE,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,MAAM,CAAS;gBAGJ,IAAI,EAAE,KAAK,EACX,IAAI,EAAE,cAAc,CAAC,KAAK,CAAC,EAC3B,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAC7B,MAAM,EAAE,WAAW,EACpC,MAAM,EAAE,MAAM;IAKhB,IAAI,KAAK,WAER;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC9B;;;;;;;OAOG;YACW,oBAAoB;CAYnC"}
@@ -0,0 +1,71 @@
1
+ class AbortError extends Error {
2
+ constructor() {
3
+ super('Operation aborted');
4
+ this.name = 'AbortError';
5
+ }
6
+ }
7
+ /**
8
+ * An executor that processes step tasks using an IPgflowClient
9
+ * with strong typing for the flow's step handlers
10
+ */
11
+ export class StepTaskExecutor {
12
+ flow;
13
+ task;
14
+ adapter;
15
+ signal;
16
+ logger;
17
+ constructor(flow, task, adapter, signal, logger) {
18
+ this.flow = flow;
19
+ this.task = task;
20
+ this.adapter = adapter;
21
+ this.signal = signal;
22
+ this.logger = logger;
23
+ }
24
+ get msgId() {
25
+ return this.task.msg_id;
26
+ }
27
+ async execute() {
28
+ try {
29
+ if (this.signal.aborted) {
30
+ throw new AbortError();
31
+ }
32
+ // Check if already aborted before starting
33
+ this.signal.throwIfAborted();
34
+ const stepSlug = this.task.step_slug;
35
+ this.logger.debug(`Executing step task ${this.task.msg_id} for step ${stepSlug}`);
36
+ // Get the step handler from the flow with proper typing
37
+ const stepDef = this.flow.getStepDefinition(stepSlug);
38
+ if (!stepDef) {
39
+ throw new Error(`No step definition found for slug=${stepSlug}`);
40
+ }
41
+ // !!! HANDLER EXECUTION !!!
42
+ const result = await stepDef.handler(this.task.input);
43
+ // !!! HANDLER EXECUTION !!!
44
+ this.logger.debug(`step task ${this.task.msg_id} completed successfully, marking as complete`);
45
+ await this.adapter.completeTask(this.task, result);
46
+ this.logger.debug(`step task ${this.task.msg_id} marked as complete`);
47
+ }
48
+ catch (error) {
49
+ await this.handleExecutionError(error);
50
+ }
51
+ }
52
+ /**
53
+ * Handles the error that occurred during execution.
54
+ *
55
+ * If the error is an AbortError, it means that the worker was aborted and stopping,
56
+ * the task will be picked up by another worker later.
57
+ *
58
+ * Otherwise, it marks the task as failed.
59
+ */
60
+ async handleExecutionError(error) {
61
+ if (error instanceof Error && error.name === 'AbortError') {
62
+ this.logger.debug(`Aborted execution for step task ${this.task.msg_id}`);
63
+ // Do not mark as failed - the worker was aborted and stopping,
64
+ // the task will be picked up by another worker later
65
+ }
66
+ else {
67
+ this.logger.error(`step task ${this.task.msg_id} failed with error: ${error}`);
68
+ await this.adapter.failTask(this.task, error);
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,21 @@
1
+ import type { StepTaskRecord, IPgflowClient } from './types.js';
2
+ import type { IPoller } from '../core/types.js';
3
+ import type { Logger } from '../platform/types.js';
4
+ import type { AnyFlow } from '@pgflow/dsl';
5
+ export interface StepTaskPollerConfig {
6
+ batchSize: number;
7
+ queueName: string;
8
+ }
9
+ /**
10
+ * A poller that retrieves flow tasks using an IPgflowClient
11
+ */
12
+ export declare class StepTaskPoller<TFlow extends AnyFlow> implements IPoller<StepTaskRecord<TFlow>> {
13
+ private readonly adapter;
14
+ private readonly signal;
15
+ private readonly config;
16
+ private logger;
17
+ constructor(adapter: IPgflowClient<TFlow>, signal: AbortSignal, config: StepTaskPollerConfig, logger: Logger);
18
+ poll(): Promise<StepTaskRecord<TFlow>[]>;
19
+ private isAborted;
20
+ }
21
+ //# sourceMappingURL=StepTaskPoller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepTaskPoller.d.ts","sourceRoot":"","sources":["../../src/flow/StepTaskPoller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,cAAc,CAAC,KAAK,SAAS,OAAO,CAC/C,YAAW,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAKvC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALzB,OAAO,CAAC,MAAM,CAAS;gBAGJ,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,EAC7B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,oBAAoB,EAC7C,MAAM,EAAE,MAAM;IAKV,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;IAuB9C,OAAO,CAAC,SAAS;CAGlB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * A poller that retrieves flow tasks using an IPgflowClient
3
+ */
4
+ export class StepTaskPoller {
5
+ adapter;
6
+ signal;
7
+ config;
8
+ logger;
9
+ constructor(adapter, signal, config, logger) {
10
+ this.adapter = adapter;
11
+ this.signal = signal;
12
+ this.config = config;
13
+ this.logger = logger;
14
+ }
15
+ async poll() {
16
+ if (this.isAborted()) {
17
+ this.logger.debug('Polling aborted, returning empty array');
18
+ return [];
19
+ }
20
+ this.logger.debug(`Polling for flow tasks with batch size ${this.config.batchSize}`);
21
+ try {
22
+ const tasks = await this.adapter.pollForTasks(this.config.queueName, this.config.batchSize);
23
+ this.logger.debug(`Retrieved ${tasks.length} flow tasks`);
24
+ return tasks;
25
+ }
26
+ catch (err) {
27
+ this.logger.error(`Error polling for flow tasks: ${err}`);
28
+ return [];
29
+ }
30
+ }
31
+ isAborted() {
32
+ return this.signal.aborted;
33
+ }
34
+ }
@@ -0,0 +1,24 @@
1
+ import type { AnyFlow } from '@pgflow/dsl';
2
+ import type { EdgeWorkerConfig } from '../EdgeWorker.js';
3
+ import type { Logger } from '../platform/types.js';
4
+ import { Worker } from '../core/Worker.js';
5
+ import postgres from 'postgres';
6
+ /**
7
+ * Configuration for the flow worker
8
+ */
9
+ export type FlowWorkerConfig = EdgeWorkerConfig & {
10
+ maxConcurrent?: number;
11
+ connectionString?: string;
12
+ sql?: postgres.Sql;
13
+ maxPgConnections?: number;
14
+ batchSize?: number;
15
+ };
16
+ /**
17
+ * Creates a new Worker instance for processing flow tasks.
18
+ *
19
+ * @param flow - The Flow DSL definition
20
+ * @param config - Configuration options for the worker
21
+ * @returns A configured Worker instance ready to be started
22
+ */
23
+ export declare function createFlowWorker<TFlow extends AnyFlow>(flow: TFlow, config: FlowWorkerConfig, createLogger: (module: string) => Logger): Worker;
24
+ //# sourceMappingURL=createFlowWorker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createFlowWorker.d.ts","sourceRoot":"","sources":["../../src/flow/createFlowWorker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAQzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,QAAQ,MAAM,UAAU,CAAC;AAIhC;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,OAAO,EACpD,IAAI,EAAE,KAAK,EACX,MAAM,EAAE,gBAAgB,EACxB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GACvC,MAAM,CAsFR"}
@@ -0,0 +1,56 @@
1
+ import { ExecutionController } from '../core/ExecutionController.js';
2
+ import { StepTaskPoller } from './StepTaskPoller.js';
3
+ import { StepTaskExecutor } from './StepTaskExecutor.js';
4
+ import { PgflowSqlClient } from '@pgflow/core';
5
+ import { Queries } from '../core/Queries.js';
6
+ import { Worker } from '../core/Worker.js';
7
+ import postgres from 'postgres';
8
+ import { FlowWorkerLifecycle } from './FlowWorkerLifecycle.js';
9
+ import { BatchProcessor } from '../core/BatchProcessor.js';
10
+ /**
11
+ * Creates a new Worker instance for processing flow tasks.
12
+ *
13
+ * @param flow - The Flow DSL definition
14
+ * @param config - Configuration options for the worker
15
+ * @returns A configured Worker instance ready to be started
16
+ */
17
+ export function createFlowWorker(flow, config, createLogger) {
18
+ const logger = createLogger('createFlowWorker');
19
+ // Create abort controller for graceful shutdown
20
+ const abortController = new AbortController();
21
+ const abortSignal = abortController.signal;
22
+ if (!config.sql && !config.connectionString) {
23
+ throw new Error("Either 'sql' or 'connectionString' must be provided in FlowWorkerConfig.");
24
+ }
25
+ const sql = config.sql ||
26
+ postgres(config.connectionString, {
27
+ max: config.maxPgConnections,
28
+ prepare: false,
29
+ });
30
+ // Create the pgflow adapter
31
+ const pgflowAdapter = new PgflowSqlClient(sql);
32
+ // Use flow slug as queue name, or fallback to 'tasks'
33
+ const queueName = flow.slug || 'tasks';
34
+ logger.debug(`Using queue name: ${queueName}`);
35
+ // Create specialized FlowWorkerLifecycle with the proxied queue and flow
36
+ const queries = new Queries(sql);
37
+ const lifecycle = new FlowWorkerLifecycle(queries, flow, createLogger('FlowWorkerLifecycle'));
38
+ // Create StepTaskPoller
39
+ const pollerConfig = {
40
+ batchSize: config.batchSize || 10,
41
+ queueName: flow.slug,
42
+ };
43
+ const poller = new StepTaskPoller(pgflowAdapter, abortSignal, pollerConfig, createLogger('StepTaskPoller'));
44
+ // Create executor factory with proper typing
45
+ const executorFactory = (record, signal) => {
46
+ return new StepTaskExecutor(flow, record, pgflowAdapter, signal, createLogger('StepTaskExecutor'));
47
+ };
48
+ // Create ExecutionController
49
+ const executionController = new ExecutionController(executorFactory, abortSignal, {
50
+ maxConcurrent: config.maxConcurrent || 10,
51
+ }, createLogger('ExecutionController'));
52
+ // Create BatchProcessor
53
+ const batchProcessor = new BatchProcessor(executionController, poller, abortSignal, createLogger('BatchProcessor'));
54
+ // Return Worker
55
+ return new Worker(batchProcessor, lifecycle, sql, createLogger('Worker'));
56
+ }
@@ -0,0 +1,2 @@
1
+ export * from '@pgflow/core';
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/flow/types.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
@@ -0,0 +1 @@
1
+ export * from '@pgflow/core';
@@ -0,0 +1,10 @@
1
+ export { createQueueWorker } from './queue/createQueueWorker.js';
2
+ export { EdgeWorker } from './EdgeWorker.js';
3
+ export { createFlowWorker } from './flow/createFlowWorker.js';
4
+ export { FlowWorkerLifecycle } from './flow/FlowWorkerLifecycle.js';
5
+ export * from './platform/index.js';
6
+ export type { StepTaskRecord } from './flow/types.js';
7
+ export type { FlowWorkerConfig } from './flow/createFlowWorker.js';
8
+ export type { StepTaskPollerConfig } from './flow/StepTaskPoller.js';
9
+ export type { Json, IExecutor, IPoller, IMessage, ILifecycle, IBatchProcessor, } from './core/types.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAGpE,cAAc,qBAAqB,CAAC;AAGpC,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGrE,YAAY,EACV,IAAI,EACJ,SAAS,EACT,OAAO,EACP,QAAQ,EACR,UAAU,EACV,eAAe,GAChB,MAAM,iBAAiB,CAAC"}