Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta 16 #16

Merged
merged 8 commits into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = {
"@typescript-eslint/comma-dangle": ["error","always-multiline"],
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/no-unused-vars": "warn",
"@typescript-eslint/no-extraneous-class": "off"
"@typescript-eslint/no-extraneous-class": "off",
"@typescript-eslint/member-delimiter-style": "off"
}
}
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ jobs:
- name: Build 📦
run: npm run build

# - name: Run tests 🧪
# run: npm test
- name: Run tests 🧪
run: npm test

7 changes: 7 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"recommendations": [
"azurite.azurite",
"connor4312.nodejs-testing",
"yoavbls.pretty-ts-errors"
]
}
62 changes: 45 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "simple-workflows",
"version": "0.1.0-beta15",
"version": "0.1.0-beta16",
"description": "Workflows as code in TypeScript",
"main": "lib/index.js",
"type": "module",
"engines": {
"node": ">=18.17.0"
},
Expand All @@ -13,7 +14,7 @@
"scripts": {
"build": "npx tsc",
"build-watch": "npx tsc -w",
"test": "node --trace-warnings --test lib/tests/",
"test": "node --test",
"lint": "eslint ./src/ --ext .ts"
},
"author": "Allan Hvam",
Expand All @@ -27,13 +28,14 @@
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-n": "^16.5.0",
"eslint-plugin-promise": "^6.1.1",
"superjson": "^1.12.1",
"superjson": "^2.2.1",
"typescript": "^5.3.3"
},
"dependencies": {
"@azure/data-tables": "^13.0.1",
"@azure/storage-blob": "^12.10.0",
"async-mutex": "^0.4.0",
"ms": "^2.1.3"
"ms": "^2.1.3",
"nanoid": "^5.0.7"
}
}
4 changes: 2 additions & 2 deletions src/DefaultRetryPolicy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type IRetryPolicy } from "./IRetryPolicy";
import { sleep } from "./sleep";
import { type IRetryPolicy } from "./IRetryPolicy.js";
import { sleep } from "./sleep.js";

