@514labs/moose-lib 0.6.376 → 0.6.378

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.
@@ -61,7 +61,9 @@ async function ScriptWorkflow(request, inputData) {
61
61
  currentData = JSON.parse(mooseJsonEncode(currentData));
62
62
  const workflow = await getWorkflowByName(workflowName);
63
63
  const task = request.execution_mode === "start" ? workflow.config.startingTask : await getTaskForWorkflow(workflowName, request.continue_from_task);
64
- const result = await handleTask(workflow, task, currentData);
64
+ const result = await handleTask(workflow, task, currentData, {
65
+ originalWorkflowInput: inputData
66
+ });
65
67
  results.push(...result);
66
68
  return results;
67
69
  } catch (error) {
@@ -69,7 +71,7 @@ async function ScriptWorkflow(request, inputData) {
69
71
  throw error;
70
72
  }
71
73
  }
72
- async function handleTask(workflow, task, inputData) {
74
+ async function handleTask(workflow, task, inputData, ctx = {}) {
73
75
  const configTimeout = task.config.timeout;
74
76
  let taskTimeout;
75
77
  if (!configTimeout) {
@@ -97,50 +99,29 @@ async function handleTask(workflow, task, inputData) {
97
99
  activityOptions.scheduleToCloseTimeout = "87600h";
98
100
  }
99
101
  const { executeTask } = (0, import_workflow.proxyActivities)(activityOptions);
100
- let taskCompleted = false;
101
- const monitorTask = async () => {
102
- import_workflow.log.info(`Monitor task starting for ${task.name}`);
103
- while (!taskCompleted) {
104
- const info = (0, import_workflow.workflowInfo)();
105
- if (info.continueAsNewSuggested) {
106
- import_workflow.log.info(`ContinueAsNew suggested by Temporal`);
107
- return await (0, import_workflow.continueAsNew)({
108
- workflow_name: workflow.name,
109
- execution_mode: "continue_as_new",
110
- continue_from_task: task.name
111
- });
112
- }
113
- await (0, import_workflow.sleep)(100);
114
- }
115
- import_workflow.log.info(`Monitor task exiting because main task completed`);
116
- };
117
- const result = await Promise.race([
118
- executeTask(workflow, task, inputData).then((taskResult) => {
119
- return {
120
- type: "task_completed",
121
- data: taskResult
122
- };
123
- }).finally(() => {
124
- taskCompleted = true;
125
- }),
126
- monitorTask().then(() => {
127
- return { type: "continue_as_new", data: void 0 };
128
- })
129
- ]);
130
- if (result.type !== "task_completed") {
131
- return [];
102
+ if ((0, import_workflow.workflowInfo)().continueAsNewSuggested) {
103
+ import_workflow.log.info(`ContinueAsNew suggested by Temporal before task ${task.name}`);
104
+ return await (0, import_workflow.continueAsNew)(
105
+ {
106
+ workflow_name: workflow.name,
107
+ execution_mode: "continue_as_new",
108
+ continue_from_task: task.name
109
+ },
110
+ ctx.originalWorkflowInput
111
+ );
132
112
  }
133
- const results = [result.data];
113
+ const result = await executeTask(workflow, task, inputData);
114
+ const results = [result];
134
115
  if (!task.config.onComplete?.length) {
135
116
  return results;
136
117
  }
137
118
  for (const childTask of task.config.onComplete) {
138
- const childResult = await handleTask(workflow, childTask, result.data);
119
+ const childResult = await handleTask(workflow, childTask, result, ctx);
139
120
  results.push(...childResult);
140
121
  }
141
- if (task.name.endsWith("_extract") && result && typeof result === "object" && result.data && typeof result.data === "object" && "hasMore" in result.data && result.data.hasMore === true) {
122
+ if (task.name.endsWith("_extract") && result && typeof result === "object" && "hasMore" in result && result.hasMore === true) {
142
123
  import_workflow.log.info(`Extract task ${task.name} has more data, restarting chain...`);
143
- const nextBatchResults = await handleTask(workflow, task, null);
124
+ const nextBatchResults = await handleTask(workflow, task, null, ctx);
144
125
  results.push(...nextBatchResults);
145
126
  }
146
127
  return results;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/scripts/workflow.ts","../../src/scripts/serialization.ts"],"sourcesContent":["import {\n log as logger,\n ActivityOptions,\n proxyActivities,\n workflowInfo,\n continueAsNew,\n sleep,\n} from \"@temporalio/workflow\";\nimport { Duration } from \"@temporalio/common\";\nimport { Task, Workflow } from \"../dmv2\";\n\nimport { WorkflowState } from \"./types\";\nimport { mooseJsonEncode } from \"./serialization\";\n\ninterface WorkflowRequest {\n workflow_name: string;\n execution_mode: \"start\" | \"continue_as_new\";\n continue_from_task?: string; // Only for continue_as_new\n}\n\nconst { getWorkflowByName, getTaskForWorkflow } = proxyActivities({\n startToCloseTimeout: \"1 minutes\",\n retry: {\n maximumAttempts: 1,\n },\n});\n\nexport async function ScriptWorkflow(\n request: WorkflowRequest,\n inputData?: any,\n): Promise<any[]> {\n const state: WorkflowState = {\n completedSteps: [],\n currentStep: null,\n failedStep: null,\n };\n\n const results: any[] = [];\n const workflowName = request.workflow_name;\n let currentData = inputData?.data || inputData || {};\n\n logger.info(\n `Starting workflow: ${workflowName} (mode: ${request.execution_mode}) with data: ${JSON.stringify(currentData)}`,\n );\n\n try {\n currentData = JSON.parse(mooseJsonEncode(currentData));\n const workflow = await getWorkflowByName(workflowName);\n const task =\n request.execution_mode === \"start\" ?\n workflow.config.startingTask\n : await getTaskForWorkflow(workflowName, request.continue_from_task!);\n const result = await handleTask(workflow, task, currentData);\n results.push(...result);\n\n return results;\n } catch (error) {\n state.failedStep = workflowName;\n throw error;\n }\n}\n\nasync function handleTask(\n workflow: Workflow,\n task: Task<any, any>,\n inputData: any,\n): Promise<any[]> {\n // Handle timeout configuration\n const configTimeout = task.config.timeout;\n let taskTimeout: Duration | undefined;\n\n if (!configTimeout) {\n taskTimeout = \"1h\";\n } else if (configTimeout === \"never\") {\n taskTimeout = undefined;\n } else {\n taskTimeout = configTimeout as Duration;\n }\n\n const taskRetries = task.config.retries ?? 3;\n // Temporal's maximumAttempts = total attempts (initial + retries)\n // User-facing \"retries\" = number of retries after initial failure\n const maxAttempts = taskRetries + 1;\n\n const timeoutMessage =\n taskTimeout ? `with timeout ${taskTimeout}` : \"with no timeout (unlimited)\";\n logger.info(\n `Handling task ${task.name} ${timeoutMessage} and retries ${taskRetries}`,\n );\n\n const activityOptions: ActivityOptions = {\n heartbeatTimeout: \"10s\",\n retry: {\n maximumAttempts: maxAttempts,\n },\n };\n\n // Temporal requires either startToCloseTimeout OR scheduleToCloseTimeout to be set\n // For unlimited timeout (timeout = \"none\"), we use scheduleToCloseTimeout with a very large value\n // For normal timeouts, we use startToCloseTimeout for single execution timeout\n if (taskTimeout) {\n // Normal timeout - limit each individual execution attempt\n activityOptions.startToCloseTimeout = taskTimeout;\n } else {\n // Unlimited timeout - set scheduleToCloseTimeout to a very large value (10 years)\n // This satisfies Temporal's requirement while effectively allowing unlimited execution\n activityOptions.scheduleToCloseTimeout = \"87600h\"; // 10 years\n }\n\n const { executeTask } = proxyActivities(activityOptions);\n\n let taskCompleted = false;\n\n const monitorTask = async () => {\n logger.info(`Monitor task starting for ${task.name}`);\n while (!taskCompleted) {\n const info = workflowInfo();\n\n // Continue-as-new only when suggested by Temporal\n if (info.continueAsNewSuggested) {\n logger.info(`ContinueAsNew suggested by Temporal`);\n return await continueAsNew({\n workflow_name: workflow.name,\n execution_mode: \"continue_as_new\" as const,\n continue_from_task: task.name,\n });\n }\n\n await sleep(100);\n }\n logger.info(`Monitor task exiting because main task completed`);\n };\n\n const result = await Promise.race([\n executeTask(workflow, task, inputData)\n .then((taskResult) => {\n return {\n type: \"task_completed\" as const,\n data: taskResult,\n };\n })\n .finally(() => {\n taskCompleted = true;\n }),\n monitorTask().then(() => {\n return { type: \"continue_as_new\" as const, data: undefined };\n }),\n ]);\n\n if (result.type !== \"task_completed\") {\n return [];\n }\n\n const results = [result.data];\n if (!task.config.onComplete?.length) {\n return results;\n }\n\n for (const childTask of task.config.onComplete) {\n const childResult = await handleTask(workflow, childTask, result.data);\n results.push(...childResult);\n }\n\n // Check if this is an ETL extract task that needs to loop\n // ETL extract tasks end with \"_extract\" and return BatchResult with hasMore\n if (\n task.name.endsWith(\"_extract\") &&\n result &&\n typeof result === \"object\" &&\n result.data &&\n typeof result.data === \"object\" &&\n \"hasMore\" in result.data &&\n (result.data as any).hasMore === true\n ) {\n logger.info(`Extract task ${task.name} has more data, restarting chain...`);\n\n // Recursively call the extract task again to get the next batch\n const nextBatchResults = await handleTask(workflow, task, null);\n results.push(...nextBatchResults);\n }\n\n return results;\n}\n","// Add serialization helpers\nexport const mooseJsonEncode = (data: any): string => {\n return JSON.stringify(data, (_, value) => {\n if (value instanceof Map) {\n return {\n __type: \"Map\",\n value: Array.from(value.entries()),\n };\n }\n return value;\n });\n};\n\nexport const mooseJsonDecode = (text: string): any => {\n return JSON.parse(text, (_, value) => {\n if (value && typeof value === \"object\" && value.__type === \"Map\") {\n return new Map(value.value);\n }\n return value;\n });\n};\n"],"mappings":"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","names":["logger"]}
1
+ {"version":3,"sources":["../../src/scripts/workflow.ts","../../src/scripts/serialization.ts"],"sourcesContent":["import {\n log as logger,\n ActivityOptions,\n proxyActivities,\n workflowInfo,\n continueAsNew,\n} from \"@temporalio/workflow\";\nimport { Duration } from \"@temporalio/common\";\nimport { Task, Workflow } from \"../dmv2\";\n\nimport { WorkflowState } from \"./types\";\nimport { mooseJsonEncode } from \"./serialization\";\n\ninterface WorkflowRequest {\n workflow_name: string;\n execution_mode: \"start\" | \"continue_as_new\";\n continue_from_task?: string; // Only for continue_as_new\n}\n\ninterface HandleTaskContext {\n originalWorkflowInput?: any;\n}\n\nconst { getWorkflowByName, getTaskForWorkflow } = proxyActivities({\n startToCloseTimeout: \"1 minutes\",\n retry: {\n maximumAttempts: 1,\n },\n});\n\nexport async function ScriptWorkflow(\n request: WorkflowRequest,\n inputData?: any,\n): Promise<any[]> {\n const state: WorkflowState = {\n completedSteps: [],\n currentStep: null,\n failedStep: null,\n };\n\n const results: any[] = [];\n const workflowName = request.workflow_name;\n let currentData = inputData?.data || inputData || {};\n\n logger.info(\n `Starting workflow: ${workflowName} (mode: ${request.execution_mode}) with data: ${JSON.stringify(currentData)}`,\n );\n\n try {\n currentData = JSON.parse(mooseJsonEncode(currentData));\n const workflow = await getWorkflowByName(workflowName);\n const task =\n request.execution_mode === \"start\" ?\n workflow.config.startingTask\n : await getTaskForWorkflow(workflowName, request.continue_from_task!);\n const result = await handleTask(workflow, task, currentData, {\n originalWorkflowInput: inputData,\n });\n results.push(...result);\n\n return results;\n } catch (error) {\n state.failedStep = workflowName;\n throw error;\n }\n}\n\nasync function handleTask(\n workflow: Workflow,\n task: Task<any, any>,\n inputData: any,\n ctx: HandleTaskContext = {},\n): Promise<any[]> {\n // Handle timeout configuration\n const configTimeout = task.config.timeout;\n let taskTimeout: Duration | undefined;\n\n if (!configTimeout) {\n taskTimeout = \"1h\";\n } else if (configTimeout === \"never\") {\n taskTimeout = undefined;\n } else {\n taskTimeout = configTimeout as Duration;\n }\n\n const taskRetries = task.config.retries ?? 3;\n // Temporal's maximumAttempts = total attempts (initial + retries)\n // User-facing \"retries\" = number of retries after initial failure\n const maxAttempts = taskRetries + 1;\n\n const timeoutMessage =\n taskTimeout ? `with timeout ${taskTimeout}` : \"with no timeout (unlimited)\";\n logger.info(\n `Handling task ${task.name} ${timeoutMessage} and retries ${taskRetries}`,\n );\n\n const activityOptions: ActivityOptions = {\n heartbeatTimeout: \"10s\",\n retry: {\n maximumAttempts: maxAttempts,\n },\n };\n\n // Temporal requires either startToCloseTimeout OR scheduleToCloseTimeout to be set\n // For unlimited timeout (timeout = \"never\"), we use scheduleToCloseTimeout with a very large value\n // For normal timeouts, we use startToCloseTimeout for single execution timeout\n if (taskTimeout) {\n // Normal timeout - limit each individual execution attempt\n activityOptions.startToCloseTimeout = taskTimeout;\n } else {\n // Unlimited timeout - set scheduleToCloseTimeout to a very large value (10 years)\n // This satisfies Temporal's requirement while effectively allowing unlimited execution\n activityOptions.scheduleToCloseTimeout = \"87600h\"; // 10 years\n }\n\n const { executeTask } = proxyActivities(activityOptions);\n\n // Check history limits BEFORE starting the task, so continue_from_task\n // points to a task that hasn't run yet (avoids duplicate execution).\n // Pass the original raw inputData so run() doesn't double-process it.\n if (workflowInfo().continueAsNewSuggested) {\n logger.info(`ContinueAsNew suggested by Temporal before task ${task.name}`);\n return await continueAsNew(\n {\n workflow_name: workflow.name,\n execution_mode: \"continue_as_new\" as const,\n continue_from_task: task.name,\n },\n ctx.originalWorkflowInput,\n );\n }\n\n // Execute the activity directly no polling monitor.\n // A running activity does not generate workflow history events, so the\n // history stays small even for long-running (timeout: \"never\") tasks.\n const result = await executeTask(workflow, task, inputData);\n\n const results = [result];\n\n if (!task.config.onComplete?.length) {\n return results;\n }\n\n for (const childTask of task.config.onComplete) {\n const childResult = await handleTask(workflow, childTask, result, ctx);\n results.push(...childResult);\n }\n\n // Check if this is an ETL extract task that needs to loop\n // ETL extract tasks end with \"_extract\" and return BatchResult with hasMore\n if (\n task.name.endsWith(\"_extract\") &&\n result &&\n typeof result === \"object\" &&\n \"hasMore\" in result &&\n (result as any).hasMore === true\n ) {\n logger.info(`Extract task ${task.name} has more data, restarting chain...`);\n\n // Recursively call the extract task again to get the next batch\n const nextBatchResults = await handleTask(workflow, task, null, ctx);\n results.push(...nextBatchResults);\n }\n\n return results;\n}\n","// Add serialization helpers\nexport const mooseJsonEncode = (data: any): string => {\n return JSON.stringify(data, (_, value) => {\n if (value instanceof Map) {\n return {\n __type: \"Map\",\n value: Array.from(value.entries()),\n };\n }\n return value;\n });\n};\n\nexport const mooseJsonDecode = (text: string): any => {\n return JSON.parse(text, (_, value) => {\n if (value && typeof value === \"object\" && value.__type === \"Map\") {\n return new Map(value.value);\n }\n return value;\n });\n};\n"],"mappings":"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","names":["logger"]}
@@ -3,8 +3,7 @@ import {
3
3
  log as logger,
4
4
  proxyActivities,
5
5
  workflowInfo,
6
- continueAsNew,
7
- sleep
6
+ continueAsNew
8
7
  } from "@temporalio/workflow";
9
8
 
10
9
  // src/scripts/serialization.ts
@@ -43,7 +42,9 @@ async function ScriptWorkflow(request, inputData) {
43
42
  currentData = JSON.parse(mooseJsonEncode(currentData));
44
43
  const workflow = await getWorkflowByName(workflowName);
45
44
  const task = request.execution_mode === "start" ? workflow.config.startingTask : await getTaskForWorkflow(workflowName, request.continue_from_task);
46
- const result = await handleTask(workflow, task, currentData);
45
+ const result = await handleTask(workflow, task, currentData, {
46
+ originalWorkflowInput: inputData
47
+ });
47
48
  results.push(...result);
48
49
  return results;
49
50
  } catch (error) {
@@ -51,7 +52,7 @@ async function ScriptWorkflow(request, inputData) {
51
52
  throw error;
52
53
  }
53
54
  }
54
- async function handleTask(workflow, task, inputData) {
55
+ async function handleTask(workflow, task, inputData, ctx = {}) {
55
56
  const configTimeout = task.config.timeout;
56
57
  let taskTimeout;
57
58
  if (!configTimeout) {
@@ -79,50 +80,29 @@ async function handleTask(workflow, task, inputData) {
79
80
  activityOptions.scheduleToCloseTimeout = "87600h";
80
81
  }
81
82
  const { executeTask } = proxyActivities(activityOptions);
82
- let taskCompleted = false;
83
- const monitorTask = async () => {
84
- logger.info(`Monitor task starting for ${task.name}`);
85
- while (!taskCompleted) {
86
- const info = workflowInfo();
87
- if (info.continueAsNewSuggested) {
88
- logger.info(`ContinueAsNew suggested by Temporal`);
89
- return await continueAsNew({
90
- workflow_name: workflow.name,
91
- execution_mode: "continue_as_new",
92
- continue_from_task: task.name
93
- });
94
- }
95
- await sleep(100);
96
- }
97
- logger.info(`Monitor task exiting because main task completed`);
98
- };
99
- const result = await Promise.race([
100
- executeTask(workflow, task, inputData).then((taskResult) => {
101
- return {
102
- type: "task_completed",
103
- data: taskResult
104
- };
105
- }).finally(() => {
106
- taskCompleted = true;
107
- }),
108
- monitorTask().then(() => {
109
- return { type: "continue_as_new", data: void 0 };
110
- })
111
- ]);
112
- if (result.type !== "task_completed") {
113
- return [];
83
+ if (workflowInfo().continueAsNewSuggested) {
84
+ logger.info(`ContinueAsNew suggested by Temporal before task ${task.name}`);
85
+ return await continueAsNew(
86
+ {
87
+ workflow_name: workflow.name,
88
+ execution_mode: "continue_as_new",
89
+ continue_from_task: task.name
90
+ },
91
+ ctx.originalWorkflowInput
92
+ );
114
93
  }
115
- const results = [result.data];
94
+ const result = await executeTask(workflow, task, inputData);
95
+ const results = [result];
116
96
  if (!task.config.onComplete?.length) {
117
97
  return results;
118
98
  }
119
99
  for (const childTask of task.config.onComplete) {
120
- const childResult = await handleTask(workflow, childTask, result.data);
100
+ const childResult = await handleTask(workflow, childTask, result, ctx);
121
101
  results.push(...childResult);
122
102
  }
123
- if (task.name.endsWith("_extract") && result && typeof result === "object" && result.data && typeof result.data === "object" && "hasMore" in result.data && result.data.hasMore === true) {
103
+ if (task.name.endsWith("_extract") && result && typeof result === "object" && "hasMore" in result && result.hasMore === true) {
124
104
  logger.info(`Extract task ${task.name} has more data, restarting chain...`);
125
- const nextBatchResults = await handleTask(workflow, task, null);
105
+ const nextBatchResults = await handleTask(workflow, task, null, ctx);
126
106
  results.push(...nextBatchResults);
127
107
  }
128
108
  return results;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/scripts/workflow.ts","../../src/scripts/serialization.ts"],"sourcesContent":["import {\n log as logger,\n ActivityOptions,\n proxyActivities,\n workflowInfo,\n continueAsNew,\n sleep,\n} from \"@temporalio/workflow\";\nimport { Duration } from \"@temporalio/common\";\nimport { Task, Workflow } from \"../dmv2\";\n\nimport { WorkflowState } from \"./types\";\nimport { mooseJsonEncode } from \"./serialization\";\n\ninterface WorkflowRequest {\n workflow_name: string;\n execution_mode: \"start\" | \"continue_as_new\";\n continue_from_task?: string; // Only for continue_as_new\n}\n\nconst { getWorkflowByName, getTaskForWorkflow } = proxyActivities({\n startToCloseTimeout: \"1 minutes\",\n retry: {\n maximumAttempts: 1,\n },\n});\n\nexport async function ScriptWorkflow(\n request: WorkflowRequest,\n inputData?: any,\n): Promise<any[]> {\n const state: WorkflowState = {\n completedSteps: [],\n currentStep: null,\n failedStep: null,\n };\n\n const results: any[] = [];\n const workflowName = request.workflow_name;\n let currentData = inputData?.data || inputData || {};\n\n logger.info(\n `Starting workflow: ${workflowName} (mode: ${request.execution_mode}) with data: ${JSON.stringify(currentData)}`,\n );\n\n try {\n currentData = JSON.parse(mooseJsonEncode(currentData));\n const workflow = await getWorkflowByName(workflowName);\n const task =\n request.execution_mode === \"start\" ?\n workflow.config.startingTask\n : await getTaskForWorkflow(workflowName, request.continue_from_task!);\n const result = await handleTask(workflow, task, currentData);\n results.push(...result);\n\n return results;\n } catch (error) {\n state.failedStep = workflowName;\n throw error;\n }\n}\n\nasync function handleTask(\n workflow: Workflow,\n task: Task<any, any>,\n inputData: any,\n): Promise<any[]> {\n // Handle timeout configuration\n const configTimeout = task.config.timeout;\n let taskTimeout: Duration | undefined;\n\n if (!configTimeout) {\n taskTimeout = \"1h\";\n } else if (configTimeout === \"never\") {\n taskTimeout = undefined;\n } else {\n taskTimeout = configTimeout as Duration;\n }\n\n const taskRetries = task.config.retries ?? 3;\n // Temporal's maximumAttempts = total attempts (initial + retries)\n // User-facing \"retries\" = number of retries after initial failure\n const maxAttempts = taskRetries + 1;\n\n const timeoutMessage =\n taskTimeout ? `with timeout ${taskTimeout}` : \"with no timeout (unlimited)\";\n logger.info(\n `Handling task ${task.name} ${timeoutMessage} and retries ${taskRetries}`,\n );\n\n const activityOptions: ActivityOptions = {\n heartbeatTimeout: \"10s\",\n retry: {\n maximumAttempts: maxAttempts,\n },\n };\n\n // Temporal requires either startToCloseTimeout OR scheduleToCloseTimeout to be set\n // For unlimited timeout (timeout = \"none\"), we use scheduleToCloseTimeout with a very large value\n // For normal timeouts, we use startToCloseTimeout for single execution timeout\n if (taskTimeout) {\n // Normal timeout - limit each individual execution attempt\n activityOptions.startToCloseTimeout = taskTimeout;\n } else {\n // Unlimited timeout - set scheduleToCloseTimeout to a very large value (10 years)\n // This satisfies Temporal's requirement while effectively allowing unlimited execution\n activityOptions.scheduleToCloseTimeout = \"87600h\"; // 10 years\n }\n\n const { executeTask } = proxyActivities(activityOptions);\n\n let taskCompleted = false;\n\n const monitorTask = async () => {\n logger.info(`Monitor task starting for ${task.name}`);\n while (!taskCompleted) {\n const info = workflowInfo();\n\n // Continue-as-new only when suggested by Temporal\n if (info.continueAsNewSuggested) {\n logger.info(`ContinueAsNew suggested by Temporal`);\n return await continueAsNew({\n workflow_name: workflow.name,\n execution_mode: \"continue_as_new\" as const,\n continue_from_task: task.name,\n });\n }\n\n await sleep(100);\n }\n logger.info(`Monitor task exiting because main task completed`);\n };\n\n const result = await Promise.race([\n executeTask(workflow, task, inputData)\n .then((taskResult) => {\n return {\n type: \"task_completed\" as const,\n data: taskResult,\n };\n })\n .finally(() => {\n taskCompleted = true;\n }),\n monitorTask().then(() => {\n return { type: \"continue_as_new\" as const, data: undefined };\n }),\n ]);\n\n if (result.type !== \"task_completed\") {\n return [];\n }\n\n const results = [result.data];\n if (!task.config.onComplete?.length) {\n return results;\n }\n\n for (const childTask of task.config.onComplete) {\n const childResult = await handleTask(workflow, childTask, result.data);\n results.push(...childResult);\n }\n\n // Check if this is an ETL extract task that needs to loop\n // ETL extract tasks end with \"_extract\" and return BatchResult with hasMore\n if (\n task.name.endsWith(\"_extract\") &&\n result &&\n typeof result === \"object\" &&\n result.data &&\n typeof result.data === \"object\" &&\n \"hasMore\" in result.data &&\n (result.data as any).hasMore === true\n ) {\n logger.info(`Extract task ${task.name} has more data, restarting chain...`);\n\n // Recursively call the extract task again to get the next batch\n const nextBatchResults = await handleTask(workflow, task, null);\n results.push(...nextBatchResults);\n }\n\n return results;\n}\n","// Add serialization helpers\nexport const mooseJsonEncode = (data: any): string => {\n return JSON.stringify(data, (_, value) => {\n if (value instanceof Map) {\n return {\n __type: \"Map\",\n value: Array.from(value.entries()),\n };\n }\n return value;\n });\n};\n\nexport const mooseJsonDecode = (text: string): any => {\n return JSON.parse(text, (_, value) => {\n if (value && typeof value === \"object\" && value.__type === \"Map\") {\n return new Map(value.value);\n }\n return value;\n });\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/scripts/workflow.ts","../../src/scripts/serialization.ts"],"sourcesContent":["import {\n log as logger,\n ActivityOptions,\n proxyActivities,\n workflowInfo,\n continueAsNew,\n} from \"@temporalio/workflow\";\nimport { Duration } from \"@temporalio/common\";\nimport { Task, Workflow } from \"../dmv2\";\n\nimport { WorkflowState } from \"./types\";\nimport { mooseJsonEncode } from \"./serialization\";\n\ninterface WorkflowRequest {\n workflow_name: string;\n execution_mode: \"start\" | \"continue_as_new\";\n continue_from_task?: string; // Only for continue_as_new\n}\n\ninterface HandleTaskContext {\n originalWorkflowInput?: any;\n}\n\nconst { getWorkflowByName, getTaskForWorkflow } = proxyActivities({\n startToCloseTimeout: \"1 minutes\",\n retry: {\n maximumAttempts: 1,\n },\n});\n\nexport async function ScriptWorkflow(\n request: WorkflowRequest,\n inputData?: any,\n): Promise<any[]> {\n const state: WorkflowState = {\n completedSteps: [],\n currentStep: null,\n failedStep: null,\n };\n\n const results: any[] = [];\n const workflowName = request.workflow_name;\n let currentData = inputData?.data || inputData || {};\n\n logger.info(\n `Starting workflow: ${workflowName} (mode: ${request.execution_mode}) with data: ${JSON.stringify(currentData)}`,\n );\n\n try {\n currentData = JSON.parse(mooseJsonEncode(currentData));\n const workflow = await getWorkflowByName(workflowName);\n const task =\n request.execution_mode === \"start\" ?\n workflow.config.startingTask\n : await getTaskForWorkflow(workflowName, request.continue_from_task!);\n const result = await handleTask(workflow, task, currentData, {\n originalWorkflowInput: inputData,\n });\n results.push(...result);\n\n return results;\n } catch (error) {\n state.failedStep = workflowName;\n throw error;\n }\n}\n\nasync function handleTask(\n workflow: Workflow,\n task: Task<any, any>,\n inputData: any,\n ctx: HandleTaskContext = {},\n): Promise<any[]> {\n // Handle timeout configuration\n const configTimeout = task.config.timeout;\n let taskTimeout: Duration | undefined;\n\n if (!configTimeout) {\n taskTimeout = \"1h\";\n } else if (configTimeout === \"never\") {\n taskTimeout = undefined;\n } else {\n taskTimeout = configTimeout as Duration;\n }\n\n const taskRetries = task.config.retries ?? 3;\n // Temporal's maximumAttempts = total attempts (initial + retries)\n // User-facing \"retries\" = number of retries after initial failure\n const maxAttempts = taskRetries + 1;\n\n const timeoutMessage =\n taskTimeout ? `with timeout ${taskTimeout}` : \"with no timeout (unlimited)\";\n logger.info(\n `Handling task ${task.name} ${timeoutMessage} and retries ${taskRetries}`,\n );\n\n const activityOptions: ActivityOptions = {\n heartbeatTimeout: \"10s\",\n retry: {\n maximumAttempts: maxAttempts,\n },\n };\n\n // Temporal requires either startToCloseTimeout OR scheduleToCloseTimeout to be set\n // For unlimited timeout (timeout = \"never\"), we use scheduleToCloseTimeout with a very large value\n // For normal timeouts, we use startToCloseTimeout for single execution timeout\n if (taskTimeout) {\n // Normal timeout - limit each individual execution attempt\n activityOptions.startToCloseTimeout = taskTimeout;\n } else {\n // Unlimited timeout - set scheduleToCloseTimeout to a very large value (10 years)\n // This satisfies Temporal's requirement while effectively allowing unlimited execution\n activityOptions.scheduleToCloseTimeout = \"87600h\"; // 10 years\n }\n\n const { executeTask } = proxyActivities(activityOptions);\n\n // Check history limits BEFORE starting the task, so continue_from_task\n // points to a task that hasn't run yet (avoids duplicate execution).\n // Pass the original raw inputData so run() doesn't double-process it.\n if (workflowInfo().continueAsNewSuggested) {\n logger.info(`ContinueAsNew suggested by Temporal before task ${task.name}`);\n return await continueAsNew(\n {\n workflow_name: workflow.name,\n execution_mode: \"continue_as_new\" as const,\n continue_from_task: task.name,\n },\n ctx.originalWorkflowInput,\n );\n }\n\n // Execute the activity directly no polling monitor.\n // A running activity does not generate workflow history events, so the\n // history stays small even for long-running (timeout: \"never\") tasks.\n const result = await executeTask(workflow, task, inputData);\n\n const results = [result];\n\n if (!task.config.onComplete?.length) {\n return results;\n }\n\n for (const childTask of task.config.onComplete) {\n const childResult = await handleTask(workflow, childTask, result, ctx);\n results.push(...childResult);\n }\n\n // Check if this is an ETL extract task that needs to loop\n // ETL extract tasks end with \"_extract\" and return BatchResult with hasMore\n if (\n task.name.endsWith(\"_extract\") &&\n result &&\n typeof result === \"object\" &&\n \"hasMore\" in result &&\n (result as any).hasMore === true\n ) {\n logger.info(`Extract task ${task.name} has more data, restarting chain...`);\n\n // Recursively call the extract task again to get the next batch\n const nextBatchResults = await handleTask(workflow, task, null, ctx);\n results.push(...nextBatchResults);\n }\n\n return results;\n}\n","// Add serialization helpers\nexport const mooseJsonEncode = (data: any): string => {\n return JSON.stringify(data, (_, value) => {\n if (value instanceof Map) {\n return {\n __type: \"Map\",\n value: Array.from(value.entries()),\n };\n }\n return value;\n });\n};\n\nexport const mooseJsonDecode = (text: string): any => {\n return JSON.parse(text, (_, value) => {\n if (value && typeof value === \"object\" && value.__type === \"Map\") {\n return new Map(value.value);\n }\n return value;\n });\n};\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@514labs/moose-lib",
3
- "version": "0.6.376",
3
+ "version": "0.6.378",
4
4
  "engines": {
5
5
  "node": ">=20 <25"
6
6
  },