@astami/temporal-functions 0.2.1 → 0.3.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.
@@ -1,5 +1,5 @@
1
- import { g as ClientConfig, j as TFNClient } from '../types-CmhOIEkF.mjs';
2
- export { S as StartWorkflowOptions, i as WorkflowHandle } from '../types-CmhOIEkF.mjs';
1
+ import { g as ClientConfig, j as TFNClient } from '../types-DY4y7IE5.mjs';
2
+ export { S as StartWorkflowOptions, i as WorkflowHandle } from '../types-DY4y7IE5.mjs';
3
3
 
4
4
  /**
5
5
  * Temporal Functions - Client Package
@@ -1,5 +1,5 @@
1
- import { g as ClientConfig, j as TFNClient } from '../types-CmhOIEkF.js';
2
- export { S as StartWorkflowOptions, i as WorkflowHandle } from '../types-CmhOIEkF.js';
1
+ import { g as ClientConfig, j as TFNClient } from '../types-DY4y7IE5.js';
2
+ export { S as StartWorkflowOptions, i as WorkflowHandle } from '../types-DY4y7IE5.js';
3
3
 
4
4
  /**
5
5
  * Temporal Functions - Client Package
@@ -43,10 +43,16 @@ var TemporalFunctionsClient = class {
43
43
  } : void 0
44
44
  } : void 0
45
45
  });
46
- this.client = new client.Client({
46
+ const clientOptions = {
47
47
  connection,
48
48
  namespace: this.config.temporal.namespace
49
- });
49
+ };
50
+ if (this.config.interceptors?.workflow) {
51
+ clientOptions.interceptors = {
52
+ workflow: this.config.interceptors.workflow
53
+ };
54
+ }
55
+ this.client = new client.Client(clientOptions);
50
56
  return this.client;
51
57
  })();
52
58
  return this.connectionPromise;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/client/index.ts"],"names":["Connection","Client"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Temporal Functions - Client Package\n *\n * Lightweight client for triggering workflows.\n * Import from 'temporal-functions/client'.\n */\n\nimport { Client, Connection } from '@temporalio/client';\nimport type {\n ClientConfig,\n WorkflowDef,\n StartWorkflowOptions,\n WorkflowHandle,\n TFNClient,\n} from '../types.js';\n\n// =============================================================================\n// Client Implementation\n// =============================================================================\n\nclass TemporalFunctionsClient implements TFNClient {\n private client: Client | null = null;\n private config: ClientConfig;\n private connectionPromise: Promise<Client> | null = null;\n\n constructor(config: ClientConfig) {\n this.config = {\n ...config,\n temporal: {\n namespace: 'default',\n ...config.temporal,\n },\n taskQueue: config.taskQueue || 'default',\n };\n }\n\n /**\n * Lazily connect to Temporal\n */\n private async getClient(): Promise<Client> {\n if (this.client) {\n return this.client;\n }\n\n if (this.connectionPromise) {\n return this.connectionPromise;\n }\n\n this.connectionPromise = (async () => {\n const connection = await Connection.connect({\n address: this.config.temporal.address,\n tls: this.config.temporal.tls\n ? {\n clientCertPair: this.config.temporal.tls.clientCertPath\n ? {\n crt: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientCertPath!)\n ),\n key: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientKeyPath!)\n ),\n }\n : undefined,\n }\n : undefined,\n });\n\n this.client = new Client({\n connection,\n namespace: this.config.temporal.namespace,\n });\n\n return this.client;\n })();\n\n return this.connectionPromise;\n }\n\n /**\n * Generate a workflow ID if not provided\n */\n private generateWorkflowId(workflowName: string): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `${workflowName}-${timestamp}-${random}`;\n }\n\n /**\n * Start a workflow and wait for the result\n */\n async invoke<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput,\n options: StartWorkflowOptions = {}\n ): Promise<TOutput> {\n const handle = await this.start(workflow, input, options);\n return handle.result();\n }\n\n /**\n * Start a workflow without waiting (fire and forget)\n */\n async start<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput,\n options: StartWorkflowOptions = {}\n ): Promise<WorkflowHandle<TOutput>> {\n const client = await this.getClient();\n\n const workflowId = options.workflowId || this.generateWorkflowId(workflow.name);\n const taskQueue = options.taskQueue || workflow.options.taskQueue || this.config.taskQueue || 'default';\n\n const handle = await client.workflow.start(workflow.name, {\n workflowId,\n taskQueue,\n args: [input],\n workflowExecutionTimeout: options.workflowExecutionTimeout,\n memo: options.memo,\n // searchAttributes requires specific types, omit for now if not properly typed\n });\n\n return this.wrapHandle<TOutput>(handle);\n }\n\n /**\n * Get a handle to an existing workflow\n */\n getHandle<TOutput = unknown>(workflowId: string): WorkflowHandle<TOutput> {\n // Create a lazy handle that connects when needed\n return {\n workflowId,\n runId: '', // Will be populated when we fetch\n result: async () => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.result() as Promise<TOutput>;\n },\n query: async <TResult = unknown>(queryName: string) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.query<TResult>(queryName);\n },\n signal: async <TPayload = unknown>(signalName: string, payload: TPayload) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.signal(signalName, payload);\n },\n cancel: async () => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.cancel();\n },\n terminate: async (reason?: string) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.terminate(reason);\n },\n };\n }\n\n /**\n * Signal an existing workflow\n */\n async signal<TPayload = unknown>(\n workflowId: string,\n signalName: string,\n payload: TPayload\n ): Promise<void> {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.signal(signalName, payload);\n }\n\n /**\n * Query an existing workflow\n */\n async query<TResult = unknown>(\n workflowId: string,\n queryName: string\n ): Promise<TResult> {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.query<TResult>(queryName);\n }\n\n /**\n * Wrap a Temporal workflow handle in our interface\n */\n private wrapHandle<TOutput>(\n handle: Awaited<ReturnType<Client['workflow']['start']>>\n ): WorkflowHandle<TOutput> {\n return {\n workflowId: handle.workflowId,\n runId: handle.firstExecutionRunId,\n result: () => handle.result() as Promise<TOutput>,\n query: <TResult = unknown>(queryName: string) =>\n handle.query<TResult>(queryName),\n signal: <TPayload = unknown>(signalName: string, payload: TPayload) =>\n handle.signal(signalName, payload),\n cancel: async () => {\n await handle.cancel();\n },\n terminate: async (reason?: string) => {\n await handle.terminate(reason);\n },\n };\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a Temporal Functions client\n *\n * @example\n * ```typescript\n * import { tfn } from 'temporal-functions/client';\n *\n * const client = tfn.client({\n * temporal: {\n * address: 'localhost:7233',\n * namespace: 'default',\n * },\n * taskQueue: 'my-queue',\n * });\n *\n * const result = await client.invoke(myWorkflow, { data: 'hello' });\n * ```\n */\nfunction createClient(config: ClientConfig): TFNClient {\n return new TemporalFunctionsClient(config);\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n client: createClient,\n};\n\nexport { createClient };\nexport type { ClientConfig, TFNClient, WorkflowHandle, StartWorkflowOptions };\nexport default tfn;\n"]}
1
+ {"version":3,"sources":["../../src/client/index.ts"],"names":["Connection","Client"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Temporal Functions - Client Package\n *\n * Lightweight client for triggering workflows.\n * Import from 'temporal-functions/client'.\n */\n\nimport { Client, Connection, type ClientOptions } from '@temporalio/client';\nimport type {\n ClientConfig,\n WorkflowDef,\n StartWorkflowOptions,\n WorkflowHandle,\n TFNClient,\n} from '../types.js';\n\n// =============================================================================\n// Client Implementation\n// =============================================================================\n\nclass TemporalFunctionsClient implements TFNClient {\n private client: Client | null = null;\n private config: ClientConfig;\n private connectionPromise: Promise<Client> | null = null;\n\n constructor(config: ClientConfig) {\n this.config = {\n ...config,\n temporal: {\n namespace: 'default',\n ...config.temporal,\n },\n taskQueue: config.taskQueue || 'default',\n };\n }\n\n /**\n * Lazily connect to Temporal\n */\n private async getClient(): Promise<Client> {\n if (this.client) {\n return this.client;\n }\n\n if (this.connectionPromise) {\n return this.connectionPromise;\n }\n\n this.connectionPromise = (async () => {\n const connection = await Connection.connect({\n address: this.config.temporal.address,\n tls: this.config.temporal.tls\n ? {\n clientCertPair: this.config.temporal.tls.clientCertPath\n ? {\n crt: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientCertPath!)\n ),\n key: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientKeyPath!)\n ),\n }\n : undefined,\n }\n : undefined,\n });\n\n // Build client options with optional interceptors\n const clientOptions: ClientOptions = {\n connection,\n namespace: this.config.temporal.namespace!,\n };\n\n // Add workflow interceptors if configured (e.g., for OpenTelemetry)\n if (this.config.interceptors?.workflow) {\n clientOptions.interceptors = {\n workflow: this.config.interceptors.workflow,\n };\n }\n\n this.client = new Client(clientOptions);\n\n return this.client;\n })();\n\n return this.connectionPromise;\n }\n\n /**\n * Generate a workflow ID if not provided\n */\n private generateWorkflowId(workflowName: string): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `${workflowName}-${timestamp}-${random}`;\n }\n\n /**\n * Start a workflow and wait for the result\n */\n async invoke<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput,\n options: StartWorkflowOptions = {}\n ): Promise<TOutput> {\n const handle = await this.start(workflow, input, options);\n return handle.result();\n }\n\n /**\n * Start a workflow without waiting (fire and forget)\n */\n async start<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput,\n options: StartWorkflowOptions = {}\n ): Promise<WorkflowHandle<TOutput>> {\n const client = await this.getClient();\n\n const workflowId = options.workflowId || this.generateWorkflowId(workflow.name);\n const taskQueue = options.taskQueue || workflow.options.taskQueue || this.config.taskQueue || 'default';\n\n const handle = await client.workflow.start(workflow.name, {\n workflowId,\n taskQueue,\n args: [input],\n workflowExecutionTimeout: options.workflowExecutionTimeout,\n memo: options.memo,\n // searchAttributes requires specific types, omit for now if not properly typed\n });\n\n return this.wrapHandle<TOutput>(handle);\n }\n\n /**\n * Get a handle to an existing workflow\n */\n getHandle<TOutput = unknown>(workflowId: string): WorkflowHandle<TOutput> {\n // Create a lazy handle that connects when needed\n return {\n workflowId,\n runId: '', // Will be populated when we fetch\n result: async () => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.result() as Promise<TOutput>;\n },\n query: async <TResult = unknown>(queryName: string) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.query<TResult>(queryName);\n },\n signal: async <TPayload = unknown>(signalName: string, payload: TPayload) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.signal(signalName, payload);\n },\n cancel: async () => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.cancel();\n },\n terminate: async (reason?: string) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.terminate(reason);\n },\n };\n }\n\n /**\n * Signal an existing workflow\n */\n async signal<TPayload = unknown>(\n workflowId: string,\n signalName: string,\n payload: TPayload\n ): Promise<void> {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.signal(signalName, payload);\n }\n\n /**\n * Query an existing workflow\n */\n async query<TResult = unknown>(\n workflowId: string,\n queryName: string\n ): Promise<TResult> {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.query<TResult>(queryName);\n }\n\n /**\n * Wrap a Temporal workflow handle in our interface\n */\n private wrapHandle<TOutput>(\n handle: Awaited<ReturnType<Client['workflow']['start']>>\n ): WorkflowHandle<TOutput> {\n return {\n workflowId: handle.workflowId,\n runId: handle.firstExecutionRunId,\n result: () => handle.result() as Promise<TOutput>,\n query: <TResult = unknown>(queryName: string) =>\n handle.query<TResult>(queryName),\n signal: <TPayload = unknown>(signalName: string, payload: TPayload) =>\n handle.signal(signalName, payload),\n cancel: async () => {\n await handle.cancel();\n },\n terminate: async (reason?: string) => {\n await handle.terminate(reason);\n },\n };\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a Temporal Functions client\n *\n * @example\n * ```typescript\n * import { tfn } from 'temporal-functions/client';\n *\n * const client = tfn.client({\n * temporal: {\n * address: 'localhost:7233',\n * namespace: 'default',\n * },\n * taskQueue: 'my-queue',\n * });\n *\n * const result = await client.invoke(myWorkflow, { data: 'hello' });\n * ```\n */\nfunction createClient(config: ClientConfig): TFNClient {\n return new TemporalFunctionsClient(config);\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n client: createClient,\n};\n\nexport { createClient };\nexport type { ClientConfig, TFNClient, WorkflowHandle, StartWorkflowOptions };\nexport default tfn;\n"]}
@@ -39,10 +39,16 @@ var TemporalFunctionsClient = class {
39
39
  } : void 0
40
40
  } : void 0
41
41
  });
42
- this.client = new Client({
42
+ const clientOptions = {
43
43
  connection,
44
44
  namespace: this.config.temporal.namespace
45
- });
45
+ };
46
+ if (this.config.interceptors?.workflow) {
47
+ clientOptions.interceptors = {
48
+ workflow: this.config.interceptors.workflow
49
+ };
50
+ }
51
+ this.client = new Client(clientOptions);
46
52
  return this.client;
47
53
  })();
48
54
  return this.connectionPromise;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/client/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Temporal Functions - Client Package\n *\n * Lightweight client for triggering workflows.\n * Import from 'temporal-functions/client'.\n */\n\nimport { Client, Connection } from '@temporalio/client';\nimport type {\n ClientConfig,\n WorkflowDef,\n StartWorkflowOptions,\n WorkflowHandle,\n TFNClient,\n} from '../types.js';\n\n// =============================================================================\n// Client Implementation\n// =============================================================================\n\nclass TemporalFunctionsClient implements TFNClient {\n private client: Client | null = null;\n private config: ClientConfig;\n private connectionPromise: Promise<Client> | null = null;\n\n constructor(config: ClientConfig) {\n this.config = {\n ...config,\n temporal: {\n namespace: 'default',\n ...config.temporal,\n },\n taskQueue: config.taskQueue || 'default',\n };\n }\n\n /**\n * Lazily connect to Temporal\n */\n private async getClient(): Promise<Client> {\n if (this.client) {\n return this.client;\n }\n\n if (this.connectionPromise) {\n return this.connectionPromise;\n }\n\n this.connectionPromise = (async () => {\n const connection = await Connection.connect({\n address: this.config.temporal.address,\n tls: this.config.temporal.tls\n ? {\n clientCertPair: this.config.temporal.tls.clientCertPath\n ? {\n crt: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientCertPath!)\n ),\n key: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientKeyPath!)\n ),\n }\n : undefined,\n }\n : undefined,\n });\n\n this.client = new Client({\n connection,\n namespace: this.config.temporal.namespace,\n });\n\n return this.client;\n })();\n\n return this.connectionPromise;\n }\n\n /**\n * Generate a workflow ID if not provided\n */\n private generateWorkflowId(workflowName: string): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `${workflowName}-${timestamp}-${random}`;\n }\n\n /**\n * Start a workflow and wait for the result\n */\n async invoke<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput,\n options: StartWorkflowOptions = {}\n ): Promise<TOutput> {\n const handle = await this.start(workflow, input, options);\n return handle.result();\n }\n\n /**\n * Start a workflow without waiting (fire and forget)\n */\n async start<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput,\n options: StartWorkflowOptions = {}\n ): Promise<WorkflowHandle<TOutput>> {\n const client = await this.getClient();\n\n const workflowId = options.workflowId || this.generateWorkflowId(workflow.name);\n const taskQueue = options.taskQueue || workflow.options.taskQueue || this.config.taskQueue || 'default';\n\n const handle = await client.workflow.start(workflow.name, {\n workflowId,\n taskQueue,\n args: [input],\n workflowExecutionTimeout: options.workflowExecutionTimeout,\n memo: options.memo,\n // searchAttributes requires specific types, omit for now if not properly typed\n });\n\n return this.wrapHandle<TOutput>(handle);\n }\n\n /**\n * Get a handle to an existing workflow\n */\n getHandle<TOutput = unknown>(workflowId: string): WorkflowHandle<TOutput> {\n // Create a lazy handle that connects when needed\n return {\n workflowId,\n runId: '', // Will be populated when we fetch\n result: async () => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.result() as Promise<TOutput>;\n },\n query: async <TResult = unknown>(queryName: string) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.query<TResult>(queryName);\n },\n signal: async <TPayload = unknown>(signalName: string, payload: TPayload) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.signal(signalName, payload);\n },\n cancel: async () => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.cancel();\n },\n terminate: async (reason?: string) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.terminate(reason);\n },\n };\n }\n\n /**\n * Signal an existing workflow\n */\n async signal<TPayload = unknown>(\n workflowId: string,\n signalName: string,\n payload: TPayload\n ): Promise<void> {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.signal(signalName, payload);\n }\n\n /**\n * Query an existing workflow\n */\n async query<TResult = unknown>(\n workflowId: string,\n queryName: string\n ): Promise<TResult> {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.query<TResult>(queryName);\n }\n\n /**\n * Wrap a Temporal workflow handle in our interface\n */\n private wrapHandle<TOutput>(\n handle: Awaited<ReturnType<Client['workflow']['start']>>\n ): WorkflowHandle<TOutput> {\n return {\n workflowId: handle.workflowId,\n runId: handle.firstExecutionRunId,\n result: () => handle.result() as Promise<TOutput>,\n query: <TResult = unknown>(queryName: string) =>\n handle.query<TResult>(queryName),\n signal: <TPayload = unknown>(signalName: string, payload: TPayload) =>\n handle.signal(signalName, payload),\n cancel: async () => {\n await handle.cancel();\n },\n terminate: async (reason?: string) => {\n await handle.terminate(reason);\n },\n };\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a Temporal Functions client\n *\n * @example\n * ```typescript\n * import { tfn } from 'temporal-functions/client';\n *\n * const client = tfn.client({\n * temporal: {\n * address: 'localhost:7233',\n * namespace: 'default',\n * },\n * taskQueue: 'my-queue',\n * });\n *\n * const result = await client.invoke(myWorkflow, { data: 'hello' });\n * ```\n */\nfunction createClient(config: ClientConfig): TFNClient {\n return new TemporalFunctionsClient(config);\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n client: createClient,\n};\n\nexport { createClient };\nexport type { ClientConfig, TFNClient, WorkflowHandle, StartWorkflowOptions };\nexport default tfn;\n"]}
