@raspect/workflow-sdk 0.1.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.
@@ -0,0 +1,74 @@
1
+ import type { ActivityHandler, WorkflowClass } from './types';
2
+ /**
3
+ * Context for workflow execution, holds activities and allows execute_activity calls.
4
+ */
5
+ export declare class WorkflowContext {
6
+ readonly activities: Map<string, ActivityHandler>;
7
+ readonly workflowId: string;
8
+ readonly worker: WorkerInterface | null;
9
+ readonly activityResults: unknown[];
10
+ readonly metadata: Record<string, unknown>;
11
+ private _completedActivities;
12
+ private _currentActivityIndex;
13
+ private _isReplaying;
14
+ constructor(activities: Map<string, ActivityHandler>, workflowId: string, worker?: WorkerInterface | null, completedActivities?: Map<number, unknown> | null, metadata?: Record<string, unknown> | null);
15
+ /**
16
+ * Execute an activity and return its result.
17
+ */
18
+ executeActivity<TInput = unknown, TOutput = unknown>(activity: ActivityHandler<TInput, TOutput> | string, inputData?: TInput, startToCloseTimeoutMs?: number): Promise<TOutput>;
19
+ }
20
+ export interface WorkerInterface {
21
+ reportLocalActivityCompletion(workflowId: string, activityName: string, activityIndex: number, output: unknown, durationMs: number): Promise<void>;
22
+ reportLocalActivityFailure(workflowId: string, activityName: string, activityIndex: number, error: string, errorType: string, durationMs: number): Promise<void>;
23
+ executeRemoteActivity(workflowId: string, activityName: string, activityIndex: number, inputData: unknown, timeoutMs: number): Promise<unknown>;
24
+ }
25
+ /**
26
+ * Get the current workflow context.
27
+ */
28
+ export declare function getCurrentContext(): WorkflowContext;
29
+ /**
30
+ * Run a function within a workflow context.
31
+ */
32
+ export declare function runWithContext<T>(ctx: WorkflowContext, fn: () => Promise<T>): Promise<T>;
33
+ /**
34
+ * Decorator to mark a class as a workflow definition.
35
+ *
36
+ * Usage:
37
+ * import { workflow } from '@inspectica/workflow-sdk';
38
+ *
39
+ * @workflow.defn
40
+ * class MyWorkflow {
41
+ * @workflow.run
42
+ * async run(input: { name: string }) {
43
+ * return await workflow.executeActivity(myActivity, input);
44
+ * }
45
+ * }
46
+ */
47
+ export declare function defn<T extends WorkflowClass>(cls: T): T;
48
+ /**
49
+ * Decorator to mark a method as the workflow entry point.
50
+ */
51
+ export declare function run(target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
52
+ /**
53
+ * Execute an activity within a workflow.
54
+ *
55
+ * Usage:
56
+ * // Option 1: Local activity (function reference)
57
+ * const result = await workflow.executeActivity(myActivity, { key: "value" });
58
+ *
59
+ * // Option 2: Remote activity (string name) - for cross-worker calls
60
+ * const result = await workflow.executeActivity("say_count", { message: "hi", count: 1 });
61
+ */
62
+ export declare function executeActivity<TInput = unknown, TOutput = unknown>(activity: ActivityHandler<TInput, TOutput> | string, inputData?: TInput, startToCloseTimeoutMs?: number): Promise<TOutput>;
63
+ /**
64
+ * Get the workflow name from a class
65
+ */
66
+ export declare function getWorkflowName(cls: WorkflowClass): string;
67
+ /**
68
+ * Check if a class is a decorated workflow
69
+ */
70
+ export declare function isWorkflow(cls: unknown): boolean;
71
+ /**
72
+ * Find the run method in a workflow class
73
+ */
74
+ export declare function findRunMethod(cls: WorkflowClass): ((input: unknown) => Promise<unknown>) | null;
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ // Workflow decorators and context utilities
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.WorkflowContext = void 0;
5
+ exports.getCurrentContext = getCurrentContext;
6
+ exports.runWithContext = runWithContext;
7
+ exports.defn = defn;
8
+ exports.run = run;
9
+ exports.executeActivity = executeActivity;
10
+ exports.getWorkflowName = getWorkflowName;
11
+ exports.isWorkflow = isWorkflow;
12
+ exports.findRunMethod = findRunMethod;
13
+ const activity_1 = require("./activity");
14
+ // Symbol for workflow metadata
15
+ const WORKFLOW_NAME = Symbol('workflowName');
16
+ const IS_WORKFLOW = Symbol('isWorkflow');
17
+ const IS_WORKFLOW_RUN = Symbol('isWorkflowRun');
18
+ // AsyncLocalStorage for workflow context (Node.js equivalent of Python's contextvars)
19
+ const async_hooks_1 = require("async_hooks");
20
+ const workflowContextStorage = new async_hooks_1.AsyncLocalStorage();
21
+ /**
22
+ * Context for workflow execution, holds activities and allows execute_activity calls.
23
+ */
24
+ class WorkflowContext {
25
+ activities;
26
+ workflowId;
27
+ worker;
28
+ activityResults = [];
29
+ metadata;
30
+ _completedActivities;
31
+ _currentActivityIndex = 0;
32
+ _isReplaying;
33
+ constructor(activities, workflowId, worker = null, completedActivities = null, metadata = null) {
34
+ this.activities = activities;
35
+ this.workflowId = workflowId;
36
+ this.worker = worker;
37
+ this._completedActivities = completedActivities || new Map();
38
+ this._currentActivityIndex = 0;
39
+ this._isReplaying = completedActivities !== null && completedActivities.size > 0;
40
+ this.metadata = metadata || {};
41
+ }
42
+ /**
43
+ * Execute an activity and return its result.
44
+ */
45
+ async executeActivity(activity, inputData, startToCloseTimeoutMs = 60000) {
46
+ // Increment activity index for this call
47
+ this._currentActivityIndex += 1;
48
+ const currentIndex = this._currentActivityIndex;
49
+ // Check if this activity was already completed (replay mode)
50
+ if (this._completedActivities.has(currentIndex)) {
51
+ const cachedResult = this._completedActivities.get(currentIndex);
52
+ console.log(`Replay: Returning cached result for activity index ${currentIndex}`);
53
+ this.activityResults.push(cachedResult);
54
+ return cachedResult;
55
+ }
56
+ // Support both function reference and string name
57
+ const activityName = (0, activity_1.getActivityName)(activity);
58
+ // Check if activity is registered locally
59
+ const activityFn = this.activities.get(activityName);
60
+ if (activityFn) {
61
+ // Execute locally (in-process)
62
+ const startTime = Date.now();
63
+ try {
64
+ const result = await Promise.race([
65
+ Promise.resolve(activityFn(inputData)),
66
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Activity timed out after ${startToCloseTimeoutMs}ms`)), startToCloseTimeoutMs)),
67
+ ]);
68
+ const durationMs = Date.now() - startTime;
69
+ // Report local activity completion to server for activity history tracking
70
+ if (this.worker) {
71
+ await this.worker.reportLocalActivityCompletion(this.workflowId, activityName, currentIndex, result, durationMs);
72
+ }
73
+ this.activityResults.push(result);
74
+ return result;
75
+ }
76
+ catch (error) {
77
+ const durationMs = Date.now() - startTime;
78
+ const err = error;
79
+ // Report local activity failure to server
80
+ if (this.worker) {
81
+ await this.worker.reportLocalActivityFailure(this.workflowId, activityName, currentIndex, err.message, err.name, durationMs);
82
+ }
83
+ throw error;
84
+ }
85
+ }
86
+ // Activity not registered locally - route via server
87
+ if (!this.worker) {
88
+ throw new Error(`Activity '${activityName}' not registered locally and no worker available for remote execution`);
89
+ }
90
+ // Execute remotely via server routing
91
+ const result = await this.worker.executeRemoteActivity(this.workflowId, activityName, currentIndex, inputData, startToCloseTimeoutMs);
92
+ this.activityResults.push(result);
93
+ return result;
94
+ }
95
+ }
96
+ exports.WorkflowContext = WorkflowContext;
97
+ /**
98
+ * Get the current workflow context.
99
+ */
100
+ function getCurrentContext() {
101
+ const ctx = workflowContextStorage.getStore();
102
+ if (!ctx) {
103
+ throw new Error('Not running inside a workflow context');
104
+ }
105
+ return ctx;
106
+ }
107
+ /**
108
+ * Run a function within a workflow context.
109
+ */
110
+ function runWithContext(ctx, fn) {
111
+ return workflowContextStorage.run(ctx, fn);
112
+ }
113
+ /**
114
+ * Decorator to mark a class as a workflow definition.
115
+ *
116
+ * Usage:
117
+ * import { workflow } from '@inspectica/workflow-sdk';
118
+ *
119
+ * @workflow.defn
120
+ * class MyWorkflow {
121
+ * @workflow.run
122
+ * async run(input: { name: string }) {
123
+ * return await workflow.executeActivity(myActivity, input);
124
+ * }
125
+ * }
126
+ */
127
+ function defn(cls) {
128
+ cls.__workflowName__ = cls.name;
129
+ cls.__isWorkflow__ = true;
130
+ cls[WORKFLOW_NAME] = cls.name;
131
+ cls[IS_WORKFLOW] = true;
132
+ return cls;
133
+ }
134
+ /**
135
+ * Decorator to mark a method as the workflow entry point.
136
+ */
137
+ function run(target, propertyKey, descriptor) {
138
+ descriptor.value.__isWorkflowRun__ = true;
139
+ descriptor.value[IS_WORKFLOW_RUN] = true;
140
+ return descriptor;
141
+ }
142
+ /**
143
+ * Execute an activity within a workflow.
144
+ *
145
+ * Usage:
146
+ * // Option 1: Local activity (function reference)
147
+ * const result = await workflow.executeActivity(myActivity, { key: "value" });
148
+ *
149
+ * // Option 2: Remote activity (string name) - for cross-worker calls
150
+ * const result = await workflow.executeActivity("say_count", { message: "hi", count: 1 });
151
+ */
152
+ async function executeActivity(activity, inputData, startToCloseTimeoutMs = 60000) {
153
+ const ctx = getCurrentContext();
154
+ return ctx.executeActivity(activity, inputData, startToCloseTimeoutMs);
155
+ }
156
+ /**
157
+ * Get the workflow name from a class
158
+ */
159
+ function getWorkflowName(cls) {
160
+ return cls.__workflowName__ || cls.name;
161
+ }
162
+ /**
163
+ * Check if a class is a decorated workflow
164
+ */
165
+ function isWorkflow(cls) {
166
+ return typeof cls === 'function' && cls.__isWorkflow__ === true;
167
+ }
168
+ /**
169
+ * Find the run method in a workflow class
170
+ */
171
+ function findRunMethod(cls) {
172
+ const instance = new cls();
173
+ const proto = Object.getPrototypeOf(instance);
174
+ for (const key of Object.getOwnPropertyNames(proto)) {
175
+ const method = instance[key];
176
+ if (typeof method === 'function' && method.__isWorkflowRun__) {
177
+ return method.bind(instance);
178
+ }
179
+ }
180
+ // Fallback: check for a method named 'run'
181
+ if (typeof instance.run === 'function') {
182
+ return instance.run.bind(instance);
183
+ }
184
+ return null;
185
+ }
186
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvd29ya2Zsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDRDQUE0Qzs7O0FBdUs1Qyw4Q0FNQztBQUtELHdDQUVDO0FBZ0JELG9CQU1DO0FBS0Qsa0JBUUM7QUFZRCwwQ0FPQztBQUtELDBDQUVDO0FBS0QsZ0NBRUM7QUFLRCxzQ0FpQkM7QUEzUUQseUNBQTZDO0FBRTdDLCtCQUErQjtBQUMvQixNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDN0MsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBQ3pDLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUVoRCxzRkFBc0Y7QUFDdEYsNkNBQWdEO0FBRWhELE1BQU0sc0JBQXNCLEdBQUcsSUFBSSwrQkFBaUIsRUFBbUIsQ0FBQztBQUV4RTs7R0FFRztBQUNILE1BQWEsZUFBZTtJQUNWLFVBQVUsQ0FBK0I7SUFDekMsVUFBVSxDQUFTO0lBQ25CLE1BQU0sQ0FBeUI7SUFDL0IsZUFBZSxHQUFjLEVBQUUsQ0FBQztJQUNoQyxRQUFRLENBQTBCO0lBRTFDLG9CQUFvQixDQUF1QjtJQUMzQyxxQkFBcUIsR0FBRyxDQUFDLENBQUM7SUFDMUIsWUFBWSxDQUFVO0lBRTlCLFlBQ0UsVUFBd0MsRUFDeEMsVUFBa0IsRUFDbEIsU0FBaUMsSUFBSSxFQUNyQyxzQkFBbUQsSUFBSSxFQUN2RCxXQUEyQyxJQUFJO1FBRS9DLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxtQkFBbUIsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzdELElBQUksQ0FBQyxxQkFB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VUFBVSxJQUFJLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQzdELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVELDJDQUEyQztJQUMzQyxJQUFJLE9BQU8sUUFBUSxDQUFDLEdBQUcsS0FBSyxVQUFVLEVBQUUsQ0FBQztRQUN2QyxPQUFPLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBXb3JrZmxvdyBkZWNvcmF0b3JzIGFuZCBjb250ZXh0IHV0aWxpdGllc1xuXG5pbXBvcnQgdHlwZSB7IEFjdGl2aXR5SGFuZGxlciwgV29ya2Zsb3dDbGFzcywgV29ya2Zsb3dJbnN0YW5jZSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgZ2V0QWN0aXZpdHlOYW1lIH0gZnJvbSAnLi9hY3Rpdml0eSc7XG5cbi8vIFN5bWJvbCBmb3Igd29ya2Zsb3cgbWV0YWRhdGFcbmNvbnN0IFdPUktGTE9XX05BTUUgPSBTeW1ib2woJ3dvcmtmbG93TmFtZScpO1xuY29uc3QgSVNfV09SS0ZMT1cgPSBTeW1ib2woJ2lzV29ya2Zsb3cnKTtcbmNvbnN0IElTX1dPUktGTE9XX1JVTiA9IFN5bWJvbCgnaXNXb3JrZmxvd1J1bicpO1xuXG4vLyBBc3luY0xvY2FsU3RvcmFnZSBmb3Igd29ya2Zsb3cgY29udGV4dCAoTm9kZS5qcyBlcXVpdmFsZW50IG9mIFB5dGhvbidzIGNvbnRleHR2YXJzKVxuaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tICdhc3luY19ob29rcyc7XG5cbmNvbnN0IHdvcmtmbG93Q29udGV4dFN0b3JhZ2UgPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2U8V29ya2Zsb3dDb250ZXh0PigpO1xuXG4vKipcbiAqIENvbnRleHQgZm9yIHdvcmtmbG93IGV4ZWN1dGlvbiwgaG9sZHMgYWN0aXZpdGllcyBhbmQgYWxsb3dzIGV4ZWN1dGVfYWN0aXZpdHkgY2FsbHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBXb3JrZmxvd0NvbnRleHQge1xuICBwdWJsaWMgcmVhZG9ubHkgYWN0aXZpdGllczogTWFwPHN0cmluZywgQWN0aXZpdHlIYW5kbGVyPjtcbiAgcHVibGljIHJlYWRvbmx5IHdvcmtmbG93SWQ6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHdvcmtlcjogV29ya2VySW50ZXJmYWNlIHwgbnVsbDtcbiAgcHVibGljIHJlYWRvbmx5IGFjdGl2aXR5UmVzdWx0czogdW5rbm93bltdID0gW107XG4gIHB1YmxpYyByZWFkb25seSBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbiAgcHJpdmF0ZSBfY29tcGxldGVkQWN0aXZpdGllczogTWFwPG51bWJlciwgdW5rbm93bj47XG4gIHByaXZhdGUgX2N1cnJlbnRBY3Rpdml0eUluZGV4ID0gMDtcbiAgcHJpdmF0ZSBfaXNSZXBsYXlpbmc6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgYWN0aXZpdGllczogTWFwPHN0cmluZywgQWN0aXZpdHlIYW5kbGVyPixcbiAgICB3b3JrZmxvd0lkOiBzdHJpbmcsXG4gICAgd29ya2VyOiBXb3JrZXJJbnRlcmZhY2UgfCBudWxsID0gbnVsbCxcbiAgICBjb21wbGV0ZWRBY3Rpdml0aWVzOiBNYXA8bnVtYmVyLCB1bmtub3duPiB8IG51bGwgPSBudWxsLFxuICAgIG1ldGFkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IG51bGwgPSBudWxsXG4gICkge1xuICAgIHRoaXMuYWN0aXZpdGllcyA9IGFjdGl2aXRpZXM7XG4gICAgdGhpcy53b3JrZmxvd0lkID0gd29ya2Zsb3dJZDtcbiAgICB0aGlzLndvcmtlciA9IHdvcmtlcjtcbiAgICB0aGlzLl9jb21wbGV0ZWRBY3Rpdml0aWVzID0gY29tcGxldGVkQWN0aXZpdGllcyB8fCBuZXcgTWFwKCk7XG4gICAgdGhpcy5fY3VycmVudEFjdGl2aXR5SW5kZXggPSAwO1xuICAgIHRoaXMuX2lzUmVwbGF5aW5nID0gY29tcGxldGVkQWN0aXZpdGllcyAhPT0gbnVsbCAmJiBjb21wbGV0ZWRBY3Rpdml0aWVzLnNpemUgPiAwO1xuICAgIHRoaXMubWV0YWRhdGEgPSBtZXRhZGF0YSB8fCB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGFuIGFjdGl2aXR5IGFuZCByZXR1cm4gaXRzIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIGV4ZWN1dGVBY3Rpdml0eTxUSW5wdXQgPSB1bmtub3duLCBUT3V0cHV0ID0gdW5rbm93bj4oXG4gICAgYWN0aXZpdHk6IEFjdGl2aXR5SGFuZGxlcjxUSW5wdXQsIFRPdXRwdXQ+IHwgc3RyaW5nLFxuICAgIGlucHV0RGF0YT86IFRJbnB1dCxcbiAgICBzdGFydFRvQ2xvc2VUaW1lb3V0TXMgPSA2MDAwMFxuICApOiBQcm9taXNlPFRPdXRwdXQ+IHtcbiAgICAvLyBJbmNyZW1lbnQgYWN0aXZpdHkgaW5kZXggZm9yIHRoaXMgY2FsbFxuICAgIHRoaXMuX2N1cnJlbnRBY3Rpdml0eUluZGV4ICs9IDE7XG4gICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fY3VycmVudEFjdGl2aXR5SW5kZXg7XG5cbiAgICAvLyBDaGVjayBpZiB0aGlzIGFjdGl2aXR5IHdhcyBhbHJlYWR5IGNvbXBsZXRlZCAocmVwbGF5IG1vZGUpXG4gICAgaWYgKHRoaXMuX2NvbXBsZXRlZEFjdGl2aXRpZXMuaGFzKGN1cnJlbnRJbmRleCkpIHtcbiAgICAgIGNvbnN0IGNhY2hlZFJlc3VsdCA9IHRoaXMuX2NvbXBsZXRlZEFjdGl2aXRpZXMuZ2V0KGN1cnJlbnRJbmRleCkgYXMgVE91dHB1dDtcbiAgICAgIGNvbnNvbGUubG9nKGBSZXBsYXk6IFJldHVybmluZyBjYWNoZWQgcmVzdWx0IGZvciBhY3Rpdml0eSBpbmRleCAke2N1cnJlbnRJbmRleH1gKTtcbiAgICAgIHRoaXMuYWN0aXZpdHlSZXN1bHRzLnB1c2goY2FjaGVkUmVzdWx0KTtcbiAgICAgIHJldHVybiBjYWNoZWRSZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8gU3VwcG9ydCBib3RoIGZ1bmN0aW9uIHJlZmVyZW5jZSBhbmQgc3RyaW5nIG5hbWVcbiAgICBjb25zdCBhY3Rpdml0eU5hbWUgPSBnZXRBY3Rpdml0eU5hbWUoYWN0aXZpdHkgYXMgQWN0aXZpdHlIYW5kbGVyIHwgc3RyaW5nKTtcblxuICAgIC8vIENoZWNrIGlmIGFjdGl2aXR5IGlzIHJlZ2lzdGVyZWQgbG9jYWxseVxuICAgIGNvbnN0IGFjdGl2aXR5Rm4gPSB0aGlzLmFjdGl2aXRpZXMuZ2V0KGFjdGl2aXR5TmFtZSk7XG4gICAgaWYgKGFjdGl2aXR5Rm4pIHtcbiAgICAgIC8vIEV4ZWN1dGUgbG9jYWxseSAoaW4tcHJvY2VzcylcbiAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IFByb21pc2UucmFjZShbXG4gICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKGFjdGl2aXR5Rm4oaW5wdXREYXRhKSksXG4gICAgICAgICAgbmV3IFByb21pc2U8bmV2ZXI+KChfLCByZWplY3QpID0+XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHJlamVjdChuZXcgRXJyb3IoYEFjdGl2aXR5IHRpbWVkIG91dCBhZnRlciAke3N0YXJ0VG9DbG9zZVRpbWVvdXRNc31tc2ApKSwgc3RhcnRUb0Nsb3NlVGltZW91dE1zKVxuICAgICAgICAgICksXG4gICAgICAgIF0pIGFzIFRPdXRwdXQ7XG5cbiAgICAgICAgY29uc3QgZHVyYXRpb25NcyA9IERhdGUubm93KCkgLSBzdGFydFRpbWU7XG5cbiAgICAgICAgLy8gUmVwb3J0IGxvY2FsIGFjdGl2aXR5IGNvbXBsZXRpb24gdG8gc2VydmVyIGZvciBhY3Rpdml0eSBoaXN0b3J5IHRyYWNraW5nXG4gICAgICAgIGlmICh0aGlzLndvcmtlcikge1xuICAgICAgICAgIGF3YWl0IHRoaXMud29ya2VyLnJlcG9ydExvY2FsQWN0aXZpdHlDb21wbGV0aW9uKFxuICAgICAgICAgICAgdGhpcy53b3JrZmxvd0lkLFxuICAgICAgICAgICAgYWN0aXZpdHlOYW1lLFxuICAgICAgICAgICAgY3VycmVudEluZGV4LFxuICAgICAgICAgICAgcmVzdWx0LFxuICAgICAgICAgICAgZHVyYXRpb25Nc1xuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmFjdGl2aXR5UmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zdCBkdXJhdGlvbk1zID0gRGF0ZS5ub3coKSAtIHN0YXJ0VGltZTtcbiAgICAgICAgY29uc3QgZXJyID0gZXJyb3IgYXMgRXJyb3I7XG5cbiAgICAgICAgLy8gUmVwb3J0IGxvY2FsIGFjdGl2aXR5IGZhaWx1cmUgdG8gc2VydmVyXG4gICAgICAgIGlmICh0aGlzLndvcmtlcikge1xuICAgICAgICAgIGF3YWl0IHRoaXMud29ya2VyLnJlcG9ydExvY2FsQWN0aXZpdHlGYWlsdXJlKFxuICAgICAgICAgICAgdGhpcy53b3JrZmxvd0lkLFxuICAgICAgICAgICAgYWN0aXZpdHlOYW1lLFxuICAgICAgICAgICAgY3VycmVudEluZGV4LFxuICAgICAgICAgICAgZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICBlcnIubmFtZSxcbiAgICAgICAgICAgIGR1cmF0aW9uTXNcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWN0aXZpdHkgbm90IHJlZ2lzdGVyZWQgbG9jYWxseSAtIHJvdXRlIHZpYSBzZXJ2ZXJcbiAgICBpZiAoIXRoaXMud29ya2VyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBBY3Rpdml0eSAnJHthY3Rpdml0eU5hbWV9JyBub3QgcmVnaXN0ZXJlZCBsb2NhbGx5IGFuZCBubyB3b3JrZXIgYXZhaWxhYmxlIGZvciByZW1vdGUgZXhlY3V0aW9uYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBFeGVjdXRlIHJlbW90ZWx5IHZpYSBzZXJ2ZXIgcm91dGluZ1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMud29ya2VyLmV4ZWN1dGVSZW1vdGVBY3Rpdml0eShcbiAgICAgIHRoaXMud29ya2Zsb3dJZCxcbiAgICAgIGFjdGl2aXR5TmFtZSxcbiAgICAgIGN1cnJlbnRJbmRleCxcbiAgICAgIGlucHV0RGF0YSxcbiAgICAgIHN0YXJ0VG9DbG9zZVRpbWVvdXRNc1xuICAgICkgYXMgVE91dHB1dDtcblxuICAgIHRoaXMuYWN0aXZpdHlSZXN1bHRzLnB1c2gocmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cbi8vIEludGVyZmFjZSBmb3Igd29ya2VyIG1ldGhvZHMgbmVlZGVkIGJ5IFdvcmtmbG93Q29udGV4dFxuZXhwb3J0IGludGVyZmFjZSBXb3JrZXJJbnRlcmZhY2Uge1xuICByZXBvcnRMb2NhbEFjdGl2aXR5Q29tcGxldGlvbihcbiAgICB3b3JrZmxvd0lkOiBzdHJpbmcsXG4gICAgYWN0aXZpdHlOYW1lOiBzdHJpbmcsXG4gICAgYWN0aXZpdHlJbmRleDogbnVtYmVyLFxuICAgIG91dHB1dDogdW5rbm93bixcbiAgICBkdXJhdGlvbk1zOiBudW1iZXJcbiAgKTogUHJvbWlzZTx2b2lkPjtcbiAgcmVwb3J0TG9jYWxBY3Rpdml0eUZhaWx1cmUoXG4gICAgd29ya2Zsb3dJZDogc3RyaW5nLFxuICAgIGFjdGl2aXR5TmFtZTogc3RyaW5nLFxuICAgIGFjdGl2aXR5SW5kZXg6IG51bWJlcixcbiAgICBlcnJvcjogc3RyaW5nLFxuICAgIGVycm9yVHlwZTogc3RyaW5nLFxuICAgIGR1cmF0aW9uTXM6IG51bWJlclxuICApOiBQcm9taXNlPHZvaWQ+O1xuICBleGVjdXRlUmVtb3RlQWN0aXZpdHkoXG4gICAgd29ya2Zsb3dJZDogc3RyaW5nLFxuICAgIGFjdGl2aXR5TmFtZTogc3RyaW5nLFxuICAgIGFjdGl2aXR5SW5kZXg6IG51bWJlcixcbiAgICBpbnB1dERhdGE6IHVua25vd24sXG4gICAgdGltZW91dE1zOiBudW1iZXJcbiAgKTogUHJvbWlzZTx1bmtub3duPjtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgd29ya2Zsb3cgY29udGV4dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRDb250ZXh0KCk6IFdvcmtmbG93Q29udGV4dCB7XG4gIGNvbnN0IGN0eCA9IHdvcmtmbG93Q29udGV4dFN0b3JhZ2UuZ2V0U3RvcmUoKTtcbiAgaWYgKCFjdHgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBydW5uaW5nIGluc2lkZSBhIHdvcmtmbG93IGNvbnRleHQnKTtcbiAgfVxuICByZXR1cm4gY3R4O1xufVxuXG4vKipcbiAqIFJ1biBhIGZ1bmN0aW9uIHdpdGhpbiBhIHdvcmtmbG93IGNvbnRleHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBydW5XaXRoQ29udGV4dDxUPihjdHg6IFdvcmtmbG93Q29udGV4dCwgZm46ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgcmV0dXJuIHdvcmtmbG93Q29udGV4dFN0b3JhZ2UucnVuKGN0eCwgZm4pO1xufVxuXG4vKipcbiAqIERlY29yYXRvciB0byBtYXJrIGEgY2xhc3MgYXMgYSB3b3JrZmxvdyBkZWZpbml0aW9uLlxuICogXG4gKiBVc2FnZTpcbiAqICAgaW1wb3J0IHsgd29ya2Zsb3cgfSBmcm9tICdAaW5zcGVjdGljYS93b3JrZmxvdy1zZGsnO1xuICogICBcbiAqICAgQHdvcmtmbG93LmRlZm5cbiAqICAgY2xhc3MgTXlXb3JrZmxvdyB7XG4gKiAgICAgQHdvcmtmbG93LnJ1blxuICogICAgIGFzeW5jIHJ1bihpbnB1dDogeyBuYW1lOiBzdHJpbmcgfSkge1xuICogICAgICAgcmV0dXJuIGF3YWl0IHdvcmtmbG93LmV4ZWN1dGVBY3Rpdml0eShteUFjdGl2aXR5LCBpbnB1dCk7XG4gKiAgICAgfVxuICogICB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZuPFQgZXh0ZW5kcyBXb3JrZmxvd0NsYXNzPihjbHM6IFQpOiBUIHtcbiAgKGNscyBhcyBhbnkpLl9fd29ya2Zsb3dOYW1lX18gPSBjbHMubmFtZTtcbiAgKGNscyBhcyBhbnkpLl9faXNXb3JrZmxvd19fID0gdHJ1ZTtcbiAgKGNscyBhcyBhbnkpW1dPUktGTE9XX05BTUVdID0gY2xzLm5hbWU7XG4gIChjbHMgYXMgYW55KVtJU19XT1JLRkxPV10gPSB0cnVlO1xuICByZXR1cm4gY2xzO1xufVxuXG4vKipcbiAqIERlY29yYXRvciB0byBtYXJrIGEgbWV0aG9kIGFzIHRoZSB3b3JrZmxvdyBlbnRyeSBwb2ludC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ1bihcbiAgdGFyZ2V0OiBhbnksXG4gIHByb3BlcnR5S2V5OiBzdHJpbmcsXG4gIGRlc2NyaXB0b3I6IFByb3BlcnR5RGVzY3JpcHRvclxuKTogUHJvcGVydHlEZXNjcmlwdG9yIHtcbiAgZGVzY3JpcHRvci52YWx1ZS5fX2lzV29ya2Zsb3dSdW5fXyA9IHRydWU7XG4gIGRlc2NyaXB0b3IudmFsdWVbSVNfV09SS0ZMT1dfUlVOXSA9IHRydWU7XG4gIHJldHVybiBkZXNjcmlwdG9yO1xufVxuXG4vKipcbiAqIEV4ZWN1dGUgYW4gYWN0aXZpdHkgd2l0aGluIGEgd29ya2Zsb3cuXG4gKiBcbiAqIFVzYWdlOlxuICogICAvLyBPcHRpb24gMTogTG9jYWwgYWN0aXZpdHkgKGZ1bmN0aW9uIHJlZmVyZW5jZSlcbiAqICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd29ya2Zsb3cuZXhlY3V0ZUFjdGl2aXR5KG15QWN0aXZpdHksIHsga2V5OiBcInZhbHVlXCIgfSk7XG4gKiAgIFxuICogICAvLyBPcHRpb24gMjogUmVtb3RlIGFjdGl2aXR5IChzdHJpbmcgbmFtZSkgLSBmb3IgY3Jvc3Mtd29ya2VyIGNhbGxzXG4gKiAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdvcmtmbG93LmV4ZWN1dGVBY3Rpdml0eShcInNheV9jb3VudFwiLCB7IG1lc3NhZ2U6IFwiaGlcIiwgY291bnQ6IDEgfSk7XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleGVjdXRlQWN0aXZpdHk8VElucHV0ID0gdW5rbm93biwgVE91dHB1dCA9IHVua25vd24+KFxuICBhY3Rpdml0eTogQWN0aXZpdHlIYW5kbGVyPFRJbnB1dCwgVE91dHB1dD4gfCBzdHJpbmcsXG4gIGlucHV0RGF0YT86IFRJbnB1dCxcbiAgc3RhcnRUb0Nsb3NlVGltZW91dE1zID0gNjAwMDBcbik6IFByb21pc2U8VE91dHB1dD4ge1xuICBjb25zdCBjdHggPSBnZXRDdXJyZW50Q29udGV4dCgpO1xuICByZXR1cm4gY3R4LmV4ZWN1dGVBY3Rpdml0eShhY3Rpdml0eSwgaW5wdXREYXRhLCBzdGFydFRvQ2xvc2VUaW1lb3V0TXMpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgd29ya2Zsb3cgbmFtZSBmcm9tIGEgY2xhc3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtmbG93TmFtZShjbHM6IFdvcmtmbG93Q2xhc3MpOiBzdHJpbmcge1xuICByZXR1cm4gKGNscyBhcyBhbnkpLl9fd29ya2Zsb3dOYW1lX18gfHwgY2xzLm5hbWU7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBjbGFzcyBpcyBhIGRlY29yYXRlZCB3b3JrZmxvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNXb3JrZmxvdyhjbHM6IHVua25vd24pOiBib29sZWFuIHtcbiAgcmV0dXJuIHR5cGVvZiBjbHMgPT09ICdmdW5jdGlvbicgJiYgKGNscyBhcyBhbnkpLl9faXNXb3JrZmxvd19fID09PSB0cnVlO1xufVxuXG4vKipcbiAqIEZpbmQgdGhlIHJ1biBtZXRob2QgaW4gYSB3b3JrZmxvdyBjbGFzc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZFJ1bk1ldGhvZChjbHM6IFdvcmtmbG93Q2xhc3MpOiAoKGlucHV0OiB1bmtub3duKSA9PiBQcm9taXNlPHVua25vd24+KSB8IG51bGwge1xuICBjb25zdCBpbnN0YW5jZSA9IG5ldyBjbHMoKTtcbiAgY29uc3QgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5zdGFuY2UpO1xuICBcbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocHJvdG8pKSB7XG4gICAgY29uc3QgbWV0aG9kID0gKGluc3RhbmNlIGFzIGFueSlba2V5XTtcbiAgICBpZiAodHlwZW9mIG1ldGhvZCA9PT0gJ2Z1bmN0aW9uJyAmJiBtZXRob2QuX19pc1dvcmtmbG93UnVuX18pIHtcbiAgICAgIHJldHVybiBtZXRob2QuYmluZChpbnN0YW5jZSk7XG4gICAgfVxuICB9XG4gIFxuICAvLyBGYWxsYmFjazogY2hlY2sgZm9yIGEgbWV0aG9kIG5hbWVkICdydW4nXG4gIGlmICh0eXBlb2YgaW5zdGFuY2UucnVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGluc3RhbmNlLnJ1bi5iaW5kKGluc3RhbmNlKTtcbiAgfVxuICBcbiAgcmV0dXJuIG51bGw7XG59XG4iXX0=
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@raspect/workflow-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Node.js SDK for Inspectica Workflow Server - Activity worker implementation",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "test": "jest",
13
+ "lint": "eslint src --ext .ts",
14
+ "format": "prettier --write src/**/*.ts",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "workflow",
19
+ "orchestration",
20
+ "kafka",
21
+ "distributed",
22
+ "activity",
23
+ "worker"
24
+ ],
25
+ "author": "Inspectica Team",
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/your-org/inspectica-workflow-server.git",
30
+ "directory": "packages/node-sdk"
31
+ },
32
+ "engines": {
33
+ "node": ">=18.0.0"
34
+ },
35
+ "dependencies": {
36
+ "aws-msk-iam-sasl-signer-js": "^1.0.0",
37
+ "kafkajs": "^2.2.4"
38
+ },
39
+ "devDependencies": {
40
+ "@types/jest": "^29.5.14",
41
+ "@types/node": "^22.10.0",
42
+ "eslint": "^9.17.0",
43
+ "jest": "^29.7.0",
44
+ "prettier": "^3.4.2",
45
+ "ts-jest": "^29.2.5",
46
+ "typescript": "^5.7.2",
47
+ "typescript-eslint": "^8.18.0"
48
+ }
49
+ }