/**
* @internal
Expand Down
2 changes: 1 addition & 1 deletion src/DefaultSerializer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ISerializer } from "./ISerializer";
import { type ISerializer } from "./ISerializer.js";

/**
* @internal
Expand Down
4 changes: 2 additions & 2 deletions src/IWorker.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type IWorkflowHistoryStore } from "./stores/IWorkflowHistoryStore";
import { type BaseWorkflowHandle, type Workflow } from "./Workflow";
import { type IWorkflowHistoryStore } from "./stores/IWorkflowHistoryStore.js";
import { type BaseWorkflowHandle, type Workflow } from "./Workflow.js";

export declare type WithWorkflowArgs<W extends Workflow, T> = T & (Parameters<W> extends [any, ...any[]] ? {
/**
Expand Down
2 changes: 1 addition & 1 deletion src/IWorkflowContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type IWorkflowHistoryStore } from "./stores/IWorkflowHistoryStore";
import { type IWorkflowHistoryStore } from "./stores/IWorkflowHistoryStore.js";
import { type MutexInterface } from "async-mutex";

export interface IWorkflowContext {
Expand Down
20 changes: 10 additions & 10 deletions src/Worker.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { AsyncLocalStorage } from "async_hooks";
import { type IWorkflowContext } from "./IWorkflowContext";
import { type IWorkflowHistoryStore } from "./stores/IWorkflowHistoryStore";
import { MemoryWorkflowHistoryStore } from "./stores/MemoryWorkflowHistoryStore";
import { type BaseWorkflowHandle, type Workflow, type WorkflowResultType, type WorkflowReturnType } from "./Workflow";
import { type IWorkflowContext } from "./IWorkflowContext.js";
import { type IWorkflowHistoryStore } from "./stores/IWorkflowHistoryStore.js";
import { MemoryWorkflowHistoryStore } from "./stores/MemoryWorkflowHistoryStore.js";
import { type BaseWorkflowHandle, type Workflow, type WorkflowResultType, type WorkflowReturnType } from "./Workflow.js";
import msPkg from "ms";
import { deserializeError, serializeError } from "./serialize-error";
import { Mutex } from "async-mutex";
import { sleep } from "./sleep";
import { type IWorker, type WorkflowStartOptions } from "./IWorker";
import { sleep } from "./sleep.js";
import { type IWorker, type WorkflowStartOptions } from "./IWorker.js";
import { nanoid } from "nanoid";

export class Worker implements IWorker {
public static asyncLocalStorage = new AsyncLocalStorage<IWorkflowContext>();
Expand All @@ -29,7 +29,7 @@ export class Worker implements IWorker {
}

public async start<T extends Workflow>(workflow: T, options?: WorkflowStartOptions<T>): Promise<BaseWorkflowHandle<T>> {
let workflowId = "wf-id-" + Math.floor(Math.random() * 1000);
let workflowId = "workflow-" + nanoid();
if (options?.workflowId) {
workflowId = options.workflowId;
}
Expand Down Expand Up @@ -79,7 +79,7 @@ export class Worker implements IWorker {
workflowId,
store,
result: async () => {
const reason = deserializeError(error);
const reason = error;
return await Promise.reject(reason);
},
};
Expand Down Expand Up @@ -133,7 +133,7 @@ export class Worker implements IWorker {
workflowInstance.result = result;
} else {
workflowContext.log(() => `${workflowId}: end (error, ${duration})`);
workflowInstance.error = serializeError(error);
workflowInstance.error = error;
}

if (store) {
Expand Down
2 changes: 1 addition & 1 deletion src/Workflow.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type IWorkflowHistoryStore } from "./stores/IWorkflowHistoryStore";
import { type IWorkflowHistoryStore } from "./stores/IWorkflowHistoryStore.js";

export declare type WorkflowReturnType = Promise<any>;

Expand Down
4 changes: 2 additions & 2 deletions src/WorkflowContext.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type IWorkflowContext } from "./IWorkflowContext";
import { Worker } from "./Worker";
import { type IWorkflowContext } from "./IWorkflowContext.js";
import { Worker } from "./Worker.js";

export class WorkflowContext {
public static current(): IWorkflowContext | undefined {
Expand Down
12 changes: 6 additions & 6 deletions src/debug.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Worker } from "./Worker";
import { greetWorkflow } from "./tests/workflows/greet-workflow";
import { FileSystemWorkflowHistoryStore } from "./stores/FileSystemWorkflowHistoryStore";
import { Worker } from "./Worker.js";
import { greetWorkflow } from "./tests/workflows/greet-workflow.js";
import { FileSystemWorkflowHistoryStore } from "./stores/FileSystemWorkflowHistoryStore.js";

let run = async () => {
const run = async (): Promise<void> => {
const worker = Worker.getInstance();
worker.store = new FileSystemWorkflowHistoryStore();

Expand All @@ -14,12 +14,12 @@ let run = async () => {
// Assert
console.log(`Started workflow ${handle.workflowId}`);

let result = await handle.result();
const result = await handle.result();
console.dir(result);
};

run().then(() => {
process.exit();
}).catch((e) => {
console.error(e);
});
});
12 changes: 6 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from "./proxyActivities";
export { Worker as WorkflowWorker } from "./Worker";
export * from "./stores/";
export * from "./IWorker";
export * from "./WorkflowContext";
export * from "./IWorkflowContext";
export * from "./proxyActivities.js";
export { Worker as WorkflowWorker } from "./Worker.js";
export * from "./stores/index.js";
export * from "./IWorker.js";
export * from "./WorkflowContext.js";
export * from "./IWorkflowContext.js";
15 changes: 7 additions & 8 deletions src/proxyActivities.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { isDeepStrictEqual } from "node:util";
import { DefaultRetryPolicy } from "./DefaultRetryPolicy";
import { deserializeError, serializeError } from "./serialize-error";
import { type WorkflowActivityInstance, type WorkflowInstance } from "./stores/IWorkflowHistoryStore";
import { Worker } from "./Worker";
import { DefaultRetryPolicy } from "./DefaultRetryPolicy.js";
import type { WorkflowActivity, WorkflowInstance } from "./stores/IWorkflowHistoryStore.js";
import { Worker } from "./Worker.js";

type PromiseFuncKeys<T> = {
[K in keyof T]: T[K] extends ((...args: any[]) => Promise<any>) ? K : never;
Expand Down Expand Up @@ -57,7 +56,7 @@ export function proxyActivities<A extends object>(activities: A, options?: { ret
}

let activityName = String(activityType);
if (obj.constructor.name && obj.constructor.name !== "Object") {
if (obj.constructor?.name && obj.constructor?.name !== "Object") {
activityName = `${obj.constructor.name}.${activityType}`;
}
const logPrefix = `${workflowId}/${activityName}${logArgs}`;
Expand All @@ -67,7 +66,7 @@ export function proxyActivities<A extends object>(activities: A, options?: { ret
// NOTE: if object is passed, make sure we have a copy of it, if it is changed later
const originalArgs = structuredClone(args);

const startActivity = await mutex.runExclusive(async (): Promise<WorkflowActivityInstance | "timeout" | undefined> => {
const startActivity = await mutex.runExclusive(async (): Promise<WorkflowActivity | "timeout" | undefined> => {
const instance = await store?.getInstance(workflowId);
if (instance?.status === "timeout") {
return instance?.status;
Expand Down Expand Up @@ -103,7 +102,7 @@ export function proxyActivities<A extends object>(activities: A, options?: { ret
return activity.result;
} else if (activity && Object.prototype.hasOwnProperty.call(activity, "error")) {
log(() => `${logPrefix}: skip (error)`);
const reason = deserializeError(activity.error);
const reason = activity.error;
return await Promise.reject(reason);
}

Expand Down Expand Up @@ -154,7 +153,7 @@ export function proxyActivities<A extends object>(activities: A, options?: { ret
activity.end = new Date();
const duration = `${activity.end.getTime() - activity.start.getTime()} ms`;
if (error) {
activity.error = serializeError(error);
activity.error = error;
log(() => `${logPrefix}: end (error, ${executions > 1 ? `${executions} executions, ` : ""}${duration})`);
} else {
activity.result = result;
Expand Down
2 changes: 1 addition & 1 deletion src/serialize-error/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface IOptions {
}

export class NonError extends Error {
name = "NonError";
override name = "NonError";

constructor(message) {
super(NonError.prepareSuperMessage(message));
Expand Down
Loading