1
+ {"version":3,"sources":["../../src/client/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Temporal Functions - Client Package\n *\n * Lightweight client for triggering workflows.\n * Import from 'temporal-functions/client'.\n */\n\nimport { Client, Connection, type ClientOptions } from '@temporalio/client';\nimport type {\n ClientConfig,\n WorkflowDef,\n StartWorkflowOptions,\n WorkflowHandle,\n TFNClient,\n} from '../types.js';\n\n// =============================================================================\n// Client Implementation\n// =============================================================================\n\nclass TemporalFunctionsClient implements TFNClient {\n private client: Client | null = null;\n private config: ClientConfig;\n private connectionPromise: Promise<Client> | null = null;\n\n constructor(config: ClientConfig) {\n this.config = {\n ...config,\n temporal: {\n namespace: 'default',\n ...config.temporal,\n },\n taskQueue: config.taskQueue || 'default',\n };\n }\n\n /**\n * Lazily connect to Temporal\n */\n private async getClient(): Promise<Client> {\n if (this.client) {\n return this.client;\n }\n\n if (this.connectionPromise) {\n return this.connectionPromise;\n }\n\n this.connectionPromise = (async () => {\n const connection = await Connection.connect({\n address: this.config.temporal.address,\n tls: this.config.temporal.tls\n ? {\n clientCertPair: this.config.temporal.tls.clientCertPath\n ? {\n crt: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientCertPath!)\n ),\n key: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientKeyPath!)\n ),\n }\n : undefined,\n }\n : undefined,\n });\n\n // Build client options with optional interceptors\n const clientOptions: ClientOptions = {\n connection,\n namespace: this.config.temporal.namespace!,\n };\n\n // Add workflow interceptors if configured (e.g., for OpenTelemetry)\n if (this.config.interceptors?.workflow) {\n clientOptions.interceptors = {\n workflow: this.config.interceptors.workflow,\n };\n }\n\n this.client = new Client(clientOptions);\n\n return this.client;\n })();\n\n return this.connectionPromise;\n }\n\n /**\n * Generate a workflow ID if not provided\n */\n private generateWorkflowId(workflowName: string): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `${workflowName}-${timestamp}-${random}`;\n }\n\n /**\n * Start a workflow and wait for the result\n */\n async invoke<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput,\n options: StartWorkflowOptions = {}\n ): Promise<TOutput> {\n const handle = await this.start(workflow, input, options);\n return handle.result();\n }\n\n /**\n * Start a workflow without waiting (fire and forget)\n */\n async start<TInput, TOutput>(\n workflow: WorkflowDef<TInput, TOutput>,\n input: TInput,\n options: StartWorkflowOptions = {}\n ): Promise<WorkflowHandle<TOutput>> {\n const client = await this.getClient();\n\n const workflowId = options.workflowId || this.generateWorkflowId(workflow.name);\n const taskQueue = options.taskQueue || workflow.options.taskQueue || this.config.taskQueue || 'default';\n\n const handle = await client.workflow.start(workflow.name, {\n workflowId,\n taskQueue,\n args: [input],\n workflowExecutionTimeout: options.workflowExecutionTimeout,\n memo: options.memo,\n // searchAttributes requires specific types, omit for now if not properly typed\n });\n\n return this.wrapHandle<TOutput>(handle);\n }\n\n /**\n * Get a handle to an existing workflow\n */\n getHandle<TOutput = unknown>(workflowId: string): WorkflowHandle<TOutput> {\n // Create a lazy handle that connects when needed\n return {\n workflowId,\n runId: '', // Will be populated when we fetch\n result: async () => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.result() as Promise<TOutput>;\n },\n query: async <TResult = unknown>(queryName: string) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.query<TResult>(queryName);\n },\n signal: async <TPayload = unknown>(signalName: string, payload: TPayload) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.signal(signalName, payload);\n },\n cancel: async () => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.cancel();\n },\n terminate: async (reason?: string) => {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.terminate(reason);\n },\n };\n }\n\n /**\n * Signal an existing workflow\n */\n async signal<TPayload = unknown>(\n workflowId: string,\n signalName: string,\n payload: TPayload\n ): Promise<void> {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n await handle.signal(signalName, payload);\n }\n\n /**\n * Query an existing workflow\n */\n async query<TResult = unknown>(\n workflowId: string,\n queryName: string\n ): Promise<TResult> {\n const client = await this.getClient();\n const handle = client.workflow.getHandle(workflowId);\n return handle.query<TResult>(queryName);\n }\n\n /**\n * Wrap a Temporal workflow handle in our interface\n */\n private wrapHandle<TOutput>(\n handle: Awaited<ReturnType<Client['workflow']['start']>>\n ): WorkflowHandle<TOutput> {\n return {\n workflowId: handle.workflowId,\n runId: handle.firstExecutionRunId,\n result: () => handle.result() as Promise<TOutput>,\n query: <TResult = unknown>(queryName: string) =>\n handle.query<TResult>(queryName),\n signal: <TPayload = unknown>(signalName: string, payload: TPayload) =>\n handle.signal(signalName, payload),\n cancel: async () => {\n await handle.cancel();\n },\n terminate: async (reason?: string) => {\n await handle.terminate(reason);\n },\n };\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a Temporal Functions client\n *\n * @example\n * ```typescript\n * import { tfn } from 'temporal-functions/client';\n *\n * const client = tfn.client({\n * temporal: {\n * address: 'localhost:7233',\n * namespace: 'default',\n * },\n * taskQueue: 'my-queue',\n * });\n *\n * const result = await client.invoke(myWorkflow, { data: 'hello' });\n * ```\n */\nfunction createClient(config: ClientConfig): TFNClient {\n return new TemporalFunctionsClient(config);\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n client: createClient,\n};\n\nexport { createClient };\nexport type { ClientConfig, TFNClient, WorkflowHandle, StartWorkflowOptions };\nexport default tfn;\n"]}
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FunctionOptions, a as FunctionDef, W as WorkflowHandler, b as WorkflowOptions, c as WorkflowDef, H as HttpTriggerOptions, C as CronTriggerOptions, R as Registry } from './types-CmhOIEkF.mjs';
2
- export { g as ClientConfig, f as RetryPolicy, S as StartWorkflowOptions, j as TFNClient, k as TFNWorker, T as TemporalConfig, h as WorkerConfig, d as WorkflowContext, i as WorkflowHandle, e as WorkflowInfo } from './types-CmhOIEkF.mjs';
1
+ import { F as FunctionOptions, a as FunctionDef, W as WorkflowHandler, b as WorkflowOptions, c as WorkflowDef, H as HttpTriggerOptions, C as CronTriggerOptions, R as Registry } from './types-DY4y7IE5.mjs';
2
+ export { g as ClientConfig, f as RetryPolicy, S as StartWorkflowOptions, j as TFNClient, k as TFNWorker, T as TemporalConfig, h as WorkerConfig, d as WorkflowContext, i as WorkflowHandle, e as WorkflowInfo } from './types-DY4y7IE5.mjs';
3
3
 
