@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.
@@ -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 };