@astami/temporal-functions 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.
- package/README.md +215 -0
- package/dist/client/index.d.mts +34 -0
- package/dist/client/index.d.ts +34 -0
- package/dist/client/index.js +168 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +162 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/index.d.mts +133 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +120 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +111 -0
- package/dist/index.mjs.map +1 -0
- package/dist/testing/index.d.mts +74 -0
- package/dist/testing/index.d.ts +74 -0
- package/dist/testing/index.js +129 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/index.mjs +121 -0
- package/dist/testing/index.mjs.map +1 -0
- package/dist/types-C-cNq1Id.d.mts +292 -0
- package/dist/types-C-cNq1Id.d.ts +292 -0
- package/dist/worker/index.d.mts +37 -0
- package/dist/worker/index.d.ts +37 -0
- package/dist/worker/index.js +239 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/index.mjs +233 -0
- package/dist/worker/index.mjs.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { a as FunctionDef, c as WorkflowDef, d as WorkflowContext } from '../types-C-cNq1Id.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Temporal Functions - Testing Utilities
|
|
5
|
+
*
|
|
6
|
+
* Utilities for testing functions and workflows.
|
|
7
|
+
* Import from 'temporal-functions/testing'.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Create a mock workflow context for testing
|
|
12
|
+
*/
|
|
13
|
+
declare function createMockContext(overrides?: Partial<WorkflowContext>): WorkflowContext;
|
|
14
|
+
/**
|
|
15
|
+
* Test environment for running workflows in isolation
|
|
16
|
+
*/
|
|
17
|
+
declare class TestEnvironment {
|
|
18
|
+
private mocks;
|
|
19
|
+
private currentTime;
|
|
20
|
+
/**
|
|
21
|
+
* Mock a function's implementation
|
|
22
|
+
*/
|
|
23
|
+
mock<TInput, TOutput>(fn: FunctionDef<TInput, TOutput>, implementation: (input: TInput) => Promise<TOutput> | TOutput): this;
|
|
24
|
+
/**
|
|
25
|
+
* Set the current time for the test
|
|
26
|
+
*/
|
|
27
|
+
setTime(time: Date): this;
|
|
28
|
+
/**
|
|
29
|
+
* Execute a workflow with the test environment
|
|
30
|
+
*/
|
|
31
|
+
execute<TInput, TOutput>(workflow: WorkflowDef<TInput, TOutput>, input: TInput): Promise<TOutput>;
|
|
32
|
+
/**
|
|
33
|
+
* Start a workflow and return a handle for interaction
|
|
34
|
+
*/
|
|
35
|
+
start<TInput, TOutput>(workflow: WorkflowDef<TInput, TOutput>, input: TInput): Promise<TestWorkflowHandle<TOutput>>;
|
|
36
|
+
/**
|
|
37
|
+
* Create a workflow context with mocks applied
|
|
38
|
+
*/
|
|
39
|
+
private createContext;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Handle to a test workflow execution
|
|
43
|
+
*/
|
|
44
|
+
interface TestWorkflowHandle<TOutput> {
|
|
45
|
+
/** Wait for the workflow result */
|
|
46
|
+
result(): Promise<TOutput>;
|
|
47
|
+
/** Send a signal to the workflow */
|
|
48
|
+
signal<TPayload>(signalName: string, payload: TPayload): Promise<void>;
|
|
49
|
+
/** Query the workflow */
|
|
50
|
+
query<TResult>(queryName: string): TResult;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create a test environment
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* import { tfn } from 'temporal-functions/testing';
|
|
58
|
+
*
|
|
59
|
+
* const env = await tfn.testEnv();
|
|
60
|
+
*
|
|
61
|
+
* env.mock(sendEmail, async (params) => ({
|
|
62
|
+
* messageId: 'test-id',
|
|
63
|
+
* }));
|
|
64
|
+
*
|
|
65
|
+
* const result = await env.execute(myWorkflow, { data: 'test' });
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
declare function createTestEnv(): Promise<TestEnvironment>;
|
|
69
|
+
declare const tfn: {
|
|
70
|
+
testEnv: typeof createTestEnv;
|
|
71
|
+
mockContext: typeof createMockContext;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export { TestEnvironment, type TestWorkflowHandle, createMockContext, createTestEnv, tfn as default, tfn };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
// src/testing/index.ts
|
|
6
|
+
function createMockContext(overrides = {}) {
|
|
7
|
+
const signalHandlers = /* @__PURE__ */ new Map();
|
|
8
|
+
const queryHandlers = /* @__PURE__ */ new Map();
|
|
9
|
+
const mockInfo = {
|
|
10
|
+
workflowId: "test-workflow-id",
|
|
11
|
+
runId: "test-run-id",
|
|
12
|
+
taskQueue: "test-queue",
|
|
13
|
+
workflowType: "test-workflow",
|
|
14
|
+
namespace: "default"
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
run: async (fn, input) => {
|
|
18
|
+
return fn.handler(input);
|
|
19
|
+
},
|
|
20
|
+
sleep: async () => {
|
|
21
|
+
},
|
|
22
|
+
now: () => /* @__PURE__ */ new Date(),
|
|
23
|
+
startChild: async () => {
|
|
24
|
+
throw new Error("startChild not implemented in mock context");
|
|
25
|
+
},
|
|
26
|
+
continueAsNew: async () => {
|
|
27
|
+
throw new Error("continueAsNew not implemented in mock context");
|
|
28
|
+
},
|
|
29
|
+
onSignal: (signalName, handler) => {
|
|
30
|
+
signalHandlers.set(signalName, handler);
|
|
31
|
+
},
|
|
32
|
+
onQuery: (queryName, handler) => {
|
|
33
|
+
queryHandlers.set(queryName, handler);
|
|
34
|
+
},
|
|
35
|
+
info: mockInfo,
|
|
36
|
+
...overrides
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
var TestEnvironment = class {
|
|
40
|
+
mocks = /* @__PURE__ */ new Map();
|
|
41
|
+
currentTime = /* @__PURE__ */ new Date();
|
|
42
|
+
/**
|
|
43
|
+
* Mock a function's implementation
|
|
44
|
+
*/
|
|
45
|
+
mock(fn, implementation) {
|
|
46
|
+
this.mocks.set(fn.name, async (input) => {
|
|
47
|
+
return implementation(input);
|
|
48
|
+
});
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Set the current time for the test
|
|
53
|
+
*/
|
|
54
|
+
setTime(time) {
|
|
55
|
+
this.currentTime = time;
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Execute a workflow with the test environment
|
|
60
|
+
*/
|
|
61
|
+
async execute(workflow, input) {
|
|
62
|
+
const ctx = this.createContext();
|
|
63
|
+
return workflow.handler(ctx, input);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Start a workflow and return a handle for interaction
|
|
67
|
+
*/
|
|
68
|
+
async start(workflow, input) {
|
|
69
|
+
const signalHandlers = /* @__PURE__ */ new Map();
|
|
70
|
+
const queryHandlers = /* @__PURE__ */ new Map();
|
|
71
|
+
const ctx = this.createContext({
|
|
72
|
+
onSignal: (signalName, handler) => {
|
|
73
|
+
signalHandlers.set(signalName, handler);
|
|
74
|
+
},
|
|
75
|
+
onQuery: (queryName, handler) => {
|
|
76
|
+
queryHandlers.set(queryName, handler);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
const resultPromise = workflow.handler(ctx, input);
|
|
80
|
+
return {
|
|
81
|
+
result: () => resultPromise,
|
|
82
|
+
signal: async (signalName, payload) => {
|
|
83
|
+
const handler = signalHandlers.get(signalName);
|
|
84
|
+
if (handler) {
|
|
85
|
+
handler(payload);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
query: (queryName) => {
|
|
89
|
+
const handler = queryHandlers.get(queryName);
|
|
90
|
+
if (handler) {
|
|
91
|
+
return handler();
|
|
92
|
+
}
|
|
93
|
+
throw new Error(`Query handler not found: ${queryName}`);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Create a workflow context with mocks applied
|
|
99
|
+
*/
|
|
100
|
+
createContext(overrides = {}) {
|
|
101
|
+
return createMockContext({
|
|
102
|
+
run: async (fn, input) => {
|
|
103
|
+
const mock = this.mocks.get(fn.name);
|
|
104
|
+
if (mock) {
|
|
105
|
+
return mock(input);
|
|
106
|
+
}
|
|
107
|
+
return fn.handler(input);
|
|
108
|
+
},
|
|
109
|
+
now: () => this.currentTime,
|
|
110
|
+
...overrides
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
async function createTestEnv() {
|
|
115
|
+
return new TestEnvironment();
|
|
116
|
+
}
|
|
117
|
+
var tfn = {
|
|
118
|
+
testEnv: createTestEnv,
|
|
119
|
+
mockContext: createMockContext
|
|
120
|
+
};
|
|
121
|
+
var testing_default = tfn;
|
|
122
|
+
|
|
123
|
+
exports.TestEnvironment = TestEnvironment;
|
|
124
|
+
exports.createMockContext = createMockContext;
|
|
125
|
+
exports.createTestEnv = createTestEnv;
|
|
126
|
+
exports.default = testing_default;
|
|
127
|
+
exports.tfn = tfn;
|
|
128
|
+
//# sourceMappingURL=index.js.map
|
|
129
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/testing/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Temporal Functions - Testing Utilities\n *\n * Utilities for testing functions and workflows.\n * Import from 'temporal-functions/testing'.\n */\n\nimport type {\n FunctionDef,\n WorkflowDef,\n WorkflowContext,\n WorkflowInfo,\n} from '../types.js';\n\n// =============================================================================\n// Mock Context\n// =============================================================================\n\n/**\n * Create a mock workflow context for testing\n */\nfunction createMockContext(overrides: Partial<WorkflowContext> = {}): WorkflowContext {\n const signalHandlers = new Map<string, (payload: unknown) => void>();\n const queryHandlers = new Map<string, () => unknown>();\n\n const mockInfo: WorkflowInfo = {\n workflowId: 'test-workflow-id',\n runId: 'test-run-id',\n taskQueue: 'test-queue',\n workflowType: 'test-workflow',\n namespace: 'default',\n };\n\n return {\n run: async <TInput, TOutput>(\n fn: FunctionDef<TInput, TOutput>,\n input: TInput\n ): Promise<TOutput> => {\n return fn.handler(input);\n },\n sleep: async () => {\n // No-op in tests by default\n },\n now: () => new Date(),\n startChild: async () => {\n throw new Error('startChild not implemented in mock context');\n },\n continueAsNew: async () => {\n throw new Error('continueAsNew not implemented in mock context');\n },\n onSignal: <TPayload = unknown>(signalName: string, handler: (payload: TPayload) => void) => {\n signalHandlers.set(signalName, handler as (payload: unknown) => void);\n },\n onQuery: (queryName, handler) => {\n queryHandlers.set(queryName, handler);\n },\n info: mockInfo,\n ...overrides,\n };\n}\n\n// =============================================================================\n// Test Environment\n// =============================================================================\n\ninterface MockedFunction<TInput, TOutput> {\n fn: FunctionDef<TInput, TOutput>;\n mock: (input: TInput) => Promise<TOutput>;\n}\n\n/**\n * Test environment for running workflows in isolation\n */\nclass TestEnvironment {\n private mocks: Map<string, (input: unknown) => Promise<unknown>> = new Map();\n private currentTime: Date = new Date();\n\n /**\n * Mock a function's implementation\n */\n mock<TInput, TOutput>(\n fn: FunctionDef<TInput, TOutput>,\n implementation: (input: TInput) => Promise<TOutput> | TOutput\n ): this {\n this.mocks.set(fn.name, async (input: unknown) => {\n return implementation(input as TInput);\n });\n return this;\n }\n\n /**\n * Set the current time for the test\n */\n setTime(time: Date): this {\n this.currentTime = time;\n return this;\n }\n\n /**\n * Execute a workflow with the test environment\n */\n async execute<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput\n ): Promise<TOutput> {\n const ctx = this.createContext();\n return workflow.handler(ctx, input);\n }\n\n /**\n * Start a workflow and return a handle for interaction\n */\n async start<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput\n ): Promise<TestWorkflowHandle<TOutput>> {\n const signalHandlers = new Map<string, (payload: unknown) => void>();\n const queryHandlers = new Map<string, () => unknown>();\n\n const ctx = this.createContext({\n onSignal: <TPayload = unknown>(signalName: string, handler: (payload: TPayload) => void) => {\n signalHandlers.set(signalName, handler as (payload: unknown) => void);\n },\n onQuery: (queryName, handler) => {\n queryHandlers.set(queryName, handler);\n },\n });\n\n const resultPromise = workflow.handler(ctx, input);\n\n return {\n result: () => resultPromise,\n signal: async <TPayload>(signalName: string, payload: TPayload) => {\n const handler = signalHandlers.get(signalName);\n if (handler) {\n handler(payload);\n }\n },\n query: <TResult>(queryName: string): TResult => {\n const handler = queryHandlers.get(queryName);\n if (handler) {\n return handler() as TResult;\n }\n throw new Error(`Query handler not found: ${queryName}`);\n },\n };\n }\n\n /**\n * Create a workflow context with mocks applied\n */\n private createContext(overrides: Partial<WorkflowContext> = {}): WorkflowContext {\n return createMockContext({\n run: async <TInput, TOutput>(\n fn: FunctionDef<TInput, TOutput>,\n input: TInput\n ): Promise<TOutput> => {\n const mock = this.mocks.get(fn.name);\n if (mock) {\n return mock(input) as Promise<TOutput>;\n }\n // Fall back to actual implementation\n return fn.handler(input);\n },\n now: () => this.currentTime,\n ...overrides,\n });\n }\n}\n\n/**\n * Handle to a test workflow execution\n */\ninterface TestWorkflowHandle<TOutput> {\n /** Wait for the workflow result */\n result(): Promise<TOutput>;\n /** Send a signal to the workflow */\n signal<TPayload>(signalName: string, payload: TPayload): Promise<void>;\n /** Query the workflow */\n query<TResult>(queryName: string): TResult;\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Create a test environment\n *\n * @example\n * ```typescript\n * import { tfn } from 'temporal-functions/testing';\n *\n * const env = await tfn.testEnv();\n *\n * env.mock(sendEmail, async (params) => ({\n * messageId: 'test-id',\n * }));\n *\n * const result = await env.execute(myWorkflow, { data: 'test' });\n * ```\n */\nasync function createTestEnv(): Promise<TestEnvironment> {\n return new TestEnvironment();\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n testEnv: createTestEnv,\n mockContext: createMockContext,\n};\n\nexport { createTestEnv, createMockContext, TestEnvironment };\nexport type { TestWorkflowHandle };\nexport default tfn;\n"]}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// src/testing/index.ts
|
|
2
|
+
function createMockContext(overrides = {}) {
|
|
3
|
+
const signalHandlers = /* @__PURE__ */ new Map();
|
|
4
|
+
const queryHandlers = /* @__PURE__ */ new Map();
|
|
5
|
+
const mockInfo = {
|
|
6
|
+
workflowId: "test-workflow-id",
|
|
7
|
+
runId: "test-run-id",
|
|
8
|
+
taskQueue: "test-queue",
|
|
9
|
+
workflowType: "test-workflow",
|
|
10
|
+
namespace: "default"
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
run: async (fn, input) => {
|
|
14
|
+
return fn.handler(input);
|
|
15
|
+
},
|
|
16
|
+
sleep: async () => {
|
|
17
|
+
},
|
|
18
|
+
now: () => /* @__PURE__ */ new Date(),
|
|
19
|
+
startChild: async () => {
|
|
20
|
+
throw new Error("startChild not implemented in mock context");
|
|
21
|
+
},
|
|
22
|
+
continueAsNew: async () => {
|
|
23
|
+
throw new Error("continueAsNew not implemented in mock context");
|
|
24
|
+
},
|
|
25
|
+
onSignal: (signalName, handler) => {
|
|
26
|
+
signalHandlers.set(signalName, handler);
|
|
27
|
+
},
|
|
28
|
+
onQuery: (queryName, handler) => {
|
|
29
|
+
queryHandlers.set(queryName, handler);
|
|
30
|
+
},
|
|
31
|
+
info: mockInfo,
|
|
32
|
+
...overrides
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
var TestEnvironment = class {
|
|
36
|
+
mocks = /* @__PURE__ */ new Map();
|
|
37
|
+
currentTime = /* @__PURE__ */ new Date();
|
|
38
|
+
/**
|
|
39
|
+
* Mock a function's implementation
|
|
40
|
+
*/
|
|
41
|
+
mock(fn, implementation) {
|
|
42
|
+
this.mocks.set(fn.name, async (input) => {
|
|
43
|
+
return implementation(input);
|
|
44
|
+
});
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Set the current time for the test
|
|
49
|
+
*/
|
|
50
|
+
setTime(time) {
|
|
51
|
+
this.currentTime = time;
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute a workflow with the test environment
|
|
56
|
+
*/
|
|
57
|
+
async execute(workflow, input) {
|
|
58
|
+
const ctx = this.createContext();
|
|
59
|
+
return workflow.handler(ctx, input);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Start a workflow and return a handle for interaction
|
|
63
|
+
*/
|
|
64
|
+
async start(workflow, input) {
|
|
65
|
+
const signalHandlers = /* @__PURE__ */ new Map();
|
|
66
|
+
const queryHandlers = /* @__PURE__ */ new Map();
|
|
67
|
+
const ctx = this.createContext({
|
|
68
|
+
onSignal: (signalName, handler) => {
|
|
69
|
+
signalHandlers.set(signalName, handler);
|
|
70
|
+
},
|
|
71
|
+
onQuery: (queryName, handler) => {
|
|
72
|
+
queryHandlers.set(queryName, handler);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const resultPromise = workflow.handler(ctx, input);
|
|
76
|
+
return {
|
|
77
|
+
result: () => resultPromise,
|
|
78
|
+
signal: async (signalName, payload) => {
|
|
79
|
+
const handler = signalHandlers.get(signalName);
|
|
80
|
+
if (handler) {
|
|
81
|
+
handler(payload);
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
query: (queryName) => {
|
|
85
|
+
const handler = queryHandlers.get(queryName);
|
|
86
|
+
if (handler) {
|
|
87
|
+
return handler();
|
|
88
|
+
}
|
|
89
|
+
throw new Error(`Query handler not found: ${queryName}`);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Create a workflow context with mocks applied
|
|
95
|
+
*/
|
|
96
|
+
createContext(overrides = {}) {
|
|
97
|
+
return createMockContext({
|
|
98
|
+
run: async (fn, input) => {
|
|
99
|
+
const mock = this.mocks.get(fn.name);
|
|
100
|
+
if (mock) {
|
|
101
|
+
return mock(input);
|
|
102
|
+
}
|
|
103
|
+
return fn.handler(input);
|
|
104
|
+
},
|
|
105
|
+
now: () => this.currentTime,
|
|
106
|
+
...overrides
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
async function createTestEnv() {
|
|
111
|
+
return new TestEnvironment();
|
|
112
|
+
}
|
|
113
|
+
var tfn = {
|
|
114
|
+
testEnv: createTestEnv,
|
|
115
|
+
mockContext: createMockContext
|
|
116
|
+
};
|
|
117
|
+
var testing_default = tfn;
|
|
118
|
+
|
|
119
|
+
export { TestEnvironment, createMockContext, createTestEnv, testing_default as default, tfn };
|
|
120
|
+
//# sourceMappingURL=index.mjs.map
|
|
121
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/testing/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Temporal Functions - Testing Utilities\n *\n * Utilities for testing functions and workflows.\n * Import from 'temporal-functions/testing'.\n */\n\nimport type {\n FunctionDef,\n WorkflowDef,\n WorkflowContext,\n WorkflowInfo,\n} from '../types.js';\n\n// =============================================================================\n// Mock Context\n// =============================================================================\n\n/**\n * Create a mock workflow context for testing\n */\nfunction createMockContext(overrides: Partial<WorkflowContext> = {}): WorkflowContext {\n const signalHandlers = new Map<string, (payload: unknown) => void>();\n const queryHandlers = new Map<string, () => unknown>();\n\n const mockInfo: WorkflowInfo = {\n workflowId: 'test-workflow-id',\n runId: 'test-run-id',\n taskQueue: 'test-queue',\n workflowType: 'test-workflow',\n namespace: 'default',\n };\n\n return {\n run: async <TInput, TOutput>(\n fn: FunctionDef<TInput, TOutput>,\n input: TInput\n ): Promise<TOutput> => {\n return fn.handler(input);\n },\n sleep: async () => {\n // No-op in tests by default\n },\n now: () => new Date(),\n startChild: async () => {\n throw new Error('startChild not implemented in mock context');\n },\n continueAsNew: async () => {\n throw new Error('continueAsNew not implemented in mock context');\n },\n onSignal: <TPayload = unknown>(signalName: string, handler: (payload: TPayload) => void) => {\n signalHandlers.set(signalName, handler as (payload: unknown) => void);\n },\n onQuery: (queryName, handler) => {\n queryHandlers.set(queryName, handler);\n },\n info: mockInfo,\n ...overrides,\n };\n}\n\n// =============================================================================\n// Test Environment\n// =============================================================================\n\ninterface MockedFunction<TInput, TOutput> {\n fn: FunctionDef<TInput, TOutput>;\n mock: (input: TInput) => Promise<TOutput>;\n}\n\n/**\n * Test environment for running workflows in isolation\n */\nclass TestEnvironment {\n private mocks: Map<string, (input: unknown) => Promise<unknown>> = new Map();\n private currentTime: Date = new Date();\n\n /**\n * Mock a function's implementation\n */\n mock<TInput, TOutput>(\n fn: FunctionDef<TInput, TOutput>,\n implementation: (input: TInput) => Promise<TOutput> | TOutput\n ): this {\n this.mocks.set(fn.name, async (input: unknown) => {\n return implementation(input as TInput);\n });\n return this;\n }\n\n /**\n * Set the current time for the test\n */\n setTime(time: Date): this {\n this.currentTime = time;\n return this;\n }\n\n /**\n * Execute a workflow with the test environment\n */\n async execute<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput\n ): Promise<TOutput> {\n const ctx = this.createContext();\n return workflow.handler(ctx, input);\n }\n\n /**\n * Start a workflow and return a handle for interaction\n */\n async start<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput\n ): Promise<TestWorkflowHandle<TOutput>> {\n const signalHandlers = new Map<string, (payload: unknown) => void>();\n const queryHandlers = new Map<string, () => unknown>();\n\n const ctx = this.createContext({\n onSignal: <TPayload = unknown>(signalName: string, handler: (payload: TPayload) => void) => {\n signalHandlers.set(signalName, handler as (payload: unknown) => void);\n },\n onQuery: (queryName, handler) => {\n queryHandlers.set(queryName, handler);\n },\n });\n\n const resultPromise = workflow.handler(ctx, input);\n\n return {\n result: () => resultPromise,\n signal: async <TPayload>(signalName: string, payload: TPayload) => {\n const handler = signalHandlers.get(signalName);\n if (handler) {\n handler(payload);\n }\n },\n query: <TResult>(queryName: string): TResult => {\n const handler = queryHandlers.get(queryName);\n if (handler) {\n return handler() as TResult;\n }\n throw new Error(`Query handler not found: ${queryName}`);\n },\n };\n }\n\n /**\n * Create a workflow context with mocks applied\n */\n private createContext(overrides: Partial<WorkflowContext> = {}): WorkflowContext {\n return createMockContext({\n run: async <TInput, TOutput>(\n fn: FunctionDef<TInput, TOutput>,\n input: TInput\n ): Promise<TOutput> => {\n const mock = this.mocks.get(fn.name);\n if (mock) {\n return mock(input) as Promise<TOutput>;\n }\n // Fall back to actual implementation\n return fn.handler(input);\n },\n now: () => this.currentTime,\n ...overrides,\n });\n }\n}\n\n/**\n * Handle to a test workflow execution\n */\ninterface TestWorkflowHandle<TOutput> {\n /** Wait for the workflow result */\n result(): Promise<TOutput>;\n /** Send a signal to the workflow */\n signal<TPayload>(signalName: string, payload: TPayload): Promise<void>;\n /** Query the workflow */\n query<TResult>(queryName: string): TResult;\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Create a test environment\n *\n * @example\n * ```typescript\n * import { tfn } from 'temporal-functions/testing';\n *\n * const env = await tfn.testEnv();\n *\n * env.mock(sendEmail, async (params) => ({\n * messageId: 'test-id',\n * }));\n *\n * const result = await env.execute(myWorkflow, { data: 'test' });\n * ```\n */\nasync function createTestEnv(): Promise<TestEnvironment> {\n return new TestEnvironment();\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n testEnv: createTestEnv,\n mockContext: createMockContext,\n};\n\nexport { createTestEnv, createMockContext, TestEnvironment };\nexport type { TestWorkflowHandle };\nexport default tfn;\n"]}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for Temporal Functions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Options for configuring a function (activity)
|
|
6
|
+
*/
|
|
7
|
+
interface FunctionOptions {
|
|
8
|
+
/** Start-to-close timeout (e.g., '30s', '5m') */
|
|
9
|
+
startToCloseTimeout?: string;
|
|
10
|
+
/** Schedule-to-close timeout */
|
|
11
|
+
scheduleToCloseTimeout?: string;
|
|
12
|
+
/** Heartbeat timeout for long-running activities */
|
|
13
|
+
heartbeatTimeout?: string;
|
|
14
|
+
/** Retry policy configuration */
|
|
15
|
+
retry?: RetryPolicy;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Retry policy for functions
|
|
19
|
+
*/
|
|
20
|
+
interface RetryPolicy {
|
|
21
|
+
/** Maximum number of retry attempts */
|
|
22
|
+
maximumAttempts?: number;
|
|
23
|
+
/** Initial retry interval (e.g., '1s') */
|
|
24
|
+
initialInterval?: string;
|
|
25
|
+
/** Maximum retry interval (e.g., '30s') */
|
|
26
|
+
maximumInterval?: string;
|
|
27
|
+
/** Backoff coefficient for exponential backoff */
|
|
28
|
+
backoffCoefficient?: number;
|
|
29
|
+
/** List of error types that should not be retried */
|
|
30
|
+
nonRetryableErrorTypes?: string[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Definition of a function (maps to Temporal Activity)
|
|
34
|
+
*/
|
|
35
|
+
interface FunctionDef<TInput = unknown, TOutput = unknown> {
|
|
36
|
+
/** Unique identifier for the function */
|
|
37
|
+
name: string;
|
|
38
|
+
/** The function implementation */
|
|
39
|
+
handler: (input: TInput) => Promise<TOutput>;
|
|
40
|
+
/** Configuration options */
|
|
41
|
+
options: FunctionOptions;
|
|
42
|
+
/** Type marker */
|
|
43
|
+
__type: 'function';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Options for configuring a workflow
|
|
47
|
+
*/
|
|
48
|
+
interface WorkflowOptions {
|
|
49
|
+
/** Task queue for this workflow (defaults to 'default') */
|
|
50
|
+
taskQueue?: string;
|
|
51
|
+
/** Workflow execution timeout */
|
|
52
|
+
workflowExecutionTimeout?: string;
|
|
53
|
+
/** Workflow run timeout */
|
|
54
|
+
workflowRunTimeout?: string;
|
|
55
|
+
/** Workflow task timeout */
|
|
56
|
+
workflowTaskTimeout?: string;
|
|
57
|
+
/** Retry policy for the workflow */
|
|
58
|
+
retry?: RetryPolicy;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Workflow information available at runtime
|
|
62
|
+
*/
|
|
63
|
+
interface WorkflowInfo {
|
|
64
|
+
/** Unique workflow ID */
|
|
65
|
+
workflowId: string;
|
|
66
|
+
/** Current run ID */
|
|
67
|
+
runId: string;
|
|
68
|
+
/** Task queue the workflow is running on */
|
|
69
|
+
taskQueue: string;
|
|
70
|
+
/** Workflow type name */
|
|
71
|
+
workflowType: string;
|
|
72
|
+
/** Namespace */
|
|
73
|
+
namespace: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Context object passed to workflow functions
|
|
77
|
+
*/
|
|
78
|
+
interface WorkflowContext {
|
|
79
|
+
/**
|
|
80
|
+
* Run a function (activity) within the workflow
|
|
81
|
+
*/
|
|
82
|
+
run<TInput, TOutput>(fn: FunctionDef<TInput, TOutput>, input: TInput, options?: Partial<FunctionOptions>): Promise<TOutput>;
|
|
83
|
+
/**
|
|
84
|
+
* Sleep for a duration
|
|
85
|
+
* @param duration - Duration string (e.g., '5m', '1h') or milliseconds
|
|
86
|
+
*/
|
|
87
|
+
sleep(duration: string | number): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Get the current workflow time (deterministic)
|
|
90
|
+
*/
|
|
91
|
+
now(): Date;
|
|
92
|
+
/**
|
|
93
|
+
* Start a child workflow
|
|
94
|
+
*/
|
|
95
|
+
startChild<TInput, TOutput>(workflow: WorkflowDef<TInput, TOutput>, input: TInput, options?: ChildWorkflowOptions): Promise<TOutput>;
|
|
96
|
+
/**
|
|
97
|
+
* Continue as new with fresh history
|
|
98
|
+
*/
|
|
99
|
+
continueAsNew<TInput>(input: TInput): Promise<never>;
|
|
100
|
+
/**
|
|
101
|
+
* Register a signal handler
|
|
102
|
+
*/
|
|
103
|
+
onSignal<TPayload = unknown>(signalName: string, handler: (payload: TPayload) => void): void;
|
|
104
|
+
/**
|
|
105
|
+
* Register a query handler
|
|
106
|
+
*/
|
|
107
|
+
onQuery<TResult = unknown>(queryName: string, handler: () => TResult): void;
|
|
108
|
+
/**
|
|
109
|
+
* Workflow information
|
|
110
|
+
*/
|
|
111
|
+
readonly info: WorkflowInfo;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Options for child workflows
|
|
115
|
+
*/
|
|
116
|
+
interface ChildWorkflowOptions {
|
|
117
|
+
workflowId?: string;
|
|
118
|
+
taskQueue?: string;
|
|
119
|
+
workflowExecutionTimeout?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Workflow handler function type
|
|
123
|
+
*/
|
|
124
|
+
type WorkflowHandler<TInput = unknown, TOutput = unknown> = (ctx: WorkflowContext, input: TInput) => Promise<TOutput>;
|
|
125
|
+
/**
|
|
126
|
+
* Definition of a workflow
|
|
127
|
+
*/
|
|
128
|
+
interface WorkflowDef<TInput = unknown, TOutput = unknown> {
|
|
129
|
+
/** Unique identifier for the workflow */
|
|
130
|
+
name: string;
|
|
131
|
+
/** The workflow implementation */
|
|
132
|
+
handler: WorkflowHandler<TInput, TOutput>;
|
|
133
|
+
/** Configuration options */
|
|
134
|
+
options: WorkflowOptions;
|
|
135
|
+
/** Type marker */
|
|
136
|
+
__type: 'workflow';
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Temporal connection configuration
|
|
140
|
+
*/
|
|
141
|
+
interface TemporalConfig {
|
|
142
|
+
/** Temporal server address (e.g., 'localhost:7233') */
|
|
143
|
+
address: string;
|
|
144
|
+
/** Namespace to use */
|
|
145
|
+
namespace?: string;
|
|
146
|
+
/** TLS configuration */
|
|
147
|
+
tls?: TLSConfig;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* TLS configuration for secure connections
|
|
151
|
+
*/
|
|
152
|
+
interface TLSConfig {
|
|
153
|
+
/** Path to client certificate */
|
|
154
|
+
clientCertPath?: string;
|
|
155
|
+
/** Path to client key */
|
|
156
|
+
clientKeyPath?: string;
|
|
157
|
+
/** Path to CA certificate */
|
|
158
|
+
serverRootCACertPath?: string;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Client configuration options
|
|
162
|
+
*/
|
|
163
|
+
interface ClientConfig {
|
|
164
|
+
/** Temporal connection settings */
|
|
165
|
+
temporal: TemporalConfig;
|
|
166
|
+
/** Default task queue for workflows */
|
|
167
|
+
taskQueue?: string;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Options when starting a workflow
|
|
171
|
+
*/
|
|
172
|
+
interface StartWorkflowOptions {
|
|
173
|
+
/** Custom workflow ID (for idempotency) */
|
|
174
|
+
workflowId?: string;
|
|
175
|
+
/** Override the default task queue */
|
|
176
|
+
taskQueue?: string;
|
|
177
|
+
/** Workflow execution timeout */
|
|
178
|
+
workflowExecutionTimeout?: string;
|
|
179
|
+
/** Memo fields */
|
|
180
|
+
memo?: Record<string, unknown>;
|
|
181
|
+
/** Search attributes */
|
|
182
|
+
searchAttributes?: Record<string, unknown>;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Handle to a running workflow
|
|
186
|
+
*/
|
|
187
|
+
interface WorkflowHandle<TOutput = unknown> {
|
|
188
|
+
/** The workflow ID */
|
|
189
|
+
workflowId: string;
|
|
190
|
+
/** The run ID */
|
|
191
|
+
runId: string;
|
|
192
|
+
/** Wait for the workflow result */
|
|
193
|
+
result(): Promise<TOutput>;
|
|
194
|
+
/** Query the workflow */
|
|
195
|
+
query<TResult = unknown>(queryName: string): Promise<TResult>;
|
|
196
|
+
/** Signal the workflow */
|
|
197
|
+
signal<TPayload = unknown>(signalName: string, payload: TPayload): Promise<void>;
|
|
198
|
+
/** Cancel the workflow */
|
|
199
|
+
cancel(): Promise<void>;
|
|
200
|
+
/** Terminate the workflow */
|
|
201
|
+
terminate(reason?: string): Promise<void>;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Temporal Functions client interface
|
|
205
|
+
*/
|
|
206
|
+
interface TFNClient {
|
|
207
|
+
/**
|
|
208
|
+
* Start a workflow and wait for the result
|
|
209
|
+
*/
|
|
210
|
+
invoke<TInput, TOutput>(workflow: WorkflowDef<TInput, TOutput>, input: TInput, options?: StartWorkflowOptions): Promise<TOutput>;
|
|
211
|
+
/**
|
|
212
|
+
* Start a workflow without waiting (fire and forget)
|
|
213
|
+
*/
|
|
214
|
+
start<TInput, TOutput>(workflow: WorkflowDef<TInput, TOutput>, input: TInput, options?: StartWorkflowOptions): Promise<WorkflowHandle<TOutput>>;
|
|
215
|
+
/**
|
|
216
|
+
* Get a handle to an existing workflow
|
|
217
|
+
*/
|
|
218
|
+
getHandle<TOutput = unknown>(workflowId: string): WorkflowHandle<TOutput>;
|
|
219
|
+
/**
|
|
220
|
+
* Signal an existing workflow
|
|
221
|
+
*/
|
|
222
|
+
signal<TPayload = unknown>(workflowId: string, signalName: string, payload: TPayload): Promise<void>;
|
|
223
|
+
/**
|
|
224
|
+
* Query an existing workflow
|
|
225
|
+
*/
|
|
226
|
+
query<TResult = unknown>(workflowId: string, queryName: string): Promise<TResult>;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Worker configuration options
|
|
230
|
+
*/
|
|
231
|
+
interface WorkerConfig {
|
|
232
|
+
/** Temporal connection settings */
|
|
233
|
+
temporal: TemporalConfig;
|
|
234
|
+
/** Task queue to poll */
|
|
235
|
+
taskQueue: string;
|
|
236
|
+
/** Maximum concurrent activity executions */
|
|
237
|
+
maxConcurrentActivities?: number;
|
|
238
|
+
/** Maximum concurrent workflow executions */
|
|
239
|
+
maxConcurrentWorkflows?: number;
|
|
240
|
+
/** Enable sticky execution (default: true) */
|
|
241
|
+
enableStickyExecution?: boolean;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Temporal Functions worker interface
|
|
245
|
+
*/
|
|
246
|
+
interface TFNWorker {
|
|
247
|
+
/**
|
|
248
|
+
* Register a function or workflow
|
|
249
|
+
*/
|
|
250
|
+
register(def: FunctionDef | WorkflowDef): void;
|
|
251
|
+
/**
|
|
252
|
+
* Register all exports from a module
|
|
253
|
+
*/
|
|
254
|
+
registerModule(module: Record<string, unknown>): void;
|
|
255
|
+
/**
|
|
256
|
+
* Start the worker (blocks until shutdown)
|
|
257
|
+
*/
|
|
258
|
+
start(): Promise<void>;
|
|
259
|
+
/**
|
|
260
|
+
* Gracefully shutdown the worker
|
|
261
|
+
*/
|
|
262
|
+
shutdown(): Promise<void>;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* HTTP trigger configuration
|
|
266
|
+
*/
|
|
267
|
+
interface HttpTriggerOptions {
|
|
268
|
+
/** Custom workflow ID generator */
|
|
269
|
+
workflowId?: (req: unknown) => string;
|
|
270
|
+
/** Return immediately without waiting for result */
|
|
271
|
+
async?: boolean;
|
|
272
|
+
/** Middleware functions */
|
|
273
|
+
middleware?: Array<(req: unknown, res: unknown, next: () => void) => void>;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Cron trigger configuration
|
|
277
|
+
*/
|
|
278
|
+
interface CronTriggerOptions {
|
|
279
|
+
/** Prevent overlapping executions */
|
|
280
|
+
overlap?: boolean;
|
|
281
|
+
/** Timezone for cron schedule */
|
|
282
|
+
timezone?: string;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Internal registry for functions and workflows
|
|
286
|
+
*/
|
|
287
|
+
interface Registry {
|
|
288
|
+
functions: Map<string, FunctionDef>;
|
|
289
|
+
workflows: Map<string, WorkflowDef>;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export type { CronTriggerOptions as C, FunctionOptions as F, HttpTriggerOptions as H, Registry as R, StartWorkflowOptions as S, TemporalConfig as T, WorkflowHandler as W, FunctionDef as a, WorkflowOptions as b, WorkflowDef as c, WorkflowContext as d, WorkflowInfo as e, RetryPolicy as f, ClientConfig as g, WorkerConfig as h, WorkflowHandle as i, TFNClient as j, TFNWorker as k };
|