4
4
  /**
5
5
  * Temporal Functions - Main Entry Point
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FunctionOptions, a as FunctionDef, W as WorkflowHandler, b as WorkflowOptions, c as WorkflowDef, H as HttpTriggerOptions, C as CronTriggerOptions, R as Registry } from './types-CmhOIEkF.js';
2
- export { g as ClientConfig, f as RetryPolicy, S as StartWorkflowOptions, j as TFNClient, k as TFNWorker, T as TemporalConfig, h as WorkerConfig, d as WorkflowContext, i as WorkflowHandle, e as WorkflowInfo } from './types-CmhOIEkF.js';
1
+ import { F as FunctionOptions, a as FunctionDef, W as WorkflowHandler, b as WorkflowOptions, c as WorkflowDef, H as HttpTriggerOptions, C as CronTriggerOptions, R as Registry } from './types-DY4y7IE5.js';
2
+ export { g as ClientConfig, f as RetryPolicy, S as StartWorkflowOptions, j as TFNClient, k as TFNWorker, T as TemporalConfig, h as WorkerConfig, d as WorkflowContext, i as WorkflowHandle, e as WorkflowInfo } from './types-DY4y7IE5.js';
3
3
 
4
4
  /**
5
5
  * Temporal Functions - Main Entry Point
@@ -0,0 +1,47 @@
1
+ import { l as WorkerInterceptors } from '../types-DY4y7IE5.mjs';
2
+ export { OpenTelemetryActivityInboundInterceptor } from '@temporalio/interceptors-opentelemetry';
3
+
4
+ /**
5
+ * Temporal Functions - Observability Package
6
+ *
7
+ * OpenTelemetry integration for Temporal workers with trace context propagation.
8
+ * Import from '@astami/temporal-functions/observability'.
9
+ */
10
+
11
+ interface WorkerInterceptorsConfig {
12
+ /** Service/processor name for logging */
13
+ serviceName: string;
14
+ /** Optional custom logger (defaults to console) */
15
+ logger?: {
16
+ info: (obj: Record<string, unknown>, msg: string) => void;
17
+ error: (obj: Record<string, unknown>, msg: string) => void;
18
+ };
19
+ }
20
+ /**
21
+ * Creates worker interceptors configuration with OpenTelemetry trace propagation
22
+ *
23
+ * This returns a WorkerInterceptors object that can be passed directly to
24
+ * the worker configuration. It includes:
25
+ * - Activity inbound interceptors for tracing and logging
26
+ * - Workflow module interceptors for end-to-end trace propagation
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import { createWorker } from '@astami/temporal-functions/worker';
31
+ * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';
32
+ * import * as activities from './activities';
33
+ *
34
+ * const worker = createWorker({
35
+ * temporal: { address: 'localhost:7233', namespace: 'loop' },
36
+ * taskQueue: 'stripe-payments',
37
+ * workflowsPath: './dist/workflows/index.js',
38
+ * activities,
39
+ * interceptors: createWorkerInterceptors({ serviceName: 'stripe' }),
40
+ * });
41
+ *
42
+ * await worker.start();
43
+ * ```
44
+ */
45
+ declare function createWorkerInterceptors(config: WorkerInterceptorsConfig): WorkerInterceptors;
46
+
47
+ export { type WorkerInterceptorsConfig, createWorkerInterceptors };
@@ -0,0 +1,47 @@
1
+ import { l as WorkerInterceptors } from '../types-DY4y7IE5.js';
2
+ export { OpenTelemetryActivityInboundInterceptor } from '@temporalio/interceptors-opentelemetry';
3
+
4
+ /**
5
+ * Temporal Functions - Observability Package
6
+ *
7
+ * OpenTelemetry integration for Temporal workers with trace context propagation.
8
+ * Import from '@astami/temporal-functions/observability'.
9
+ */
10
+
11
+ interface WorkerInterceptorsConfig {
12
+ /** Service/processor name for logging */
13
+ serviceName: string;
14
+ /** Optional custom logger (defaults to console) */
15
+ logger?: {
16
+ info: (obj: Record<string, unknown>, msg: string) => void;
17
+ error: (obj: Record<string, unknown>, msg: string) => void;
18
+ };
19
+ }
20
+ /**
21
+ * Creates worker interceptors configuration with OpenTelemetry trace propagation
22
+ *
23
+ * This returns a WorkerInterceptors object that can be passed directly to
24
+ * the worker configuration. It includes:
25
+ * - Activity inbound interceptors for tracing and logging
26
+ * - Workflow module interceptors for end-to-end trace propagation
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import { createWorker } from '@astami/temporal-functions/worker';
31
+ * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';
32
+ * import * as activities from './activities';
33
+ *
34
+ * const worker = createWorker({
35
+ * temporal: { address: 'localhost:7233', namespace: 'loop' },
36
+ * taskQueue: 'stripe-payments',
37
+ * workflowsPath: './dist/workflows/index.js',
38
+ * activities,
39
+ * interceptors: createWorkerInterceptors({ serviceName: 'stripe' }),
40
+ * });
41
+ *
42
+ * await worker.start();
43
+ * ```
44
+ */
45
+ declare function createWorkerInterceptors(config: WorkerInterceptorsConfig): WorkerInterceptors;
46
+
47
+ export { type WorkerInterceptorsConfig, createWorkerInterceptors };
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ var api = require('@opentelemetry/api');
4
+ var interceptorsOpentelemetry = require('@temporalio/interceptors-opentelemetry');
5
+
6
+ // src/observability/index.ts
7
+ var TracingActivityInterceptor = class {
8
+ otelInterceptor;
9
+ config;
10
+ ctx;
11
+ constructor(ctx, config) {
12
+ this.ctx = ctx;
13
+ this.config = config;
14
+ this.otelInterceptor = new interceptorsOpentelemetry.OpenTelemetryActivityInboundInterceptor(ctx);
15
+ }
16
+ async execute(input, next) {
17
+ const activityType = this.ctx.info.activityType;
18
+ const workflowId = this.ctx.info.workflowExecution.workflowId;
19
+ const startTime = Date.now();
20
+ const config = this.config;
21
+ const logger = config.logger ?? console;
22
+ const loggingNext = async (nextInput) => {
23
+ const currentSpan = api.trace.getActiveSpan();
24
+ const spanContext = currentSpan?.spanContext();
25
+ logger.info(
26
+ {
27
+ activity: activityType,
28
+ workflowId,
29
+ processor: config.serviceName,
30
+ trace_id: spanContext?.traceId,
31
+ span_id: spanContext?.spanId
32
+ },
33
+ "Activity started"
34
+ );
35
+ try {
36
+ const result = await next(nextInput);
37
+ logger.info(
38
+ {
39
+ activity: activityType,
40
+ workflowId,
41
+ duration: Date.now() - startTime,
42
+ trace_id: spanContext?.traceId,
43
+ span_id: spanContext?.spanId
44
+ },
45
+ "Activity completed"
46
+ );
47
+ return result;
48
+ } catch (error) {
49
+ logger.error(
50
+ {
51
+ activity: activityType,
52
+ workflowId,
53
+ error,
54
+ duration: Date.now() - startTime,
55
+ trace_id: spanContext?.traceId,
56
+ span_id: spanContext?.spanId
57
+ },
58
+ "Activity failed"
59
+ );
60
+ throw error;
61
+ }
62
+ };
63
+ return this.otelInterceptor.execute(input, loggingNext);
64
+ }
65
+ };
66
+ function createWorkerInterceptors(config) {
67
+ return {
68
+ activityInbound: [
69
+ (ctx) => new TracingActivityInterceptor(ctx, config)
70
+ ],
71
+ // Include OTel workflow interceptors for end-to-end trace propagation
72
+ workflowModules: ["@temporalio/interceptors-opentelemetry/lib/workflow"]
73
+ };
74
+ }
75
+
76
+ Object.defineProperty(exports, "OpenTelemetryActivityInboundInterceptor", {
77
+ enumerable: true,
78
+ get: function () { return interceptorsOpentelemetry.OpenTelemetryActivityInboundInterceptor; }
79
+ });
80
+ exports.createWorkerInterceptors = createWorkerInterceptors;
81
+ //# sourceMappingURL=index.js.map
82
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/observability/index.ts"],"names":["OpenTelemetryActivityInboundInterceptor","trace"],"mappings":";;;;;;AA2CA,IAAM,6BAAN,MAA4E;AAAA,EACzD,eAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAA;AAAA,EAEjB,WAAA,CAAY,KAAsB,MAAA,EAAkC;AAClE,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAEd,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAIA,iEAAA,CAAwC,GAAG,CAAA;AAAA,EACxE;AAAA,EAEA,MAAM,OAAA,CACJ,KAAA,EACA,IAAA,EACkB;AAClB,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,YAAA;AACnC,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,iBAAA,CAAkB,UAAA;AACnD,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,IAAA,MAAM,MAAA,GAAS,OAAO,MAAA,IAAU,OAAA;AAGhC,IAAA,MAAM,WAAA,GAAgE,OACpE,SAAA,KACG;AAEH,MAAA,MAAM,WAAA,GAAcC,UAAM,aAAA,EAAc;AACxC,MAAA,MAAM,WAAA,GAAc,aAAa,WAAA,EAAY;AAE7C,MAAA,MAAA,CAAO,IAAA;AAAA,QACL;AAAA,UACE,QAAA,EAAU,YAAA;AAAA,UACV,UAAA;AAAA,UACA,WAAW,MAAA,CAAO,WAAA;AAAA,UAClB,UAAU,WAAA,EAAa,OAAA;AAAA,UACvB,SAAS,WAAA,EAAa;AAAA,SACxB;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAS,CAAA;AAEnC,QAAA,MAAA,CAAO,IAAA;AAAA,UACL;AAAA,YACE,QAAA,EAAU,YAAA;AAAA,YACV,UAAA;AAAA,YACA,QAAA,EAAU,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,YACvB,UAAU,WAAA,EAAa,OAAA;AAAA,YACvB,SAAS,WAAA,EAAa;AAAA,WACxB;AAAA,UACA;AAAA,SACF;AAEA,QAAA,OAAO,MAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,MAAA,CAAO,KAAA;AAAA,UACL;AAAA,YACE,QAAA,EAAU,YAAA;AAAA,YACV,UAAA;AAAA,YACA,KAAA;AAAA,YACA,QAAA,EAAU,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,YACvB,UAAU,WAAA,EAAa,OAAA;AAAA,YACvB,SAAS,WAAA,EAAa;AAAA,WACxB;AAAA,UACA;AAAA,SACF;AAEA,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF,CAAA;AAIA,IAAA,OAAO,IAAA,CAAK,eAAA,CAAgB,OAAA,CAAQ,KAAA,EAAO,WAAW,CAAA;AAAA,EACxD;AACF,CAAA;AA+BO,SAAS,yBAAyB,MAAA,EAAsD;AAC7F,EAAA,OAAO;AAAA,IACL,eAAA,EAAiB;AAAA,MACf,CAAC,GAAA,KAAyB,IAAI,0BAAA,CAA2B,KAAK,MAAM;AAAA,KACtE;AAAA;AAAA,IAEA,eAAA,EAAiB,CAAC,qDAAqD;AAAA,GACzE;AACF","file":"index.js","sourcesContent":["/**\n * Temporal Functions - Observability Package\n *\n * OpenTelemetry integration for Temporal workers with trace context propagation.\n * Import from '@astami/temporal-functions/observability'.\n */\n\nimport { trace } from '@opentelemetry/api';\nimport {\n OpenTelemetryActivityInboundInterceptor,\n} from '@temporalio/interceptors-opentelemetry';\nimport type { Context as ActivityContext } from '@temporalio/activity';\nimport type {\n ActivityInboundCallsInterceptor,\n ActivityExecuteInput,\n Next,\n} from '@temporalio/worker';\nimport type { WorkerInterceptors } from '../types.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface WorkerInterceptorsConfig {\n /** Service/processor name for logging */\n serviceName: string;\n /** Optional custom logger (defaults to console) */\n logger?: {\n info: (obj: Record<string, unknown>, msg: string) => void;\n error: (obj: Record<string, unknown>, msg: string) => void;\n };\n}\n\n// =============================================================================\n// Tracing Activity Interceptor\n// =============================================================================\n\n/**\n * Creates an activity interceptor that combines OpenTelemetry tracing with structured logging\n *\n * Uses Temporal's OpenTelemetryActivityInboundInterceptor for trace propagation,\n * and wraps it with additional structured logging that includes trace IDs.\n */\nclass TracingActivityInterceptor implements ActivityInboundCallsInterceptor {\n private readonly otelInterceptor: OpenTelemetryActivityInboundInterceptor;\n private readonly config: WorkerInterceptorsConfig;\n private readonly ctx: ActivityContext;\n\n constructor(ctx: ActivityContext, config: WorkerInterceptorsConfig) {\n this.ctx = ctx;\n this.config = config;\n // Use Temporal's built-in OTel interceptor for proper trace context propagation\n this.otelInterceptor = new OpenTelemetryActivityInboundInterceptor(ctx);\n }\n\n async execute(\n input: ActivityExecuteInput,\n next: Next<ActivityInboundCallsInterceptor, 'execute'>\n ): Promise<unknown> {\n const activityType = this.ctx.info.activityType;\n const workflowId = this.ctx.info.workflowExecution.workflowId;\n const startTime = Date.now();\n const config = this.config;\n const logger = config.logger ?? console;\n\n // Wrap the next function to add logging INSIDE the OTel span context\n const loggingNext: Next<ActivityInboundCallsInterceptor, 'execute'> = async (\n nextInput: ActivityExecuteInput\n ) => {\n // Now we're inside the OTel interceptor's span context\n const currentSpan = trace.getActiveSpan();\n const spanContext = currentSpan?.spanContext();\n\n logger.info(\n {\n activity: activityType,\n workflowId,\n processor: config.serviceName,\n trace_id: spanContext?.traceId,\n span_id: spanContext?.spanId,\n },\n 'Activity started'\n );\n\n try {\n const result = await next(nextInput);\n\n logger.info(\n {\n activity: activityType,\n workflowId,\n duration: Date.now() - startTime,\n trace_id: spanContext?.traceId,\n span_id: spanContext?.spanId,\n },\n 'Activity completed'\n );\n\n return result;\n } catch (error) {\n logger.error(\n {\n activity: activityType,\n workflowId,\n error,\n duration: Date.now() - startTime,\n trace_id: spanContext?.traceId,\n span_id: spanContext?.spanId,\n },\n 'Activity failed'\n );\n\n throw error;\n }\n };\n\n // Delegate to Temporal's OTel interceptor which sets up the span context,\n // then our loggingNext will execute with the proper trace context\n return this.otelInterceptor.execute(input, loggingNext);\n }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Creates worker interceptors configuration with OpenTelemetry trace propagation\n *\n * This returns a WorkerInterceptors object that can be passed directly to\n * the worker configuration. It includes:\n * - Activity inbound interceptors for tracing and logging\n * - Workflow module interceptors for end-to-end trace propagation\n *\n * @example\n * ```typescript\n * import { createWorker } from '@astami/temporal-functions/worker';\n * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';\n * import * as activities from './activities';\n *\n * const worker = createWorker({\n * temporal: { address: 'localhost:7233', namespace: 'loop' },\n * taskQueue: 'stripe-payments',\n * workflowsPath: './dist/workflows/index.js',\n * activities,\n * interceptors: createWorkerInterceptors({ serviceName: 'stripe' }),\n * });\n *\n * await worker.start();\n * ```\n */\nexport function createWorkerInterceptors(config: WorkerInterceptorsConfig): WorkerInterceptors {\n return {\n activityInbound: [\n (ctx: ActivityContext) => new TracingActivityInterceptor(ctx, config),\n ],\n // Include OTel workflow interceptors for end-to-end trace propagation\n workflowModules: ['@temporalio/interceptors-opentelemetry/lib/workflow'],\n };\n}\n\n// =============================================================================\n// Re-exports from Temporal OTel package\n// =============================================================================\n\nexport {\n OpenTelemetryActivityInboundInterceptor,\n} from '@temporalio/interceptors-opentelemetry';\n"]}
@@ -0,0 +1,77 @@
1
+ import { trace } from '@opentelemetry/api';
2
+ import { OpenTelemetryActivityInboundInterceptor } from '@temporalio/interceptors-opentelemetry';
3
+ export { OpenTelemetryActivityInboundInterceptor } from '@temporalio/interceptors-opentelemetry';
4
+
5
+ // src/observability/index.ts
6
+ var TracingActivityInterceptor = class {
7
+ otelInterceptor;
8
+ config;
9
+ ctx;
10
+ constructor(ctx, config) {
11
+ this.ctx = ctx;
12
+ this.config = config;
13
+ this.otelInterceptor = new OpenTelemetryActivityInboundInterceptor(ctx);
14
+ }
15
+ async execute(input, next) {
16
+ const activityType = this.ctx.info.activityType;
17
+ const workflowId = this.ctx.info.workflowExecution.workflowId;
18
+ const startTime = Date.now();
19
+ const config = this.config;
20
+ const logger = config.logger ?? console;
21
+ const loggingNext = async (nextInput) => {
22
+ const currentSpan = trace.getActiveSpan();
23
+ const spanContext = currentSpan?.spanContext();
24
+ logger.info(
25
+ {
26
+ activity: activityType,
27
+ workflowId,
28
+ processor: config.serviceName,
29
+ trace_id: spanContext?.traceId,
30
+ span_id: spanContext?.spanId
31
+ },
32
+ "Activity started"
33
+ );
34
+ try {
35
+ const result = await next(nextInput);
36
+ logger.info(
37
+ {
38
+ activity: activityType,
39
+ workflowId,
40
+ duration: Date.now() - startTime,
41
+ trace_id: spanContext?.traceId,
42
+ span_id: spanContext?.spanId
43
+ },
44
+ "Activity completed"
45
+ );
46
+ return result;
47
+ } catch (error) {
48
+ logger.error(
49
+ {
50
+ activity: activityType,
51
+ workflowId,
52
+ error,
53
+ duration: Date.now() - startTime,
54
+ trace_id: spanContext?.traceId,
55
+ span_id: spanContext?.spanId
56
+ },
57
+ "Activity failed"
58
+ );
59
+ throw error;
60
+ }
61
+ };
62
+ return this.otelInterceptor.execute(input, loggingNext);
63
+ }
64
+ };
65
+ function createWorkerInterceptors(config) {
66
+ return {
67
+ activityInbound: [
68
+ (ctx) => new TracingActivityInterceptor(ctx, config)
69
+ ],
70
+ // Include OTel workflow interceptors for end-to-end trace propagation
71
+ workflowModules: ["@temporalio/interceptors-opentelemetry/lib/workflow"]
72
+ };
73
+ }
74
+
75
+ export { createWorkerInterceptors };
76
+ //# sourceMappingURL=index.mjs.map
77
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/observability/index.ts"],"names":[],"mappings":";;;;;AA2CA,IAAM,6BAAN,MAA4E;AAAA,EACzD,eAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAA;AAAA,EAEjB,WAAA,CAAY,KAAsB,MAAA,EAAkC;AAClE,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAEd,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAI,uCAAA,CAAwC,GAAG,CAAA;AAAA,EACxE;AAAA,EAEA,MAAM,OAAA,CACJ,KAAA,EACA,IAAA,EACkB;AAClB,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,YAAA;AACnC,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,iBAAA,CAAkB,UAAA;AACnD,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,IAAA,MAAM,MAAA,GAAS,OAAO,MAAA,IAAU,OAAA;AAGhC,IAAA,MAAM,WAAA,GAAgE,OACpE,SAAA,KACG;AAEH,MAAA,MAAM,WAAA,GAAc,MAAM,aAAA,EAAc;AACxC,MAAA,MAAM,WAAA,GAAc,aAAa,WAAA,EAAY;AAE7C,MAAA,MAAA,CAAO,IAAA;AAAA,QACL;AAAA,UACE,QAAA,EAAU,YAAA;AAAA,UACV,UAAA;AAAA,UACA,WAAW,MAAA,CAAO,WAAA;AAAA,UAClB,UAAU,WAAA,EAAa,OAAA;AAAA,UACvB,SAAS,WAAA,EAAa;AAAA,SACxB;AAAA,QACA;AAAA,OACF;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAS,CAAA;AAEnC,QAAA,MAAA,CAAO,IAAA;AAAA,UACL;AAAA,YACE,QAAA,EAAU,YAAA;AAAA,YACV,UAAA;AAAA,YACA,QAAA,EAAU,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,YACvB,UAAU,WAAA,EAAa,OAAA;AAAA,YACvB,SAAS,WAAA,EAAa;AAAA,WACxB;AAAA,UACA;AAAA,SACF;AAEA,QAAA,OAAO,MAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,MAAA,CAAO,KAAA;AAAA,UACL;AAAA,YACE,QAAA,EAAU,YAAA;AAAA,YACV,UAAA;AAAA,YACA,KAAA;AAAA,YACA,QAAA,EAAU,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAAA,YACvB,UAAU,WAAA,EAAa,OAAA;AAAA,YACvB,SAAS,WAAA,EAAa;AAAA,WACxB;AAAA,UACA;AAAA,SACF;AAEA,QAAA,MAAM,KAAA;AAAA,MACR;AAAA,IACF,CAAA;AAIA,IAAA,OAAO,IAAA,CAAK,eAAA,CAAgB,OAAA,CAAQ,KAAA,EAAO,WAAW,CAAA;AAAA,EACxD;AACF,CAAA;AA+BO,SAAS,yBAAyB,MAAA,EAAsD;AAC7F,EAAA,OAAO;AAAA,IACL,eAAA,EAAiB;AAAA,MACf,CAAC,GAAA,KAAyB,IAAI,0BAAA,CAA2B,KAAK,MAAM;AAAA,KACtE;AAAA;AAAA,IAEA,eAAA,EAAiB,CAAC,qDAAqD;AAAA,GACzE;AACF","file":"index.mjs","sourcesContent":["/**\n * Temporal Functions - Observability Package\n *\n * OpenTelemetry integration for Temporal workers with trace context propagation.\n * Import from '@astami/temporal-functions/observability'.\n */\n\nimport { trace } from '@opentelemetry/api';\nimport {\n OpenTelemetryActivityInboundInterceptor,\n} from '@temporalio/interceptors-opentelemetry';\nimport type { Context as ActivityContext } from '@temporalio/activity';\nimport type {\n ActivityInboundCallsInterceptor,\n ActivityExecuteInput,\n Next,\n} from '@temporalio/worker';\nimport type { WorkerInterceptors } from '../types.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface WorkerInterceptorsConfig {\n /** Service/processor name for logging */\n serviceName: string;\n /** Optional custom logger (defaults to console) */\n logger?: {\n info: (obj: Record<string, unknown>, msg: string) => void;\n error: (obj: Record<string, unknown>, msg: string) => void;\n };\n}\n\n// =============================================================================\n// Tracing Activity Interceptor\n// =============================================================================\n\n/**\n * Creates an activity interceptor that combines OpenTelemetry tracing with structured logging\n *\n * Uses Temporal's OpenTelemetryActivityInboundInterceptor for trace propagation,\n * and wraps it with additional structured logging that includes trace IDs.\n */\nclass TracingActivityInterceptor implements ActivityInboundCallsInterceptor {\n private readonly otelInterceptor: OpenTelemetryActivityInboundInterceptor;\n private readonly config: WorkerInterceptorsConfig;\n private readonly ctx: ActivityContext;\n\n constructor(ctx: ActivityContext, config: WorkerInterceptorsConfig) {\n this.ctx = ctx;\n this.config = config;\n // Use Temporal's built-in OTel interceptor for proper trace context propagation\n this.otelInterceptor = new OpenTelemetryActivityInboundInterceptor(ctx);\n }\n\n async execute(\n input: ActivityExecuteInput,\n next: Next<ActivityInboundCallsInterceptor, 'execute'>\n ): Promise<unknown> {\n const activityType = this.ctx.info.activityType;\n const workflowId = this.ctx.info.workflowExecution.workflowId;\n const startTime = Date.now();\n const config = this.config;\n const logger = config.logger ?? console;\n\n // Wrap the next function to add logging INSIDE the OTel span context\n const loggingNext: Next<ActivityInboundCallsInterceptor, 'execute'> = async (\n nextInput: ActivityExecuteInput\n ) => {\n // Now we're inside the OTel interceptor's span context\n const currentSpan = trace.getActiveSpan();\n const spanContext = currentSpan?.spanContext();\n\n logger.info(\n {\n activity: activityType,\n workflowId,\n processor: config.serviceName,\n trace_id: spanContext?.traceId,\n span_id: spanContext?.spanId,\n },\n 'Activity started'\n );\n\n try {\n const result = await next(nextInput);\n\n logger.info(\n {\n activity: activityType,\n workflowId,\n duration: Date.now() - startTime,\n trace_id: spanContext?.traceId,\n span_id: spanContext?.spanId,\n },\n 'Activity completed'\n );\n\n return result;\n } catch (error) {\n logger.error(\n {\n activity: activityType,\n workflowId,\n error,\n duration: Date.now() - startTime,\n trace_id: spanContext?.traceId,\n span_id: spanContext?.spanId,\n },\n 'Activity failed'\n );\n\n throw error;\n }\n };\n\n // Delegate to Temporal's OTel interceptor which sets up the span context,\n // then our loggingNext will execute with the proper trace context\n return this.otelInterceptor.execute(input, loggingNext);\n }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Creates worker interceptors configuration with OpenTelemetry trace propagation\n *\n * This returns a WorkerInterceptors object that can be passed directly to\n * the worker configuration. It includes:\n * - Activity inbound interceptors for tracing and logging\n * - Workflow module interceptors for end-to-end trace propagation\n *\n * @example\n * ```typescript\n * import { createWorker } from '@astami/temporal-functions/worker';\n * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';\n * import * as activities from './activities';\n *\n * const worker = createWorker({\n * temporal: { address: 'localhost:7233', namespace: 'loop' },\n * taskQueue: 'stripe-payments',\n * workflowsPath: './dist/workflows/index.js',\n * activities,\n * interceptors: createWorkerInterceptors({ serviceName: 'stripe' }),\n * });\n *\n * await worker.start();\n * ```\n */\nexport function createWorkerInterceptors(config: WorkerInterceptorsConfig): WorkerInterceptors {\n return {\n activityInbound: [\n (ctx: ActivityContext) => new TracingActivityInterceptor(ctx, config),\n ],\n // Include OTel workflow interceptors for end-to-end trace propagation\n workflowModules: ['@temporalio/interceptors-opentelemetry/lib/workflow'],\n };\n}\n\n// =============================================================================\n// Re-exports from Temporal OTel package\n// =============================================================================\n\nexport {\n OpenTelemetryActivityInboundInterceptor,\n} from '@temporalio/interceptors-opentelemetry';\n"]}
@@ -1,4 +1,4 @@
1
- import { a as FunctionDef, c as WorkflowDef, d as WorkflowContext } from '../types-CmhOIEkF.mjs';
1
+ import { a as FunctionDef, c as WorkflowDef, d as WorkflowContext } from '../types-DY4y7IE5.mjs';
2
2
 
3
3
  /**
4
4
  * Temporal Functions - Testing Utilities
@@ -1,4 +1,4 @@
1
- import { a as FunctionDef, c as WorkflowDef, d as WorkflowContext } from '../types-CmhOIEkF.js';
1
+ import { a as FunctionDef, c as WorkflowDef, d as WorkflowContext } from '../types-DY4y7IE5.js';
2
2
 
3
3
  /**
4
4
  * Temporal Functions - Testing Utilities
@@ -172,6 +172,52 @@ interface TLSConfig {
172
172
  /** Path to CA certificate */
173
173
  serverRootCACertPath?: string;
174
174
  }
175
+ /**
176
+ * Client interceptors configuration
177
+ *
178
+ * Uses the actual Temporal SDK interceptor types for full compatibility
179
+ * with @temporalio/interceptors-opentelemetry and other interceptor packages.
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * import { OpenTelemetryWorkflowClientInterceptor } from '@temporalio/interceptors-opentelemetry';
184
+ *
185
+ * const client = tfn.client({
186
+ * temporal: { address: 'localhost:7233' },
187
+ * interceptors: {
188
+ * workflow: [new OpenTelemetryWorkflowClientInterceptor()],
189
+ * },
190
+ * });
191
+ * ```
192
+ */
193
+ interface ClientInterceptors {
194
+ /** Workflow client interceptors (e.g., for OpenTelemetry trace propagation) */
195
+ workflow?: any[];
196
+ }
197
+ /**
198
+ * Worker interceptors configuration
199
+ *
200
+ * Supports both activity interceptors and workflow module interceptors
201
+ * for OpenTelemetry trace propagation and custom instrumentation.
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';
206
+ *
207
+ * const worker = tfn.worker({
208
+ * temporal: { address: 'localhost:7233' },
209
+ * taskQueue: 'payments',
210
+ * workflowsPath: './dist/workflows.js',
211
+ * interceptors: createWorkerInterceptors({ serviceName: 'stripe-processor' }),
212
+ * });
213
+ * ```
214
+ */
215
+ interface WorkerInterceptors {
216
+ /** Activity inbound interceptors (e.g., for logging, tracing) */
217
+ activityInbound?: ((ctx: any) => any)[];
218
+ /** Workflow interceptor module paths for bundling (e.g., '@temporalio/interceptors-opentelemetry/lib/workflow') */
219
+ workflowModules?: string[];
220
+ }
175
221
  /**
176
222
  * Client configuration options
177
223
  */
@@ -180,6 +226,8 @@ interface ClientConfig {
180
226
  temporal: TemporalConfig;
181
227
  /** Default task queue for workflows */
182
228
  taskQueue?: string;
229
+ /** Client interceptors for customizing behavior */
230
+ interceptors?: ClientInterceptors;
183
231
  }
184
232
  /**
185
233
  * Options when starting a workflow
@@ -195,6 +243,8 @@ interface StartWorkflowOptions {
195
243
  memo?: Record<string, unknown>;
196
244
  /** Search attributes */
197
245
  searchAttributes?: Record<string, unknown>;
246
+ /** Headers for context propagation (e.g., OpenTelemetry trace context) */
247
+ headers?: Record<string, string>;
198
248
  }
199
249
  /**
200
250
  * Handle to a running workflow
@@ -248,6 +298,12 @@ interface WorkerConfig {
248
298
  temporal: TemporalConfig;
249
299
  /** Task queue to poll */
250
300
  taskQueue: string;
301
+ /** Path to compiled workflow module (for external workflow files) */
302
+ workflowsPath?: string;
303
+ /** Activities object to register */
304
+ activities?: Record<string, (...args: any[]) => Promise<any>>;
305
+ /** Worker interceptors for observability and custom instrumentation */
306
+ interceptors?: WorkerInterceptors;
251
307
  /** Maximum concurrent activity executions */
252
308
  maxConcurrentActivities?: number;
253
309
  /** Maximum concurrent workflow executions */
@@ -304,4 +360,4 @@ interface Registry {
304
360
  workflows: Map<string, WorkflowDef>;
305
361
  }
306
362
 
307
- 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 };
363
+ 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, WorkerInterceptors as l };
@@ -172,6 +172,52 @@ interface TLSConfig {
172
172
  /** Path to CA certificate */
173
173
  serverRootCACertPath?: string;
174
174
  }
