![require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages](https://cdn.sanity.io/images/cgdhsj6q/production/be8ab80c8efa5907bc341c6fefe9aa20d239d890-1600x1097.png?w=400&fit=max&auto=format)
Security News
require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
chrono-forge
Advanced tools
A powerful framework for temporal workflows, state management, and streaming activities, designed for seamless developer experience.
ChronoForge is an opensource framework for Temporal.io Workflows which integrates a wide array of features through a comprehensive set of decorators and a robust workflow execution engine. The system is designed to be flexible, allowing for easy definition of workflows with dynamic execution paths, detailed error handling, and integrated tracing. The use of decorators simplifies the management of steps, conditions, signals, queries, and hooks, while the workflow engine ensures that all steps are executed in the correct order, based on defined dependencies and conditions. This system is powerful enough to handle complex workflows while remaining easy to define, manage, and debug.
Those who say it cannot be done should stop interrupting the people doing it.
Workflow
)
@ChronoFlow(options: { name?: string })
name?: string
: An optional custom name for the workflow. If not provided, the class name is used.Workflow
. If it doesn't, a dynamic class is created that does.@ChronoFlow()
class MyWorkflow extends Workflow {
async execute() {
// Workflow logic here
}
}
@Signal(name?: string)
name?: string
: An optional name for the signal. If not provided, the method name is used.@Signal()
resume() {
this.status = 'resume';
}
@Query(name?: string)
name?: string
: An optional name for the query. If not provided, the method name is used.@Query("status")
getStatus() {
return this.status;
}
@Hook(options: { before?: string; after?: string })
before?: string
: The name of the method that this hook should run before.after?: string
: The name of the method that this hook should run after.@Hook({ before: "executeStep" })
beforeExecuteStep() {
console.log('Before executing step');
}
@Hook({ after: "executeStep" })
afterExecuteStep() {
console.log('After executing step');
}
@Before(targetMethod: string)
targetMethod: string
: The name of the method that this hook should run before.@Hook({ before: targetMethod })
.@Before("processData")
logBeforeProcessing() {
console.log('Processing data...');
}
@After(targetMethod: string)
targetMethod: string
: The name of the method that this hook should run after.@Hook({ after: targetMethod })
.@After("processData")
logAfterProcessing() {
console.log('Data processed.');
}
@Property(options?: { get?: boolean | string; set?: boolean | string })
get?: boolean | string
: Controls query generation. If true
, a query handler is created with the property name. If a string is provided, the query handler is named accordingly. If false
, no query handler is created.set?: boolean | string
: Controls signal generation. If true
, a signal handler is created with the property name. If a string is provided, the signal handler is named accordingly. If false
, no signal handler is created.@Property()
status: string;
@Condition(timeout?: string)
timeout?: string
: An optional timeout string specifying how long to wait for the condition to be met before timing out.condition(() => <method logic>, { timeout })
. The method is executed only if the condition returns true
within the specified timeout.@Condition("1h")
async checkIfReady() {
return this.ready;
}
@Step(options?: { name?: string; on?: () => boolean; before?: string | string[]; after?: string | string[] })
name?: string
: An optional name for the step. If not provided, the method name is used.on?: () => boolean
: An optional condition function that must return true
for the step to execute.before?: string | string[]
: Specifies one or more steps that should be executed before this step.after?: string | string[]
: Specifies one or more steps that should be executed after this step.the method as a step within the workflow, managing dependencies and conditions to determine the order of execution.
@Step({ name: "initialize", before: "executeTask" })
async initialize() {
// Initialization logic
}
@Step({ name: "executeTask", after: "initialize", on: () => this.ready })
async executeTask() {
// Task execution logic
}
getSteps()
:
getCurrentSteps()
:
isComplete
Boolean:
after
steps) and their dependent steps have been executed.before
and after
) and conditions.after
steps) have been successfully executed.Workflow
)The Workflow
class is the foundational abstract class that all workflows in the ChronoForge system must extend. It provides essential methods and properties that handle the core functionality of Temporal workflows, including signals, queries, hooks, step execution, and more. This section details all the methods and properties of the Workflow
class.
The Workflow
class provides the necessary infrastructure for defining and executing Temporal workflows. Below are the core methods and properties available in the Workflow
class:
params: any
any
options: { [key: string]: any }
object
signalHandlers: { [key: string]: (args: any) => Promise<void> }
object
queryHandlers: { [key: string]: (...args: any) => any }
object
handles: { [workflowId: string]: ReturnType<typeof workflow.getExternalWorkflowHandle> | workflow.ChildWorkflowHandle<any> }
object
continueAsNew: boolean
boolean
false
log: typeof log
typeof log
steps: { name: string; method: string; on?: () => boolean; before?: string | string[]; after?: string | string[] }[]
array
tracer: typeof trace.getTracer
typeof trace.getTracer
iteration: number
MAX_ITERATIONS
to manage workflow lifecycle.number
0
MAX_ITERATIONS: number
number
10000
status: string
running
, paused
, complete
, cancelled
, errored
).string
running
constructor(params: any, options: { [key: string]: any })
Workflow
class, setting up the parameters and options, and initializing properties like signal handlers, query handlers, and workflow handles.params
: Workflow-specific parameters passed during instantiation.options
: Optional configuration options for the workflow.condition(): boolean | Promise<boolean>
boolean
or Promise<boolean>
execute(...args: unknown[]): Promise<unknown>
Promise<unknown>
bindQueriesAndSignals()
signalHandlers
and queryHandlers
properties, setting up the necessary bindings with Temporal.void
applyHooks(hooks: { before: { [name: string]: string[] }, after: { [name: string]: string[] } })
hooks
: An object defining the methods that should have hooks applied, with arrays of hook method names for before
and after
the target method.void
signal(signalName: string, ...args: unknown[]): Promise<void>
signalName
: The name of the signal to be sent.args
: The arguments to be passed to the signal handler.Promise<void>
query(queryName: string, ...args: unknown[]): Promise<any>
queryName
: The name of the query to be executed.args
: The arguments to be passed to the query handler.Promise<any>
forwardSignalToChildren(signalName: string, ...args: unknown[]): Promise<void>
signalName
: The name of the signal to be forwarded.args
: The arguments to be passed to the child workflows.Promise<void>
executeWorkflow(params: any): Promise<any>
params
: The parameters passed to the workflow upon initialization.Promise<any>
awaitCondition(): Promise<void>
condition()
method defined in the subclass or the workflow's internal state to determine when to continue.Promise<void>
isInTerminalState(): boolean
complete
, cancelled
, errored
). This method is used to determine if the workflow should stop execution.boolean
handleMaxIterations(): Promise<void>
continueAsNew
operation, allowing the workflow to restart with a clean state while retaining its parameters and status.Promise<void>
handlePause(): Promise<void>
Promise<void>
handleExecutionError(err: any, span: any): Promise<void>
err
: The error that occurred during execution.span
: The OpenTelemetry span associated with the current execution step.Promise<void>
executeSteps(): Promise<void>
Promise<void>
**
executeStep(step: { name: string; method: string }): Promise<void>
**
Description: Executes an individual step within the workflow. This method calls the corresponding method for the step and processes its result.
Parameters:
step
: The step object containing the name and method to be executed.Returns: Promise<void>
processDependentSteps(stepName: string): Promise<void>
stepName
: The name of the step that has just been executed.Promise<void>
The Workflow
class in ChronoForge is a powerful and flexible foundation for building Temporal workflows in TypeScript. It provides the necessary tools for managing workflow execution, handling signals and queries, applying hooks, and processing complex step sequences. By extending this class, developers can create robust and maintainable workflows that integrate seamlessly with the Temporal.io platform and OpenTelemetry for tracing and monitoring.
Workflow
, the decorator dynamically creates a new class that does. This ensures all workflows inherit the necessary functionality, even if the original class was not explicitly designed to extend Workflow
.new Function()
, allowing it to be named dynamically based on the class or provided name. This function starts the workflow, binds queries and signals, and wraps the execution in an OpenTelemetry span, managing the workflow’s lifecycle.before
steps and are the initial points of execution in the workflow. Exit steps are those without any after
steps, representing the final stages of the workflow.FAQs
A comprehensive framework for building resilient Temporal workflows, advanced state management, and real-time streaming activities in TypeScript. Designed for a seamless developer experience with powerful abstractions, dynamic orchestration, and full cont
The npm package chrono-forge receives a total of 846 weekly downloads. As such, chrono-forge popularity was classified as not popular.
We found that chrono-forge demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.