175
+ /**
176
+ * Client interceptors configuration
177
+ *
178
+ * Uses the actual Temporal SDK interceptor types for full compatibility
179
+ * with @temporalio/interceptors-opentelemetry and other interceptor packages.
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * import { OpenTelemetryWorkflowClientInterceptor } from '@temporalio/interceptors-opentelemetry';
184
+ *
185
+ * const client = tfn.client({
186
+ * temporal: { address: 'localhost:7233' },
187
+ * interceptors: {
188
+ * workflow: [new OpenTelemetryWorkflowClientInterceptor()],
189
+ * },
190
+ * });
191
+ * ```
192
+ */
193
+ interface ClientInterceptors {
194
+ /** Workflow client interceptors (e.g., for OpenTelemetry trace propagation) */
195
+ workflow?: any[];
196
+ }
197
+ /**
198
+ * Worker interceptors configuration
199
+ *
200
+ * Supports both activity interceptors and workflow module interceptors
201
+ * for OpenTelemetry trace propagation and custom instrumentation.
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';
206
+ *
207
+ * const worker = tfn.worker({
208
+ * temporal: { address: 'localhost:7233' },
209
+ * taskQueue: 'payments',
210
+ * workflowsPath: './dist/workflows.js',
211
+ * interceptors: createWorkerInterceptors({ serviceName: 'stripe-processor' }),
212
+ * });
213
+ * ```
214
+ */
215
+ interface WorkerInterceptors {
216
+ /** Activity inbound interceptors (e.g., for logging, tracing) */
217
+ activityInbound?: ((ctx: any) => any)[];
218
+ /** Workflow interceptor module paths for bundling (e.g., '@temporalio/interceptors-opentelemetry/lib/workflow') */
219
+ workflowModules?: string[];
220
+ }
175
221
  /**
176
222
  * Client configuration options
177
223
  */
@@ -180,6 +226,8 @@ interface ClientConfig {
180
226
  temporal: TemporalConfig;
181
227
  /** Default task queue for workflows */
182
228
  taskQueue?: string;
229
+ /** Client interceptors for customizing behavior */
230
+ interceptors?: ClientInterceptors;
183
231
  }
184
232
  /**
185
233
  * Options when starting a workflow
@@ -195,6 +243,8 @@ interface StartWorkflowOptions {
195
243
  memo?: Record<string, unknown>;
196
244
  /** Search attributes */
197
245
  searchAttributes?: Record<string, unknown>;
246
+ /** Headers for context propagation (e.g., OpenTelemetry trace context) */
247
+ headers?: Record<string, string>;
198
248
  }
199
249
  /**
200
250
  * Handle to a running workflow
@@ -248,6 +298,12 @@ interface WorkerConfig {
248
298
  temporal: TemporalConfig;
249
299
  /** Task queue to poll */
250
300
  taskQueue: string;
301
+ /** Path to compiled workflow module (for external workflow files) */
302
+ workflowsPath?: string;
303
+ /** Activities object to register */
304
+ activities?: Record<string, (...args: any[]) => Promise<any>>;
305
+ /** Worker interceptors for observability and custom instrumentation */
306
+ interceptors?: WorkerInterceptors;
251
307
  /** Maximum concurrent activity executions */
252
308
  maxConcurrentActivities?: number;
253
309
  /** Maximum concurrent workflow executions */
@@ -304,4 +360,4 @@ interface Registry {
304
360
  workflows: Map<string, WorkflowDef>;
305
361
  }
306
362
 
307
- 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 };
363
+ 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, WorkerInterceptors as l };
@@ -1,4 +1,4 @@
1
- import { h as WorkerConfig, k as TFNWorker } from '../types-CmhOIEkF.mjs';
1
+ import { h as WorkerConfig, k as TFNWorker } from '../types-DY4y7IE5.mjs';
2
2
 
3
3
  /**
4
4
  * Temporal Functions - Worker Package
@@ -12,19 +12,34 @@ import { h as WorkerConfig, k as TFNWorker } from '../types-CmhOIEkF.mjs';
12
12
  *
13
13
  * @example
14
14
  * ```typescript
15
+ * // Option 1: Using registered functions (tfn pattern)
15
16
  * import { tfn } from 'temporal-functions/worker';
16
17
  * import { validateOrder, processOrder } from './functions';
17
18
  *
18
19
  * const worker = tfn.worker({
19
- * temporal: {
20
- * address: 'localhost:7233',
21
- * namespace: 'default',
22
- * },
20
+ * temporal: { address: 'localhost:7233', namespace: 'default' },
23
21
  * taskQueue: 'my-queue',
24
22
  * });
25
23
  *
26
24
  * worker.register(validateOrder);
27
25
  * worker.register(processOrder);
26
+ * await worker.start();
27
+ * ```
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Option 2: Using external workflowsPath and activities (processor pattern)
32
+ * import { createWorker } from '@astami/temporal-functions/worker';
33
+ * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';
34
+ * import * as activities from './activities';
35
+ *
36
+ * const worker = createWorker({
37
+ * temporal: { address: 'localhost:7233', namespace: 'loop' },
38
+ * taskQueue: 'stripe-payments',
39
+ * workflowsPath: './dist/workflows/index.js',
40
+ * activities,
41
+ * interceptors: createWorkerInterceptors({ serviceName: 'stripe' }),
42
+ * });
28
43
  *
29
44
  * await worker.start();
30
45
  * ```
@@ -1,4 +1,4 @@
1
- import { h as WorkerConfig, k as TFNWorker } from '../types-CmhOIEkF.js';
1
+ import { h as WorkerConfig, k as TFNWorker } from '../types-DY4y7IE5.js';
2
2
 
3
3
  /**
4
4
  * Temporal Functions - Worker Package
@@ -12,19 +12,34 @@ import { h as WorkerConfig, k as TFNWorker } from '../types-CmhOIEkF.js';
12
12
  *
13
13
  * @example
14
14
  * ```typescript
15
+ * // Option 1: Using registered functions (tfn pattern)
15
16
  * import { tfn } from 'temporal-functions/worker';
16
17
  * import { validateOrder, processOrder } from './functions';
17
18
  *
18
19
  * const worker = tfn.worker({
19
- * temporal: {
20
- * address: 'localhost:7233',
21
- * namespace: 'default',
22
- * },
20
+ * temporal: { address: 'localhost:7233', namespace: 'default' },
23
21
  * taskQueue: 'my-queue',
24
22
  * });
25
23
  *
26
24
  * worker.register(validateOrder);
27
25
  * worker.register(processOrder);
26
+ * await worker.start();
27
+ * ```
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * // Option 2: Using external workflowsPath and activities (processor pattern)
32
+ * import { createWorker } from '@astami/temporal-functions/worker';
33
+ * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';
34
+ * import * as activities from './activities';
35
+ *
36
+ * const worker = createWorker({
37
+ * temporal: { address: 'localhost:7233', namespace: 'loop' },
38
+ * taskQueue: 'stripe-payments',
39
+ * workflowsPath: './dist/workflows/index.js',
40
+ * activities,
41
+ * interceptors: createWorkerInterceptors({ serviceName: 'stripe' }),
42
+ * });
28
43
  *
29
44
  * await worker.start();
30
45
  * ```
@@ -198,15 +198,22 @@ var TemporalFunctionsWorker = class {
198
198
  * Start the worker
199
199
  */
200
200
  async start() {
201
- if (this.functions.size === 0 && this.workflows.size === 0) {
202
- throw new Error("No functions or workflows registered. Call register() before start().");
201
+ const hasRegisteredFunctions = this.functions.size > 0 || this.workflows.size > 0;
202
+ const hasExternalConfig = this.config.workflowsPath || this.config.activities;
203
+ if (!hasRegisteredFunctions && !hasExternalConfig) {
204
+ throw new Error("No functions, workflows, or external config provided. Either call register() or provide workflowsPath/activities.");
203
205
  }
204
206
  console.log(`Starting Temporal Functions worker...`);
205
207
  console.log(` Temporal: ${this.config.temporal.address}`);
206
208
  console.log(` Namespace: ${this.config.temporal.namespace}`);
207
209
  console.log(` Task Queue: ${this.config.taskQueue}`);
208
- console.log(` Functions: ${this.functions.size}`);
209
- console.log(` Workflows: ${this.workflows.size}`);
210
+ if (this.config.workflowsPath) {
211
+ console.log(` Workflows Path: ${this.config.workflowsPath}`);
212
+ }
213
+ if (hasRegisteredFunctions) {
214
+ console.log(` Registered Functions: ${this.functions.size}`);
215
+ console.log(` Registered Workflows: ${this.workflows.size}`);
216
+ }
210
217
  const connection = await worker.NativeConnection.connect({
211
218
  address: this.config.temporal.address,
212
219
  tls: this.config.temporal.tls ? {
@@ -220,17 +227,32 @@ var TemporalFunctionsWorker = class {
220
227
  } : void 0
221
228
  } : void 0
222
229
  });
223
- const activities = this.buildActivities();
224
- this.worker = await worker.Worker.create({
230
+ const registeredActivities = this.buildActivities();
231
+ const activities = {
232
+ ...registeredActivities,
233
+ ...this.config.activities
234
+ };
235
+ const workerOptions = {
225
236
  connection,
226
237
  namespace: this.config.temporal.namespace,
227
238
  taskQueue: this.config.taskQueue,
228
- activities,
229
- // workflowsPath will need to be provided by the user
230
- // or we need to implement dynamic bundling
239
+ activities: Object.keys(activities).length > 0 ? activities : void 0,
231
240
  maxConcurrentActivityTaskExecutions: this.config.maxConcurrentActivities,
232
241
  maxConcurrentWorkflowTaskExecutions: this.config.maxConcurrentWorkflows
233
- });
242
+ };
243
+ if (this.config.workflowsPath) {
244
+ workerOptions.workflowsPath = this.config.workflowsPath;
245
+ }
246
+ if (this.config.interceptors) {
247
+ workerOptions.interceptors = {};
248
+ if (this.config.interceptors.activityInbound) {
249
+ workerOptions.interceptors.activityInbound = this.config.interceptors.activityInbound;
250
+ }
251
+ if (this.config.interceptors.workflowModules) {
252
+ workerOptions.interceptors.workflowModules = this.config.interceptors.workflowModules;
253
+ }
254
+ }
255
+ this.worker = await worker.Worker.create(workerOptions);
234
256
  const shutdown = async () => {
235
257
  if (this.shutdownRequested) return;
236
258
  this.shutdownRequested = true;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/worker/index.ts"],"names":["NativeConnection","Worker"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Temporal Functions - Main Entry Point\n *\n * This module provides the core API for defining functions and workflows.\n * Import from 'temporal-functions' for function/workflow definitions.\n * Import from 'temporal-functions/client' for triggering workflows.\n * Import from 'temporal-functions/worker' for running workers.\n */\n\nimport type {\n FunctionDef,\n FunctionOptions,\n WorkflowDef,\n WorkflowOptions,\n WorkflowHandler,\n Registry,\n HttpTriggerOptions,\n CronTriggerOptions,\n} from './types.js';\n\n// =============================================================================\n// Global Registry\n// =============================================================================\n\n/**\n * Global registry for all defined functions and workflows\n */\nexport const registry: Registry = {\n functions: new Map(),\n workflows: new Map(),\n};\n\n// =============================================================================\n// Function Definition\n// =============================================================================\n\n/**\n * Define a function (maps to a Temporal Activity)\n *\n * @example\n * ```typescript\n * export const sendEmail = tfn.fn(\n * 'sendEmail',\n * async (params: EmailParams) => {\n * return await emailService.send(params);\n * },\n * { timeout: '30s', retries: 3 }\n * );\n * ```\n */\nfunction fn<TInput, TOutput>(\n name: string,\n handler: (input: TInput) => Promise<TOutput>,\n options: FunctionOptions = {}\n): FunctionDef<TInput, TOutput> {\n const def: FunctionDef<TInput, TOutput> = {\n name,\n handler,\n options: {\n startToCloseTimeout: '1m',\n ...options,\n },\n __type: 'function',\n };\n\n registry.functions.set(name, def as FunctionDef);\n return def;\n}\n\n// =============================================================================\n// Workflow Definition\n// =============================================================================\n\n/**\n * Define a workflow\n *\n * @example\n * ```typescript\n * export const processOrder = tfn.workflow(\n * 'processOrder',\n * async (ctx, order: Order) => {\n * const validated = await ctx.run(validateOrder, order);\n * const paid = await ctx.run(chargePayment, validated);\n * return { orderId: paid.id, status: 'complete' };\n * }\n * );\n * ```\n */\nfunction workflow<TInput, TOutput>(\n name: string,\n handler: WorkflowHandler<TInput, TOutput>,\n options: WorkflowOptions = {}\n): WorkflowDef<TInput, TOutput> {\n const def: WorkflowDef<TInput, TOutput> = {\n name,\n handler,\n options: {\n taskQueue: 'default',\n ...options,\n },\n __type: 'workflow',\n };\n\n registry.workflows.set(name, def as WorkflowDef);\n return def;\n}\n\n// =============================================================================\n// Trigger Definitions (Declarative)\n// =============================================================================\n\ninterface HttpTriggerDef {\n type: 'http';\n method: string;\n path: string;\n workflow: WorkflowDef;\n options: HttpTriggerOptions;\n}\n\ninterface CronTriggerDef {\n type: 'cron';\n schedule: string;\n workflow: WorkflowDef;\n options: CronTriggerOptions;\n}\n\ninterface SignalTriggerDef {\n type: 'signal';\n signalName: string;\n handler: (payload: unknown) => void | Promise<void>;\n}\n\ntype TriggerDef = HttpTriggerDef | CronTriggerDef | SignalTriggerDef;\n\n/**\n * Registry for trigger definitions\n */\nexport const triggers: TriggerDef[] = [];\n\n/**\n * Define an HTTP trigger for a workflow\n *\n * @example\n * ```typescript\n * tfn.http('POST', '/api/orders', processOrder);\n * ```\n */\nfunction http<TInput, TOutput>(\n method: string,\n path: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: HttpTriggerOptions = {}\n): void {\n triggers.push({\n type: 'http',\n method: method.toUpperCase(),\n path,\n workflow: workflow as WorkflowDef,\n options,\n });\n}\n\n/**\n * Define a cron/scheduled trigger for a workflow\n *\n * @example\n * ```typescript\n * tfn.cron('0 9 * * *', dailyReport); // Every day at 9am\n * ```\n */\nfunction cron<TInput, TOutput>(\n schedule: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: CronTriggerOptions = {}\n): void {\n triggers.push({\n type: 'cron',\n schedule,\n workflow: workflow as WorkflowDef,\n options,\n });\n}\n\n/**\n * Define an interval trigger (convenience wrapper around cron)\n *\n * @example\n * ```typescript\n * tfn.interval('5m', healthCheck); // Every 5 minutes\n * ```\n */\nfunction interval<TInput, TOutput>(\n duration: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: CronTriggerOptions = {}\n): void {\n // Convert duration to cron expression\n const cronSchedule = durationToCron(duration);\n cron(cronSchedule, workflow, options);\n}\n\n/**\n * Define a signal trigger\n *\n * @example\n * ```typescript\n * tfn.signal('order.cancel', handleCancellation);\n * ```\n */\nfunction signal(\n signalName: string,\n handler: (payload: unknown) => void | Promise<void>\n): void {\n triggers.push({\n type: 'signal',\n signalName,\n handler,\n });\n}\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\n/**\n * Convert a duration string to a cron expression\n */\nfunction durationToCron(duration: string): string {\n const match = duration.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${duration}. Use format like '5m', '1h', '30s'`);\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's':\n if (value < 60) {\n return `*/${value} * * * * *`; // Every N seconds (non-standard)\n }\n throw new Error('Seconds interval must be less than 60');\n case 'm':\n return `*/${value} * * * *`; // Every N minutes\n case 'h':\n return `0 */${value} * * *`; // Every N hours\n case 'd':\n return `0 0 */${value} * *`; // Every N days\n default:\n throw new Error(`Unknown duration unit: ${unit}`);\n }\n}\n\n/**\n * Check if a definition is a function\n */\nexport function isFunction(def: unknown): def is FunctionDef {\n return (def as FunctionDef)?.__type === 'function';\n}\n\n/**\n * Check if a definition is a workflow\n */\nexport function isWorkflow(def: unknown): def is WorkflowDef {\n return (def as WorkflowDef)?.__type === 'workflow';\n}\n\n// =============================================================================\n// Main API Export\n// =============================================================================\n\n/**\n * The main Temporal Functions API\n */\nexport const tfn = {\n /** Define a function (activity) */\n fn,\n /** Define a workflow */\n workflow,\n /** Define an HTTP trigger */\n http,\n /** Define a cron trigger */\n cron,\n /** Define an interval trigger */\n interval,\n /** Define a signal trigger */\n signal,\n};\n\n// Re-export types\nexport type {\n FunctionDef,\n FunctionOptions,\n WorkflowDef,\n WorkflowOptions,\n WorkflowContext,\n WorkflowHandler,\n WorkflowInfo,\n RetryPolicy,\n HttpTriggerOptions,\n CronTriggerOptions,\n TemporalConfig,\n ClientConfig,\n WorkerConfig,\n StartWorkflowOptions,\n WorkflowHandle,\n TFNClient,\n TFNWorker,\n} from './types.js';\n\nexport default tfn;\n","/**\n * Temporal Functions - Worker Package\n *\n * Full worker implementation for executing functions and workflows.\n * Import from 'temporal-functions/worker'.\n */\n\nimport { Worker, NativeConnection } from '@temporalio/worker';\nimport type {\n WorkerConfig,\n FunctionDef,\n WorkflowDef,\n TFNWorker,\n} from '../types.js';\nimport { isFunction, isWorkflow } from '../index.js';\n\n// =============================================================================\n// Worker Implementation\n// =============================================================================\n\nclass TemporalFunctionsWorker implements TFNWorker {\n private config: WorkerConfig;\n private functions: Map<string, FunctionDef> = new Map();\n private workflows: Map<string, WorkflowDef> = new Map();\n private worker: Worker | null = null;\n private shutdownRequested = false;\n\n constructor(config: WorkerConfig) {\n this.config = {\n ...config,\n temporal: {\n namespace: 'default',\n ...config.temporal,\n },\n maxConcurrentActivities: config.maxConcurrentActivities ?? 100,\n maxConcurrentWorkflows: config.maxConcurrentWorkflows ?? 50,\n };\n }\n\n /**\n * Register a function or workflow\n */\n register(def: FunctionDef | WorkflowDef): void {\n if (isFunction(def)) {\n this.functions.set(def.name, def);\n } else if (isWorkflow(def)) {\n this.workflows.set(def.name, def);\n } else {\n throw new Error('Invalid definition: must be a function or workflow created with tfn.fn() or tfn.workflow()');\n }\n }\n\n /**\n * Register all exported functions and workflows from a module\n */\n registerModule(module: Record<string, unknown>): void {\n for (const [, value] of Object.entries(module)) {\n if (isFunction(value) || isWorkflow(value)) {\n this.register(value);\n }\n }\n }\n\n /**\n * Build activities object from registered functions\n */\n private buildActivities(): Record<string, (...args: unknown[]) => Promise<unknown>> {\n const activities: Record<string, (...args: unknown[]) => Promise<unknown>> = {};\n\n for (const [name, def] of this.functions) {\n activities[name] = async (input: unknown) => {\n return def.handler(input);\n };\n }\n\n return activities;\n }\n\n /**\n * Generate workflow wrapper code for Temporal\n *\n * This creates the workflow module that Temporal requires,\n * wrapping our user-defined workflow handlers with the proper\n * Temporal workflow context.\n */\n private generateWorkflowBundle(): string {\n const workflowNames = Array.from(this.workflows.keys());\n\n // Generate the workflow module code\n const code = `\n import { proxyActivities, sleep, workflowInfo, setHandler, defineSignal, defineQuery, condition, CancellationScope } from '@temporalio/workflow';\n\n // Proxy all activities\n const activities = proxyActivities({\n startToCloseTimeout: '1 minute',\n });\n\n // Create workflow context\n function createContext() {\n const signalHandlers = new Map();\n const queryHandlers = new Map();\n const signalPayloads = new Map();\n const signalReceived = new Map();\n\n return {\n run: async (fn, input, options = {}) => {\n const activity = activities[fn.name];\n if (!activity) {\n throw new Error(\\`Function \\${fn.name} not registered\\`);\n }\n return activity(input);\n },\n sleep: async (duration) => {\n if (typeof duration === 'string') {\n const ms = parseDuration(duration);\n return sleep(ms);\n }\n return sleep(duration);\n },\n now: () => new Date(),\n startChild: async (workflow, input, options = {}) => {\n throw new Error('startChild not yet implemented');\n },\n continueAsNew: async (input) => {\n throw new Error('continueAsNew not yet implemented');\n },\n onSignal: (signalName, handler) => {\n signalHandlers.set(signalName, handler);\n const signal = defineSignal(signalName);\n setHandler(signal, handler);\n },\n waitForSignal: async (signalName, options = {}) => {\n // Register signal handler if not already registered\n if (!signalReceived.has(signalName)) {\n signalReceived.set(signalName, false);\n signalPayloads.set(signalName, undefined);\n const signal = defineSignal(signalName);\n setHandler(signal, (payload) => {\n signalPayloads.set(signalName, payload);\n signalReceived.set(signalName, true);\n });\n }\n\n // Wait for signal with optional timeout\n const timeoutMs = options.timeout ? parseDuration(options.timeout) : undefined;\n const received = await condition(() => signalReceived.get(signalName), timeoutMs);\n\n if (!received) {\n throw new Error(\\`Timeout waiting for signal: \\${signalName}\\`);\n }\n\n // Reset for potential reuse\n const payload = signalPayloads.get(signalName);\n signalReceived.set(signalName, false);\n signalPayloads.set(signalName, undefined);\n\n return payload;\n },\n onQuery: (queryName, handler) => {\n queryHandlers.set(queryName, handler);\n const query = defineQuery(queryName);\n setHandler(query, handler);\n },\n get info() {\n const info = workflowInfo();\n return {\n workflowId: info.workflowId,\n runId: info.runId,\n taskQueue: info.taskQueue,\n workflowType: info.workflowType,\n namespace: info.namespace,\n };\n },\n };\n }\n\n // Parse duration string to milliseconds\n function parseDuration(duration) {\n const match = duration.match(/^(\\\\d+(?:\\\\.\\\\d+)?)(ms|s|m|h|d)$/);\n if (!match) {\n throw new Error(\\`Invalid duration: \\${duration}\\`);\n }\n const value = parseFloat(match[1]);\n const unit = match[2];\n switch (unit) {\n case 'ms': return value;\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: throw new Error(\\`Unknown duration unit: \\${unit}\\`);\n }\n }\n\n // Export workflow functions\n ${workflowNames.map((name) => `\n export async function ${name}(input) {\n const ctx = createContext();\n const handler = __workflowHandlers__.get('${name}');\n if (!handler) {\n throw new Error('Workflow handler not found: ${name}');\n }\n return handler(ctx, input);\n }\n `).join('\\n')}\n `;\n\n return code;\n }\n\n /**\n * Start the worker\n */\n async start(): Promise<void> {\n if (this.functions.size === 0 && this.workflows.size === 0) {\n throw new Error('No functions or workflows registered. Call register() before start().');\n }\n\n console.log(`Starting Temporal Functions worker...`);\n console.log(` Temporal: ${this.config.temporal.address}`);\n console.log(` Namespace: ${this.config.temporal.namespace}`);\n console.log(` Task Queue: ${this.config.taskQueue}`);\n console.log(` Functions: ${this.functions.size}`);\n console.log(` Workflows: ${this.workflows.size}`);\n\n // Connect to Temporal\n const connection = await NativeConnection.connect({\n address: this.config.temporal.address,\n tls: this.config.temporal.tls\n ? {\n clientCertPair: this.config.temporal.tls.clientCertPath\n ? {\n crt: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientCertPath!)\n ),\n key: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientKeyPath!)\n ),\n }\n : undefined,\n }\n : undefined,\n });\n\n // Build activities\n const activities = this.buildActivities();\n\n // For now, we'll use a simplified approach where workflows\n // are bundled separately. In a full implementation, we'd\n // generate the workflow bundle dynamically.\n //\n // TODO: Implement dynamic workflow bundling\n // const workflowBundle = this.generateWorkflowBundle();\n\n // Create worker\n this.worker = await Worker.create({\n connection,\n namespace: this.config.temporal.namespace,\n taskQueue: this.config.taskQueue,\n activities,\n // workflowsPath will need to be provided by the user\n // or we need to implement dynamic bundling\n maxConcurrentActivityTaskExecutions: this.config.maxConcurrentActivities,\n maxConcurrentWorkflowTaskExecutions: this.config.maxConcurrentWorkflows,\n });\n\n // Handle graceful shutdown\n const shutdown = async () => {\n if (this.shutdownRequested) return;\n this.shutdownRequested = true;\n console.log('\\nShutting down worker...');\n await this.shutdown();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n console.log('\\nWorker started. Press Ctrl+C to stop.\\n');\n\n // Run the worker (blocks until shutdown)\n await this.worker.run();\n }\n\n /**\n * Gracefully shutdown the worker\n */\n async shutdown(): Promise<void> {\n if (this.worker) {\n this.worker.shutdown();\n this.worker = null;\n }\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a Temporal Functions worker\n *\n * @example\n * ```typescript\n * import { tfn } from 'temporal-functions/worker';\n * import { validateOrder, processOrder } from './functions';\n *\n * const worker = tfn.worker({\n * temporal: {\n * address: 'localhost:7233',\n * namespace: 'default',\n * },\n * taskQueue: 'my-queue',\n * });\n *\n * worker.register(validateOrder);\n * worker.register(processOrder);\n *\n * await worker.start();\n * ```\n */\nfunction createWorker(config: WorkerConfig): TFNWorker {\n return new TemporalFunctionsWorker(config);\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n worker: createWorker,\n};\n\nexport { createWorker };\nexport type { WorkerConfig, TFNWorker };\nexport default tfn;\n"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/worker/index.ts"],"names":["NativeConnection","Worker"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Temporal Functions - Main Entry Point\n *\n * This module provides the core API for defining functions and workflows.\n * Import from 'temporal-functions' for function/workflow definitions.\n * Import from 'temporal-functions/client' for triggering workflows.\n * Import from 'temporal-functions/worker' for running workers.\n */\n\nimport type {\n FunctionDef,\n FunctionOptions,\n WorkflowDef,\n WorkflowOptions,\n WorkflowHandler,\n Registry,\n HttpTriggerOptions,\n CronTriggerOptions,\n} from './types.js';\n\n// =============================================================================\n// Global Registry\n// =============================================================================\n\n/**\n * Global registry for all defined functions and workflows\n */\nexport const registry: Registry = {\n functions: new Map(),\n workflows: new Map(),\n};\n\n// =============================================================================\n// Function Definition\n// =============================================================================\n\n/**\n * Define a function (maps to a Temporal Activity)\n *\n * @example\n * ```typescript\n * export const sendEmail = tfn.fn(\n * 'sendEmail',\n * async (params: EmailParams) => {\n * return await emailService.send(params);\n * },\n * { timeout: '30s', retries: 3 }\n * );\n * ```\n */\nfunction fn<TInput, TOutput>(\n name: string,\n handler: (input: TInput) => Promise<TOutput>,\n options: FunctionOptions = {}\n): FunctionDef<TInput, TOutput> {\n const def: FunctionDef<TInput, TOutput> = {\n name,\n handler,\n options: {\n startToCloseTimeout: '1m',\n ...options,\n },\n __type: 'function',\n };\n\n registry.functions.set(name, def as FunctionDef);\n return def;\n}\n\n// =============================================================================\n// Workflow Definition\n// =============================================================================\n\n/**\n * Define a workflow\n *\n * @example\n * ```typescript\n * export const processOrder = tfn.workflow(\n * 'processOrder',\n * async (ctx, order: Order) => {\n * const validated = await ctx.run(validateOrder, order);\n * const paid = await ctx.run(chargePayment, validated);\n * return { orderId: paid.id, status: 'complete' };\n * }\n * );\n * ```\n */\nfunction workflow<TInput, TOutput>(\n name: string,\n handler: WorkflowHandler<TInput, TOutput>,\n options: WorkflowOptions = {}\n): WorkflowDef<TInput, TOutput> {\n const def: WorkflowDef<TInput, TOutput> = {\n name,\n handler,\n options: {\n taskQueue: 'default',\n ...options,\n },\n __type: 'workflow',\n };\n\n registry.workflows.set(name, def as WorkflowDef);\n return def;\n}\n\n// =============================================================================\n// Trigger Definitions (Declarative)\n// =============================================================================\n\ninterface HttpTriggerDef {\n type: 'http';\n method: string;\n path: string;\n workflow: WorkflowDef;\n options: HttpTriggerOptions;\n}\n\ninterface CronTriggerDef {\n type: 'cron';\n schedule: string;\n workflow: WorkflowDef;\n options: CronTriggerOptions;\n}\n\ninterface SignalTriggerDef {\n type: 'signal';\n signalName: string;\n handler: (payload: unknown) => void | Promise<void>;\n}\n\ntype TriggerDef = HttpTriggerDef | CronTriggerDef | SignalTriggerDef;\n\n/**\n * Registry for trigger definitions\n */\nexport const triggers: TriggerDef[] = [];\n\n/**\n * Define an HTTP trigger for a workflow\n *\n * @example\n * ```typescript\n * tfn.http('POST', '/api/orders', processOrder);\n * ```\n */\nfunction http<TInput, TOutput>(\n method: string,\n path: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: HttpTriggerOptions = {}\n): void {\n triggers.push({\n type: 'http',\n method: method.toUpperCase(),\n path,\n workflow: workflow as WorkflowDef,\n options,\n });\n}\n\n/**\n * Define a cron/scheduled trigger for a workflow\n *\n * @example\n * ```typescript\n * tfn.cron('0 9 * * *', dailyReport); // Every day at 9am\n * ```\n */\nfunction cron<TInput, TOutput>(\n schedule: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: CronTriggerOptions = {}\n): void {\n triggers.push({\n type: 'cron',\n schedule,\n workflow: workflow as WorkflowDef,\n options,\n });\n}\n\n/**\n * Define an interval trigger (convenience wrapper around cron)\n *\n * @example\n * ```typescript\n * tfn.interval('5m', healthCheck); // Every 5 minutes\n * ```\n */\nfunction interval<TInput, TOutput>(\n duration: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: CronTriggerOptions = {}\n): void {\n // Convert duration to cron expression\n const cronSchedule = durationToCron(duration);\n cron(cronSchedule, workflow, options);\n}\n\n/**\n * Define a signal trigger\n *\n * @example\n * ```typescript\n * tfn.signal('order.cancel', handleCancellation);\n * ```\n */\nfunction signal(\n signalName: string,\n handler: (payload: unknown) => void | Promise<void>\n): void {\n triggers.push({\n type: 'signal',\n signalName,\n handler,\n });\n}\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\n/**\n * Convert a duration string to a cron expression\n */\nfunction durationToCron(duration: string): string {\n const match = duration.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${duration}. Use format like '5m', '1h', '30s'`);\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's':\n if (value < 60) {\n return `*/${value} * * * * *`; // Every N seconds (non-standard)\n }\n throw new Error('Seconds interval must be less than 60');\n case 'm':\n return `*/${value} * * * *`; // Every N minutes\n case 'h':\n return `0 */${value} * * *`; // Every N hours\n case 'd':\n return `0 0 */${value} * *`; // Every N days\n default:\n throw new Error(`Unknown duration unit: ${unit}`);\n }\n}\n\n/**\n * Check if a definition is a function\n */\nexport function isFunction(def: unknown): def is FunctionDef {\n return (def as FunctionDef)?.__type === 'function';\n}\n\n/**\n * Check if a definition is a workflow\n */\nexport function isWorkflow(def: unknown): def is WorkflowDef {\n return (def as WorkflowDef)?.__type === 'workflow';\n}\n\n// =============================================================================\n// Main API Export\n// =============================================================================\n\n/**\n * The main Temporal Functions API\n */\nexport const tfn = {\n /** Define a function (activity) */\n fn,\n /** Define a workflow */\n workflow,\n /** Define an HTTP trigger */\n http,\n /** Define a cron trigger */\n cron,\n /** Define an interval trigger */\n interval,\n /** Define a signal trigger */\n signal,\n};\n\n// Re-export types\nexport type {\n FunctionDef,\n FunctionOptions,\n WorkflowDef,\n WorkflowOptions,\n WorkflowContext,\n WorkflowHandler,\n WorkflowInfo,\n RetryPolicy,\n HttpTriggerOptions,\n CronTriggerOptions,\n TemporalConfig,\n ClientConfig,\n WorkerConfig,\n StartWorkflowOptions,\n WorkflowHandle,\n TFNClient,\n TFNWorker,\n} from './types.js';\n\nexport default tfn;\n","/**\n * Temporal Functions - Worker Package\n *\n * Full worker implementation for executing functions and workflows.\n * Import from 'temporal-functions/worker'.\n */\n\nimport { Worker, NativeConnection } from '@temporalio/worker';\nimport type {\n WorkerConfig,\n FunctionDef,\n WorkflowDef,\n TFNWorker,\n} from '../types.js';\nimport { isFunction, isWorkflow } from '../index.js';\n\n// =============================================================================\n// Worker Implementation\n// =============================================================================\n\nclass TemporalFunctionsWorker implements TFNWorker {\n private config: WorkerConfig;\n private functions: Map<string, FunctionDef> = new Map();\n private workflows: Map<string, WorkflowDef> = new Map();\n private worker: Worker | null = null;\n private shutdownRequested = false;\n\n constructor(config: WorkerConfig) {\n this.config = {\n ...config,\n temporal: {\n namespace: 'default',\n ...config.temporal,\n },\n maxConcurrentActivities: config.maxConcurrentActivities ?? 100,\n maxConcurrentWorkflows: config.maxConcurrentWorkflows ?? 50,\n };\n }\n\n /**\n * Register a function or workflow\n */\n register(def: FunctionDef | WorkflowDef): void {\n if (isFunction(def)) {\n this.functions.set(def.name, def);\n } else if (isWorkflow(def)) {\n this.workflows.set(def.name, def);\n } else {\n throw new Error('Invalid definition: must be a function or workflow created with tfn.fn() or tfn.workflow()');\n }\n }\n\n /**\n * Register all exported functions and workflows from a module\n */\n registerModule(module: Record<string, unknown>): void {\n for (const [, value] of Object.entries(module)) {\n if (isFunction(value) || isWorkflow(value)) {\n this.register(value);\n }\n }\n }\n\n /**\n * Build activities object from registered functions\n */\n private buildActivities(): Record<string, (...args: unknown[]) => Promise<unknown>> {\n const activities: Record<string, (...args: unknown[]) => Promise<unknown>> = {};\n\n for (const [name, def] of this.functions) {\n activities[name] = async (input: unknown) => {\n return def.handler(input);\n };\n }\n\n return activities;\n }\n\n /**\n * Generate workflow wrapper code for Temporal\n *\n * This creates the workflow module that Temporal requires,\n * wrapping our user-defined workflow handlers with the proper\n * Temporal workflow context.\n */\n private generateWorkflowBundle(): string {\n const workflowNames = Array.from(this.workflows.keys());\n\n // Generate the workflow module code\n const code = `\n import { proxyActivities, sleep, workflowInfo, setHandler, defineSignal, defineQuery, condition, CancellationScope } from '@temporalio/workflow';\n\n // Proxy all activities\n const activities = proxyActivities({\n startToCloseTimeout: '1 minute',\n });\n\n // Create workflow context\n function createContext() {\n const signalHandlers = new Map();\n const queryHandlers = new Map();\n const signalPayloads = new Map();\n const signalReceived = new Map();\n\n return {\n run: async (fn, input, options = {}) => {\n const activity = activities[fn.name];\n if (!activity) {\n throw new Error(\\`Function \\${fn.name} not registered\\`);\n }\n return activity(input);\n },\n sleep: async (duration) => {\n if (typeof duration === 'string') {\n const ms = parseDuration(duration);\n return sleep(ms);\n }\n return sleep(duration);\n },\n now: () => new Date(),\n startChild: async (workflow, input, options = {}) => {\n throw new Error('startChild not yet implemented');\n },\n continueAsNew: async (input) => {\n throw new Error('continueAsNew not yet implemented');\n },\n onSignal: (signalName, handler) => {\n signalHandlers.set(signalName, handler);\n const signal = defineSignal(signalName);\n setHandler(signal, handler);\n },\n waitForSignal: async (signalName, options = {}) => {\n // Register signal handler if not already registered\n if (!signalReceived.has(signalName)) {\n signalReceived.set(signalName, false);\n signalPayloads.set(signalName, undefined);\n const signal = defineSignal(signalName);\n setHandler(signal, (payload) => {\n signalPayloads.set(signalName, payload);\n signalReceived.set(signalName, true);\n });\n }\n\n // Wait for signal with optional timeout\n const timeoutMs = options.timeout ? parseDuration(options.timeout) : undefined;\n const received = await condition(() => signalReceived.get(signalName), timeoutMs);\n\n if (!received) {\n throw new Error(\\`Timeout waiting for signal: \\${signalName}\\`);\n }\n\n // Reset for potential reuse\n const payload = signalPayloads.get(signalName);\n signalReceived.set(signalName, false);\n signalPayloads.set(signalName, undefined);\n\n return payload;\n },\n onQuery: (queryName, handler) => {\n queryHandlers.set(queryName, handler);\n const query = defineQuery(queryName);\n setHandler(query, handler);\n },\n get info() {\n const info = workflowInfo();\n return {\n workflowId: info.workflowId,\n runId: info.runId,\n taskQueue: info.taskQueue,\n workflowType: info.workflowType,\n namespace: info.namespace,\n };\n },\n };\n }\n\n // Parse duration string to milliseconds\n function parseDuration(duration) {\n const match = duration.match(/^(\\\\d+(?:\\\\.\\\\d+)?)(ms|s|m|h|d)$/);\n if (!match) {\n throw new Error(\\`Invalid duration: \\${duration}\\`);\n }\n const value = parseFloat(match[1]);\n const unit = match[2];\n switch (unit) {\n case 'ms': return value;\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: throw new Error(\\`Unknown duration unit: \\${unit}\\`);\n }\n }\n\n // Export workflow functions\n ${workflowNames.map((name) => `\n export async function ${name}(input) {\n const ctx = createContext();\n const handler = __workflowHandlers__.get('${name}');\n if (!handler) {\n throw new Error('Workflow handler not found: ${name}');\n }\n return handler(ctx, input);\n }\n `).join('\\n')}\n `;\n\n return code;\n }\n\n /**\n * Start the worker\n */\n async start(): Promise<void> {\n // Allow starting with external workflowsPath and activities\n const hasRegisteredFunctions = this.functions.size > 0 || this.workflows.size > 0;\n const hasExternalConfig = this.config.workflowsPath || this.config.activities;\n\n if (!hasRegisteredFunctions && !hasExternalConfig) {\n throw new Error('No functions, workflows, or external config provided. Either call register() or provide workflowsPath/activities.');\n }\n\n console.log(`Starting Temporal Functions worker...`);\n console.log(` Temporal: ${this.config.temporal.address}`);\n console.log(` Namespace: ${this.config.temporal.namespace}`);\n console.log(` Task Queue: ${this.config.taskQueue}`);\n if (this.config.workflowsPath) {\n console.log(` Workflows Path: ${this.config.workflowsPath}`);\n }\n if (hasRegisteredFunctions) {\n console.log(` Registered Functions: ${this.functions.size}`);\n console.log(` Registered Workflows: ${this.workflows.size}`);\n }\n\n // Connect to Temporal\n const connection = await NativeConnection.connect({\n address: this.config.temporal.address,\n tls: this.config.temporal.tls\n ? {\n clientCertPair: this.config.temporal.tls.clientCertPath\n ? {\n crt: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientCertPath!)\n ),\n key: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientKeyPath!)\n ),\n }\n : undefined,\n }\n : undefined,\n });\n\n // Build activities - merge registered functions with external activities\n const registeredActivities = this.buildActivities();\n const activities = {\n ...registeredActivities,\n ...this.config.activities,\n };\n\n // Build worker options\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const workerOptions: any = {\n connection,\n namespace: this.config.temporal.namespace,\n taskQueue: this.config.taskQueue,\n activities: Object.keys(activities).length > 0 ? activities : undefined,\n maxConcurrentActivityTaskExecutions: this.config.maxConcurrentActivities,\n maxConcurrentWorkflowTaskExecutions: this.config.maxConcurrentWorkflows,\n };\n\n // Add workflowsPath if provided (for external workflow files)\n if (this.config.workflowsPath) {\n workerOptions.workflowsPath = this.config.workflowsPath;\n }\n\n // Add interceptors if provided\n if (this.config.interceptors) {\n workerOptions.interceptors = {};\n\n if (this.config.interceptors.activityInbound) {\n workerOptions.interceptors.activityInbound = this.config.interceptors.activityInbound;\n }\n\n if (this.config.interceptors.workflowModules) {\n workerOptions.interceptors.workflowModules = this.config.interceptors.workflowModules;\n }\n }\n\n // Create worker\n this.worker = await Worker.create(workerOptions);\n\n // Handle graceful shutdown\n const shutdown = async () => {\n if (this.shutdownRequested) return;\n this.shutdownRequested = true;\n console.log('\\nShutting down worker...');\n await this.shutdown();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n console.log('\\nWorker started. Press Ctrl+C to stop.\\n');\n\n // Run the worker (blocks until shutdown)\n await this.worker.run();\n }\n\n /**\n * Gracefully shutdown the worker\n */\n async shutdown(): Promise<void> {\n if (this.worker) {\n this.worker.shutdown();\n this.worker = null;\n }\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a Temporal Functions worker\n *\n * @example\n * ```typescript\n * // Option 1: Using registered functions (tfn pattern)\n * import { tfn } from 'temporal-functions/worker';\n * import { validateOrder, processOrder } from './functions';\n *\n * const worker = tfn.worker({\n * temporal: { address: 'localhost:7233', namespace: 'default' },\n * taskQueue: 'my-queue',\n * });\n *\n * worker.register(validateOrder);\n * worker.register(processOrder);\n * await worker.start();\n * ```\n *\n * @example\n * ```typescript\n * // Option 2: Using external workflowsPath and activities (processor pattern)\n * import { createWorker } from '@astami/temporal-functions/worker';\n * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';\n * import * as activities from './activities';\n *\n * const worker = createWorker({\n * temporal: { address: 'localhost:7233', namespace: 'loop' },\n * taskQueue: 'stripe-payments',\n * workflowsPath: './dist/workflows/index.js',\n * activities,\n * interceptors: createWorkerInterceptors({ serviceName: 'stripe' }),\n * });\n *\n * await worker.start();\n * ```\n */\nfunction createWorker(config: WorkerConfig): TFNWorker {\n return new TemporalFunctionsWorker(config);\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n worker: createWorker,\n};\n\nexport { createWorker };\nexport type { WorkerConfig, TFNWorker };\nexport default tfn;\n"]}
@@ -194,15 +194,22 @@ var TemporalFunctionsWorker = class {
194
194
  * Start the worker
195
195
  */
196
196
  async start() {
197
- if (this.functions.size === 0 && this.workflows.size === 0) {
198
- throw new Error("No functions or workflows registered. Call register() before start().");
197
+ const hasRegisteredFunctions = this.functions.size > 0 || this.workflows.size > 0;
198
+ const hasExternalConfig = this.config.workflowsPath || this.config.activities;
199
+ if (!hasRegisteredFunctions && !hasExternalConfig) {
200
+ throw new Error("No functions, workflows, or external config provided. Either call register() or provide workflowsPath/activities.");
199
201
  }
200
202
  console.log(`Starting Temporal Functions worker...`);
201
203
  console.log(` Temporal: ${this.config.temporal.address}`);
202
204
  console.log(` Namespace: ${this.config.temporal.namespace}`);
203
205
  console.log(` Task Queue: ${this.config.taskQueue}`);
204
- console.log(` Functions: ${this.functions.size}`);
205
- console.log(` Workflows: ${this.workflows.size}`);
206
+ if (this.config.workflowsPath) {
207
+ console.log(` Workflows Path: ${this.config.workflowsPath}`);
208
+ }
209
+ if (hasRegisteredFunctions) {
210
+ console.log(` Registered Functions: ${this.functions.size}`);
211
+ console.log(` Registered Workflows: ${this.workflows.size}`);
212
+ }
206
213
  const connection = await NativeConnection.connect({
207
214
  address: this.config.temporal.address,
208
215
  tls: this.config.temporal.tls ? {
@@ -216,17 +223,32 @@ var TemporalFunctionsWorker = class {
216
223
  } : void 0
217
224
  } : void 0
218
225
  });
219
- const activities = this.buildActivities();
220
- this.worker = await Worker.create({
226
+ const registeredActivities = this.buildActivities();
227
+ const activities = {
228
+ ...registeredActivities,
229
+ ...this.config.activities
230
+ };
231
+ const workerOptions = {
221
232
  connection,
222
233
  namespace: this.config.temporal.namespace,
223
234
  taskQueue: this.config.taskQueue,
224
- activities,
225
- // workflowsPath will need to be provided by the user
226
- // or we need to implement dynamic bundling
235
+ activities: Object.keys(activities).length > 0 ? activities : void 0,
227
236
  maxConcurrentActivityTaskExecutions: this.config.maxConcurrentActivities,
228
237
  maxConcurrentWorkflowTaskExecutions: this.config.maxConcurrentWorkflows
229
- });
238
+ };
239
+ if (this.config.workflowsPath) {
240
+ workerOptions.workflowsPath = this.config.workflowsPath;
241
+ }
242
+ if (this.config.interceptors) {
243
+ workerOptions.interceptors = {};
244
+ if (this.config.interceptors.activityInbound) {
245
+ workerOptions.interceptors.activityInbound = this.config.interceptors.activityInbound;
246
+ }
247
+ if (this.config.interceptors.workflowModules) {
248
+ workerOptions.interceptors.workflowModules = this.config.interceptors.workflowModules;
249
+ }
250
+ }
251
+ this.worker = await Worker.create(workerOptions);
230
252
  const shutdown = async () => {
231
253
  if (this.shutdownRequested) return;
232
254
  this.shutdownRequested = true;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/worker/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Temporal Functions - Main Entry Point\n *\n * This module provides the core API for defining functions and workflows.\n * Import from 'temporal-functions' for function/workflow definitions.\n * Import from 'temporal-functions/client' for triggering workflows.\n * Import from 'temporal-functions/worker' for running workers.\n */\n\nimport type {\n FunctionDef,\n FunctionOptions,\n WorkflowDef,\n WorkflowOptions,\n WorkflowHandler,\n Registry,\n HttpTriggerOptions,\n CronTriggerOptions,\n} from './types.js';\n\n// =============================================================================\n// Global Registry\n// =============================================================================\n\n/**\n * Global registry for all defined functions and workflows\n */\nexport const registry: Registry = {\n functions: new Map(),\n workflows: new Map(),\n};\n\n// =============================================================================\n// Function Definition\n// =============================================================================\n\n/**\n * Define a function (maps to a Temporal Activity)\n *\n * @example\n * ```typescript\n * export const sendEmail = tfn.fn(\n * 'sendEmail',\n * async (params: EmailParams) => {\n * return await emailService.send(params);\n * },\n * { timeout: '30s', retries: 3 }\n * );\n * ```\n */\nfunction fn<TInput, TOutput>(\n name: string,\n handler: (input: TInput) => Promise<TOutput>,\n options: FunctionOptions = {}\n): FunctionDef<TInput, TOutput> {\n const def: FunctionDef<TInput, TOutput> = {\n name,\n handler,\n options: {\n startToCloseTimeout: '1m',\n ...options,\n },\n __type: 'function',\n };\n\n registry.functions.set(name, def as FunctionDef);\n return def;\n}\n\n// =============================================================================\n// Workflow Definition\n// =============================================================================\n\n/**\n * Define a workflow\n *\n * @example\n * ```typescript\n * export const processOrder = tfn.workflow(\n * 'processOrder',\n * async (ctx, order: Order) => {\n * const validated = await ctx.run(validateOrder, order);\n * const paid = await ctx.run(chargePayment, validated);\n * return { orderId: paid.id, status: 'complete' };\n * }\n * );\n * ```\n */\nfunction workflow<TInput, TOutput>(\n name: string,\n handler: WorkflowHandler<TInput, TOutput>,\n options: WorkflowOptions = {}\n): WorkflowDef<TInput, TOutput> {\n const def: WorkflowDef<TInput, TOutput> = {\n name,\n handler,\n options: {\n taskQueue: 'default',\n ...options,\n },\n __type: 'workflow',\n };\n\n registry.workflows.set(name, def as WorkflowDef);\n return def;\n}\n\n// =============================================================================\n// Trigger Definitions (Declarative)\n// =============================================================================\n\ninterface HttpTriggerDef {\n type: 'http';\n method: string;\n path: string;\n workflow: WorkflowDef;\n options: HttpTriggerOptions;\n}\n\ninterface CronTriggerDef {\n type: 'cron';\n schedule: string;\n workflow: WorkflowDef;\n options: CronTriggerOptions;\n}\n\ninterface SignalTriggerDef {\n type: 'signal';\n signalName: string;\n handler: (payload: unknown) => void | Promise<void>;\n}\n\ntype TriggerDef = HttpTriggerDef | CronTriggerDef | SignalTriggerDef;\n\n/**\n * Registry for trigger definitions\n */\nexport const triggers: TriggerDef[] = [];\n\n/**\n * Define an HTTP trigger for a workflow\n *\n * @example\n * ```typescript\n * tfn.http('POST', '/api/orders', processOrder);\n * ```\n */\nfunction http<TInput, TOutput>(\n method: string,\n path: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: HttpTriggerOptions = {}\n): void {\n triggers.push({\n type: 'http',\n method: method.toUpperCase(),\n path,\n workflow: workflow as WorkflowDef,\n options,\n });\n}\n\n/**\n * Define a cron/scheduled trigger for a workflow\n *\n * @example\n * ```typescript\n * tfn.cron('0 9 * * *', dailyReport); // Every day at 9am\n * ```\n */\nfunction cron<TInput, TOutput>(\n schedule: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: CronTriggerOptions = {}\n): void {\n triggers.push({\n type: 'cron',\n schedule,\n workflow: workflow as WorkflowDef,\n options,\n });\n}\n\n/**\n * Define an interval trigger (convenience wrapper around cron)\n *\n * @example\n * ```typescript\n * tfn.interval('5m', healthCheck); // Every 5 minutes\n * ```\n */\nfunction interval<TInput, TOutput>(\n duration: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: CronTriggerOptions = {}\n): void {\n // Convert duration to cron expression\n const cronSchedule = durationToCron(duration);\n cron(cronSchedule, workflow, options);\n}\n\n/**\n * Define a signal trigger\n *\n * @example\n * ```typescript\n * tfn.signal('order.cancel', handleCancellation);\n * ```\n */\nfunction signal(\n signalName: string,\n handler: (payload: unknown) => void | Promise<void>\n): void {\n triggers.push({\n type: 'signal',\n signalName,\n handler,\n });\n}\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\n/**\n * Convert a duration string to a cron expression\n */\nfunction durationToCron(duration: string): string {\n const match = duration.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${duration}. Use format like '5m', '1h', '30s'`);\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's':\n if (value < 60) {\n return `*/${value} * * * * *`; // Every N seconds (non-standard)\n }\n throw new Error('Seconds interval must be less than 60');\n case 'm':\n return `*/${value} * * * *`; // Every N minutes\n case 'h':\n return `0 */${value} * * *`; // Every N hours\n case 'd':\n return `0 0 */${value} * *`; // Every N days\n default:\n throw new Error(`Unknown duration unit: ${unit}`);\n }\n}\n\n/**\n * Check if a definition is a function\n */\nexport function isFunction(def: unknown): def is FunctionDef {\n return (def as FunctionDef)?.__type === 'function';\n}\n\n/**\n * Check if a definition is a workflow\n */\nexport function isWorkflow(def: unknown): def is WorkflowDef {\n return (def as WorkflowDef)?.__type === 'workflow';\n}\n\n// =============================================================================\n// Main API Export\n// =============================================================================\n\n/**\n * The main Temporal Functions API\n */\nexport const tfn = {\n /** Define a function (activity) */\n fn,\n /** Define a workflow */\n workflow,\n /** Define an HTTP trigger */\n http,\n /** Define a cron trigger */\n cron,\n /** Define an interval trigger */\n interval,\n /** Define a signal trigger */\n signal,\n};\n\n// Re-export types\nexport type {\n FunctionDef,\n FunctionOptions,\n WorkflowDef,\n WorkflowOptions,\n WorkflowContext,\n WorkflowHandler,\n WorkflowInfo,\n RetryPolicy,\n HttpTriggerOptions,\n CronTriggerOptions,\n TemporalConfig,\n ClientConfig,\n WorkerConfig,\n StartWorkflowOptions,\n WorkflowHandle,\n TFNClient,\n TFNWorker,\n} from './types.js';\n\nexport default tfn;\n","/**\n * Temporal Functions - Worker Package\n *\n * Full worker implementation for executing functions and workflows.\n * Import from 'temporal-functions/worker'.\n */\n\nimport { Worker, NativeConnection } from '@temporalio/worker';\nimport type {\n WorkerConfig,\n FunctionDef,\n WorkflowDef,\n TFNWorker,\n} from '../types.js';\nimport { isFunction, isWorkflow } from '../index.js';\n\n// =============================================================================\n// Worker Implementation\n// =============================================================================\n\nclass TemporalFunctionsWorker implements TFNWorker {\n private config: WorkerConfig;\n private functions: Map<string, FunctionDef> = new Map();\n private workflows: Map<string, WorkflowDef> = new Map();\n private worker: Worker | null = null;\n private shutdownRequested = false;\n\n constructor(config: WorkerConfig) {\n this.config = {\n ...config,\n temporal: {\n namespace: 'default',\n ...config.temporal,\n },\n maxConcurrentActivities: config.maxConcurrentActivities ?? 100,\n maxConcurrentWorkflows: config.maxConcurrentWorkflows ?? 50,\n };\n }\n\n /**\n * Register a function or workflow\n */\n register(def: FunctionDef | WorkflowDef): void {\n if (isFunction(def)) {\n this.functions.set(def.name, def);\n } else if (isWorkflow(def)) {\n this.workflows.set(def.name, def);\n } else {\n throw new Error('Invalid definition: must be a function or workflow created with tfn.fn() or tfn.workflow()');\n }\n }\n\n /**\n * Register all exported functions and workflows from a module\n */\n registerModule(module: Record<string, unknown>): void {\n for (const [, value] of Object.entries(module)) {\n if (isFunction(value) || isWorkflow(value)) {\n this.register(value);\n }\n }\n }\n\n /**\n * Build activities object from registered functions\n */\n private buildActivities(): Record<string, (...args: unknown[]) => Promise<unknown>> {\n const activities: Record<string, (...args: unknown[]) => Promise<unknown>> = {};\n\n for (const [name, def] of this.functions) {\n activities[name] = async (input: unknown) => {\n return def.handler(input);\n };\n }\n\n return activities;\n }\n\n /**\n * Generate workflow wrapper code for Temporal\n *\n * This creates the workflow module that Temporal requires,\n * wrapping our user-defined workflow handlers with the proper\n * Temporal workflow context.\n */\n private generateWorkflowBundle(): string {\n const workflowNames = Array.from(this.workflows.keys());\n\n // Generate the workflow module code\n const code = `\n import { proxyActivities, sleep, workflowInfo, setHandler, defineSignal, defineQuery, condition, CancellationScope } from '@temporalio/workflow';\n\n // Proxy all activities\n const activities = proxyActivities({\n startToCloseTimeout: '1 minute',\n });\n\n // Create workflow context\n function createContext() {\n const signalHandlers = new Map();\n const queryHandlers = new Map();\n const signalPayloads = new Map();\n const signalReceived = new Map();\n\n return {\n run: async (fn, input, options = {}) => {\n const activity = activities[fn.name];\n if (!activity) {\n throw new Error(\\`Function \\${fn.name} not registered\\`);\n }\n return activity(input);\n },\n sleep: async (duration) => {\n if (typeof duration === 'string') {\n const ms = parseDuration(duration);\n return sleep(ms);\n }\n return sleep(duration);\n },\n now: () => new Date(),\n startChild: async (workflow, input, options = {}) => {\n throw new Error('startChild not yet implemented');\n },\n continueAsNew: async (input) => {\n throw new Error('continueAsNew not yet implemented');\n },\n onSignal: (signalName, handler) => {\n signalHandlers.set(signalName, handler);\n const signal = defineSignal(signalName);\n setHandler(signal, handler);\n },\n waitForSignal: async (signalName, options = {}) => {\n // Register signal handler if not already registered\n if (!signalReceived.has(signalName)) {\n signalReceived.set(signalName, false);\n signalPayloads.set(signalName, undefined);\n const signal = defineSignal(signalName);\n setHandler(signal, (payload) => {\n signalPayloads.set(signalName, payload);\n signalReceived.set(signalName, true);\n });\n }\n\n // Wait for signal with optional timeout\n const timeoutMs = options.timeout ? parseDuration(options.timeout) : undefined;\n const received = await condition(() => signalReceived.get(signalName), timeoutMs);\n\n if (!received) {\n throw new Error(\\`Timeout waiting for signal: \\${signalName}\\`);\n }\n\n // Reset for potential reuse\n const payload = signalPayloads.get(signalName);\n signalReceived.set(signalName, false);\n signalPayloads.set(signalName, undefined);\n\n return payload;\n },\n onQuery: (queryName, handler) => {\n queryHandlers.set(queryName, handler);\n const query = defineQuery(queryName);\n setHandler(query, handler);\n },\n get info() {\n const info = workflowInfo();\n return {\n workflowId: info.workflowId,\n runId: info.runId,\n taskQueue: info.taskQueue,\n workflowType: info.workflowType,\n namespace: info.namespace,\n };\n },\n };\n }\n\n // Parse duration string to milliseconds\n function parseDuration(duration) {\n const match = duration.match(/^(\\\\d+(?:\\\\.\\\\d+)?)(ms|s|m|h|d)$/);\n if (!match) {\n throw new Error(\\`Invalid duration: \\${duration}\\`);\n }\n const value = parseFloat(match[1]);\n const unit = match[2];\n switch (unit) {\n case 'ms': return value;\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: throw new Error(\\`Unknown duration unit: \\${unit}\\`);\n }\n }\n\n // Export workflow functions\n ${workflowNames.map((name) => `\n export async function ${name}(input) {\n const ctx = createContext();\n const handler = __workflowHandlers__.get('${name}');\n if (!handler) {\n throw new Error('Workflow handler not found: ${name}');\n }\n return handler(ctx, input);\n }\n `).join('\\n')}\n `;\n\n return code;\n }\n\n /**\n * Start the worker\n */\n async start(): Promise<void> {\n if (this.functions.size === 0 && this.workflows.size === 0) {\n throw new Error('No functions or workflows registered. Call register() before start().');\n }\n\n console.log(`Starting Temporal Functions worker...`);\n console.log(` Temporal: ${this.config.temporal.address}`);\n console.log(` Namespace: ${this.config.temporal.namespace}`);\n console.log(` Task Queue: ${this.config.taskQueue}`);\n console.log(` Functions: ${this.functions.size}`);\n console.log(` Workflows: ${this.workflows.size}`);\n\n // Connect to Temporal\n const connection = await NativeConnection.connect({\n address: this.config.temporal.address,\n tls: this.config.temporal.tls\n ? {\n clientCertPair: this.config.temporal.tls.clientCertPath\n ? {\n crt: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientCertPath!)\n ),\n key: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientKeyPath!)\n ),\n }\n : undefined,\n }\n : undefined,\n });\n\n // Build activities\n const activities = this.buildActivities();\n\n // For now, we'll use a simplified approach where workflows\n // are bundled separately. In a full implementation, we'd\n // generate the workflow bundle dynamically.\n //\n // TODO: Implement dynamic workflow bundling\n // const workflowBundle = this.generateWorkflowBundle();\n\n // Create worker\n this.worker = await Worker.create({\n connection,\n namespace: this.config.temporal.namespace,\n taskQueue: this.config.taskQueue,\n activities,\n // workflowsPath will need to be provided by the user\n // or we need to implement dynamic bundling\n maxConcurrentActivityTaskExecutions: this.config.maxConcurrentActivities,\n maxConcurrentWorkflowTaskExecutions: this.config.maxConcurrentWorkflows,\n });\n\n // Handle graceful shutdown\n const shutdown = async () => {\n if (this.shutdownRequested) return;\n this.shutdownRequested = true;\n console.log('\\nShutting down worker...');\n await this.shutdown();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n console.log('\\nWorker started. Press Ctrl+C to stop.\\n');\n\n // Run the worker (blocks until shutdown)\n await this.worker.run();\n }\n\n /**\n * Gracefully shutdown the worker\n */\n async shutdown(): Promise<void> {\n if (this.worker) {\n this.worker.shutdown();\n this.worker = null;\n }\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a Temporal Functions worker\n *\n * @example\n * ```typescript\n * import { tfn } from 'temporal-functions/worker';\n * import { validateOrder, processOrder } from './functions';\n *\n * const worker = tfn.worker({\n * temporal: {\n * address: 'localhost:7233',\n * namespace: 'default',\n * },\n * taskQueue: 'my-queue',\n * });\n *\n * worker.register(validateOrder);\n * worker.register(processOrder);\n *\n * await worker.start();\n * ```\n */\nfunction createWorker(config: WorkerConfig): TFNWorker {\n return new TemporalFunctionsWorker(config);\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n worker: createWorker,\n};\n\nexport { createWorker };\nexport type { WorkerConfig, TFNWorker };\nexport default tfn;\n"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/worker/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Temporal Functions - Main Entry Point\n *\n * This module provides the core API for defining functions and workflows.\n * Import from 'temporal-functions' for function/workflow definitions.\n * Import from 'temporal-functions/client' for triggering workflows.\n * Import from 'temporal-functions/worker' for running workers.\n */\n\nimport type {\n FunctionDef,\n FunctionOptions,\n WorkflowDef,\n WorkflowOptions,\n WorkflowHandler,\n Registry,\n HttpTriggerOptions,\n CronTriggerOptions,\n} from './types.js';\n\n// =============================================================================\n// Global Registry\n// =============================================================================\n\n/**\n * Global registry for all defined functions and workflows\n */\nexport const registry: Registry = {\n functions: new Map(),\n workflows: new Map(),\n};\n\n// =============================================================================\n// Function Definition\n// =============================================================================\n\n/**\n * Define a function (maps to a Temporal Activity)\n *\n * @example\n * ```typescript\n * export const sendEmail = tfn.fn(\n * 'sendEmail',\n * async (params: EmailParams) => {\n * return await emailService.send(params);\n * },\n * { timeout: '30s', retries: 3 }\n * );\n * ```\n */\nfunction fn<TInput, TOutput>(\n name: string,\n handler: (input: TInput) => Promise<TOutput>,\n options: FunctionOptions = {}\n): FunctionDef<TInput, TOutput> {\n const def: FunctionDef<TInput, TOutput> = {\n name,\n handler,\n options: {\n startToCloseTimeout: '1m',\n ...options,\n },\n __type: 'function',\n };\n\n registry.functions.set(name, def as FunctionDef);\n return def;\n}\n\n// =============================================================================\n// Workflow Definition\n// =============================================================================\n\n/**\n * Define a workflow\n *\n * @example\n * ```typescript\n * export const processOrder = tfn.workflow(\n * 'processOrder',\n * async (ctx, order: Order) => {\n * const validated = await ctx.run(validateOrder, order);\n * const paid = await ctx.run(chargePayment, validated);\n * return { orderId: paid.id, status: 'complete' };\n * }\n * );\n * ```\n */\nfunction workflow<TInput, TOutput>(\n name: string,\n handler: WorkflowHandler<TInput, TOutput>,\n options: WorkflowOptions = {}\n): WorkflowDef<TInput, TOutput> {\n const def: WorkflowDef<TInput, TOutput> = {\n name,\n handler,\n options: {\n taskQueue: 'default',\n ...options,\n },\n __type: 'workflow',\n };\n\n registry.workflows.set(name, def as WorkflowDef);\n return def;\n}\n\n// =============================================================================\n// Trigger Definitions (Declarative)\n// =============================================================================\n\ninterface HttpTriggerDef {\n type: 'http';\n method: string;\n path: string;\n workflow: WorkflowDef;\n options: HttpTriggerOptions;\n}\n\ninterface CronTriggerDef {\n type: 'cron';\n schedule: string;\n workflow: WorkflowDef;\n options: CronTriggerOptions;\n}\n\ninterface SignalTriggerDef {\n type: 'signal';\n signalName: string;\n handler: (payload: unknown) => void | Promise<void>;\n}\n\ntype TriggerDef = HttpTriggerDef | CronTriggerDef | SignalTriggerDef;\n\n/**\n * Registry for trigger definitions\n */\nexport const triggers: TriggerDef[] = [];\n\n/**\n * Define an HTTP trigger for a workflow\n *\n * @example\n * ```typescript\n * tfn.http('POST', '/api/orders', processOrder);\n * ```\n */\nfunction http<TInput, TOutput>(\n method: string,\n path: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: HttpTriggerOptions = {}\n): void {\n triggers.push({\n type: 'http',\n method: method.toUpperCase(),\n path,\n workflow: workflow as WorkflowDef,\n options,\n });\n}\n\n/**\n * Define a cron/scheduled trigger for a workflow\n *\n * @example\n * ```typescript\n * tfn.cron('0 9 * * *', dailyReport); // Every day at 9am\n * ```\n */\nfunction cron<TInput, TOutput>(\n schedule: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: CronTriggerOptions = {}\n): void {\n triggers.push({\n type: 'cron',\n schedule,\n workflow: workflow as WorkflowDef,\n options,\n });\n}\n\n/**\n * Define an interval trigger (convenience wrapper around cron)\n *\n * @example\n * ```typescript\n * tfn.interval('5m', healthCheck); // Every 5 minutes\n * ```\n */\nfunction interval<TInput, TOutput>(\n duration: string,\n workflow: WorkflowDef<TInput, TOutput>,\n options: CronTriggerOptions = {}\n): void {\n // Convert duration to cron expression\n const cronSchedule = durationToCron(duration);\n cron(cronSchedule, workflow, options);\n}\n\n/**\n * Define a signal trigger\n *\n * @example\n * ```typescript\n * tfn.signal('order.cancel', handleCancellation);\n * ```\n */\nfunction signal(\n signalName: string,\n handler: (payload: unknown) => void | Promise<void>\n): void {\n triggers.push({\n type: 'signal',\n signalName,\n handler,\n });\n}\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\n/**\n * Convert a duration string to a cron expression\n */\nfunction durationToCron(duration: string): string {\n const match = duration.match(/^(\\d+)(s|m|h|d)$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${duration}. Use format like '5m', '1h', '30s'`);\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case 's':\n if (value < 60) {\n return `*/${value} * * * * *`; // Every N seconds (non-standard)\n }\n throw new Error('Seconds interval must be less than 60');\n case 'm':\n return `*/${value} * * * *`; // Every N minutes\n case 'h':\n return `0 */${value} * * *`; // Every N hours\n case 'd':\n return `0 0 */${value} * *`; // Every N days\n default:\n throw new Error(`Unknown duration unit: ${unit}`);\n }\n}\n\n/**\n * Check if a definition is a function\n */\nexport function isFunction(def: unknown): def is FunctionDef {\n return (def as FunctionDef)?.__type === 'function';\n}\n\n/**\n * Check if a definition is a workflow\n */\nexport function isWorkflow(def: unknown): def is WorkflowDef {\n return (def as WorkflowDef)?.__type === 'workflow';\n}\n\n// =============================================================================\n// Main API Export\n// =============================================================================\n\n/**\n * The main Temporal Functions API\n */\nexport const tfn = {\n /** Define a function (activity) */\n fn,\n /** Define a workflow */\n workflow,\n /** Define an HTTP trigger */\n http,\n /** Define a cron trigger */\n cron,\n /** Define an interval trigger */\n interval,\n /** Define a signal trigger */\n signal,\n};\n\n// Re-export types\nexport type {\n FunctionDef,\n FunctionOptions,\n WorkflowDef,\n WorkflowOptions,\n WorkflowContext,\n WorkflowHandler,\n WorkflowInfo,\n RetryPolicy,\n HttpTriggerOptions,\n CronTriggerOptions,\n TemporalConfig,\n ClientConfig,\n WorkerConfig,\n StartWorkflowOptions,\n WorkflowHandle,\n TFNClient,\n TFNWorker,\n} from './types.js';\n\nexport default tfn;\n","/**\n * Temporal Functions - Worker Package\n *\n * Full worker implementation for executing functions and workflows.\n * Import from 'temporal-functions/worker'.\n */\n\nimport { Worker, NativeConnection } from '@temporalio/worker';\nimport type {\n WorkerConfig,\n FunctionDef,\n WorkflowDef,\n TFNWorker,\n} from '../types.js';\nimport { isFunction, isWorkflow } from '../index.js';\n\n// =============================================================================\n// Worker Implementation\n// =============================================================================\n\nclass TemporalFunctionsWorker implements TFNWorker {\n private config: WorkerConfig;\n private functions: Map<string, FunctionDef> = new Map();\n private workflows: Map<string, WorkflowDef> = new Map();\n private worker: Worker | null = null;\n private shutdownRequested = false;\n\n constructor(config: WorkerConfig) {\n this.config = {\n ...config,\n temporal: {\n namespace: 'default',\n ...config.temporal,\n },\n maxConcurrentActivities: config.maxConcurrentActivities ?? 100,\n maxConcurrentWorkflows: config.maxConcurrentWorkflows ?? 50,\n };\n }\n\n /**\n * Register a function or workflow\n */\n register(def: FunctionDef | WorkflowDef): void {\n if (isFunction(def)) {\n this.functions.set(def.name, def);\n } else if (isWorkflow(def)) {\n this.workflows.set(def.name, def);\n } else {\n throw new Error('Invalid definition: must be a function or workflow created with tfn.fn() or tfn.workflow()');\n }\n }\n\n /**\n * Register all exported functions and workflows from a module\n */\n registerModule(module: Record<string, unknown>): void {\n for (const [, value] of Object.entries(module)) {\n if (isFunction(value) || isWorkflow(value)) {\n this.register(value);\n }\n }\n }\n\n /**\n * Build activities object from registered functions\n */\n private buildActivities(): Record<string, (...args: unknown[]) => Promise<unknown>> {\n const activities: Record<string, (...args: unknown[]) => Promise<unknown>> = {};\n\n for (const [name, def] of this.functions) {\n activities[name] = async (input: unknown) => {\n return def.handler(input);\n };\n }\n\n return activities;\n }\n\n /**\n * Generate workflow wrapper code for Temporal\n *\n * This creates the workflow module that Temporal requires,\n * wrapping our user-defined workflow handlers with the proper\n * Temporal workflow context.\n */\n private generateWorkflowBundle(): string {\n const workflowNames = Array.from(this.workflows.keys());\n\n // Generate the workflow module code\n const code = `\n import { proxyActivities, sleep, workflowInfo, setHandler, defineSignal, defineQuery, condition, CancellationScope } from '@temporalio/workflow';\n\n // Proxy all activities\n const activities = proxyActivities({\n startToCloseTimeout: '1 minute',\n });\n\n // Create workflow context\n function createContext() {\n const signalHandlers = new Map();\n const queryHandlers = new Map();\n const signalPayloads = new Map();\n const signalReceived = new Map();\n\n return {\n run: async (fn, input, options = {}) => {\n const activity = activities[fn.name];\n if (!activity) {\n throw new Error(\\`Function \\${fn.name} not registered\\`);\n }\n return activity(input);\n },\n sleep: async (duration) => {\n if (typeof duration === 'string') {\n const ms = parseDuration(duration);\n return sleep(ms);\n }\n return sleep(duration);\n },\n now: () => new Date(),\n startChild: async (workflow, input, options = {}) => {\n throw new Error('startChild not yet implemented');\n },\n continueAsNew: async (input) => {\n throw new Error('continueAsNew not yet implemented');\n },\n onSignal: (signalName, handler) => {\n signalHandlers.set(signalName, handler);\n const signal = defineSignal(signalName);\n setHandler(signal, handler);\n },\n waitForSignal: async (signalName, options = {}) => {\n // Register signal handler if not already registered\n if (!signalReceived.has(signalName)) {\n signalReceived.set(signalName, false);\n signalPayloads.set(signalName, undefined);\n const signal = defineSignal(signalName);\n setHandler(signal, (payload) => {\n signalPayloads.set(signalName, payload);\n signalReceived.set(signalName, true);\n });\n }\n\n // Wait for signal with optional timeout\n const timeoutMs = options.timeout ? parseDuration(options.timeout) : undefined;\n const received = await condition(() => signalReceived.get(signalName), timeoutMs);\n\n if (!received) {\n throw new Error(\\`Timeout waiting for signal: \\${signalName}\\`);\n }\n\n // Reset for potential reuse\n const payload = signalPayloads.get(signalName);\n signalReceived.set(signalName, false);\n signalPayloads.set(signalName, undefined);\n\n return payload;\n },\n onQuery: (queryName, handler) => {\n queryHandlers.set(queryName, handler);\n const query = defineQuery(queryName);\n setHandler(query, handler);\n },\n get info() {\n const info = workflowInfo();\n return {\n workflowId: info.workflowId,\n runId: info.runId,\n taskQueue: info.taskQueue,\n workflowType: info.workflowType,\n namespace: info.namespace,\n };\n },\n };\n }\n\n // Parse duration string to milliseconds\n function parseDuration(duration) {\n const match = duration.match(/^(\\\\d+(?:\\\\.\\\\d+)?)(ms|s|m|h|d)$/);\n if (!match) {\n throw new Error(\\`Invalid duration: \\${duration}\\`);\n }\n const value = parseFloat(match[1]);\n const unit = match[2];\n switch (unit) {\n case 'ms': return value;\n case 's': return value * 1000;\n case 'm': return value * 60 * 1000;\n case 'h': return value * 60 * 60 * 1000;\n case 'd': return value * 24 * 60 * 60 * 1000;\n default: throw new Error(\\`Unknown duration unit: \\${unit}\\`);\n }\n }\n\n // Export workflow functions\n ${workflowNames.map((name) => `\n export async function ${name}(input) {\n const ctx = createContext();\n const handler = __workflowHandlers__.get('${name}');\n if (!handler) {\n throw new Error('Workflow handler not found: ${name}');\n }\n return handler(ctx, input);\n }\n `).join('\\n')}\n `;\n\n return code;\n }\n\n /**\n * Start the worker\n */\n async start(): Promise<void> {\n // Allow starting with external workflowsPath and activities\n const hasRegisteredFunctions = this.functions.size > 0 || this.workflows.size > 0;\n const hasExternalConfig = this.config.workflowsPath || this.config.activities;\n\n if (!hasRegisteredFunctions && !hasExternalConfig) {\n throw new Error('No functions, workflows, or external config provided. Either call register() or provide workflowsPath/activities.');\n }\n\n console.log(`Starting Temporal Functions worker...`);\n console.log(` Temporal: ${this.config.temporal.address}`);\n console.log(` Namespace: ${this.config.temporal.namespace}`);\n console.log(` Task Queue: ${this.config.taskQueue}`);\n if (this.config.workflowsPath) {\n console.log(` Workflows Path: ${this.config.workflowsPath}`);\n }\n if (hasRegisteredFunctions) {\n console.log(` Registered Functions: ${this.functions.size}`);\n console.log(` Registered Workflows: ${this.workflows.size}`);\n }\n\n // Connect to Temporal\n const connection = await NativeConnection.connect({\n address: this.config.temporal.address,\n tls: this.config.temporal.tls\n ? {\n clientCertPair: this.config.temporal.tls.clientCertPath\n ? {\n crt: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientCertPath!)\n ),\n key: await import('fs').then((fs) =>\n fs.promises.readFile(this.config.temporal.tls!.clientKeyPath!)\n ),\n }\n : undefined,\n }\n : undefined,\n });\n\n // Build activities - merge registered functions with external activities\n const registeredActivities = this.buildActivities();\n const activities = {\n ...registeredActivities,\n ...this.config.activities,\n };\n\n // Build worker options\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const workerOptions: any = {\n connection,\n namespace: this.config.temporal.namespace,\n taskQueue: this.config.taskQueue,\n activities: Object.keys(activities).length > 0 ? activities : undefined,\n maxConcurrentActivityTaskExecutions: this.config.maxConcurrentActivities,\n maxConcurrentWorkflowTaskExecutions: this.config.maxConcurrentWorkflows,\n };\n\n // Add workflowsPath if provided (for external workflow files)\n if (this.config.workflowsPath) {\n workerOptions.workflowsPath = this.config.workflowsPath;\n }\n\n // Add interceptors if provided\n if (this.config.interceptors) {\n workerOptions.interceptors = {};\n\n if (this.config.interceptors.activityInbound) {\n workerOptions.interceptors.activityInbound = this.config.interceptors.activityInbound;\n }\n\n if (this.config.interceptors.workflowModules) {\n workerOptions.interceptors.workflowModules = this.config.interceptors.workflowModules;\n }\n }\n\n // Create worker\n this.worker = await Worker.create(workerOptions);\n\n // Handle graceful shutdown\n const shutdown = async () => {\n if (this.shutdownRequested) return;\n this.shutdownRequested = true;\n console.log('\\nShutting down worker...');\n await this.shutdown();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n console.log('\\nWorker started. Press Ctrl+C to stop.\\n');\n\n // Run the worker (blocks until shutdown)\n await this.worker.run();\n }\n\n /**\n * Gracefully shutdown the worker\n */\n async shutdown(): Promise<void> {\n if (this.worker) {\n this.worker.shutdown();\n this.worker = null;\n }\n }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a Temporal Functions worker\n *\n * @example\n * ```typescript\n * // Option 1: Using registered functions (tfn pattern)\n * import { tfn } from 'temporal-functions/worker';\n * import { validateOrder, processOrder } from './functions';\n *\n * const worker = tfn.worker({\n * temporal: { address: 'localhost:7233', namespace: 'default' },\n * taskQueue: 'my-queue',\n * });\n *\n * worker.register(validateOrder);\n * worker.register(processOrder);\n * await worker.start();\n * ```\n *\n * @example\n * ```typescript\n * // Option 2: Using external workflowsPath and activities (processor pattern)\n * import { createWorker } from '@astami/temporal-functions/worker';\n * import { createWorkerInterceptors } from '@astami/temporal-functions/observability';\n * import * as activities from './activities';\n *\n * const worker = createWorker({\n * temporal: { address: 'localhost:7233', namespace: 'loop' },\n * taskQueue: 'stripe-payments',\n * workflowsPath: './dist/workflows/index.js',\n * activities,\n * interceptors: createWorkerInterceptors({ serviceName: 'stripe' }),\n * });\n *\n * await worker.start();\n * ```\n */\nfunction createWorker(config: WorkerConfig): TFNWorker {\n return new TemporalFunctionsWorker(config);\n}\n\n// =============================================================================\n// Export\n// =============================================================================\n\nexport const tfn = {\n worker: createWorker,\n};\n\nexport { createWorker };\nexport type { WorkerConfig, TFNWorker };\nexport default tfn;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astami/temporal-functions",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "A lightweight TypeScript framework providing lambda-like DX on top of Temporal's durable execution engine",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -25,6 +25,11 @@
25
25
  "types": "./dist/testing/index.d.ts",
26
26
  "import": "./dist/testing/index.mjs",
27
27
  "require": "./dist/testing/index.js"
28
+ },
29
+ "./observability": {
30
+ "types": "./dist/observability/index.d.ts",
31
+ "import": "./dist/observability/index.mjs",
32
+ "require": "./dist/observability/index.js"
28
33
  }
29
34
  },
30
35
  "files": [
@@ -64,7 +69,9 @@
64
69
  "peerDependencies": {
65
70
  "@temporalio/client": "^1.9.0",
66
71
  "@temporalio/worker": "^1.9.0",
67
- "@temporalio/workflow": "^1.9.0"
72
+ "@temporalio/workflow": "^1.9.0",
73
+ "@temporalio/interceptors-opentelemetry": "^1.9.0",
74
+ "@opentelemetry/api": "^1.0.0"
68
75
  },
69
76
  "peerDependenciesMeta": {
70
77
  "@temporalio/worker": {
@@ -72,6 +79,12 @@
72
79
  },
73
80
  "@temporalio/workflow": {
74
81
  "optional": true
82
+ },
83
+ "@temporalio/interceptors-opentelemetry": {
84
+ "optional": true
85
+ },
86
+ "@opentelemetry/api": {
87
+ "optional": true
75
88
  }
76
89
  },
77
90
  "devDependencies": {
@@ -79,6 +92,8 @@
79
92
  "@temporalio/worker": "^1.11.7",
80
93
  "@temporalio/workflow": "^1.11.7",
81
94
  "@temporalio/activity": "^1.11.7",
95
+ "@temporalio/interceptors-opentelemetry": "^1.11.7",
96
+ "@opentelemetry/api": "^1.9.0",
82
97
  "@types/node": "^20.11.0",
83
98
  "tsup": "^8.0.1",
84
99
  "typescript": "^5.3.3",