@temporalio/lambda-worker 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makePowertoolsLogger = makePowertoolsLogger;
4
+ const json_logger_1 = require("./json-logger");
5
+ /**
6
+ * Create a Powertools-based logger for the Lambda worker.
7
+ *
8
+ * If `@aws-lambda-powertools/logger` is installed, returns a
9
+ * {@link PowertoolsLoggerAdapter} wrapping a Powertools Logger.
10
+ * Otherwise, returns `undefined`, causing the Runtime to fall back
11
+ * to its default logger.
12
+ */
13
+ function makePowertoolsLogger() {
14
+ try {
15
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
16
+ const { Logger: PtLogger } = require('@aws-lambda-powertools/logger');
17
+ return new json_logger_1.PowertoolsLoggerAdapter(new PtLogger({
18
+ serviceName: process.env['AWS_LAMBDA_FUNCTION_NAME'] ?? 'temporal-lambda-worker',
19
+ }));
20
+ }
21
+ catch (err) {
22
+ if (err.code !== 'MODULE_NOT_FOUND') {
23
+ throw err;
24
+ }
25
+ return undefined;
26
+ }
27
+ }
28
+ //# sourceMappingURL=logger-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-factory.js","sourceRoot":"","sources":["../src/logger-factory.ts"],"names":[],"mappings":";;AAWA,oDAeC;AAzBD,+CAAwD;AAExD;;;;;;;GAOG;AACH,SAAgB,oBAAoB;IAClC,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;QACtE,OAAO,IAAI,qCAAuB,CAChC,IAAI,QAAQ,CAAC;YACX,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,IAAI,wBAAwB;SACjF,CAAC,CACH,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YAC/D,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
package/lib/otel.d.ts ADDED
@@ -0,0 +1,83 @@
1
+ import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
2
+ import { OpenTelemetryPlugin } from '@temporalio/interceptors-opentelemetry';
3
+ import type { LambdaWorkerConfig } from './types';
4
+ /**
5
+ * Options for the batteries-included OTel setup.
6
+ */
7
+ export interface OtelOptions {
8
+ /**
9
+ * OTLP gRPC collector endpoint for Core SDK metrics and SDK trace span export.
10
+ * Defaults to `OTEL_EXPORTER_OTLP_ENDPOINT` env var, then `grpc://localhost:4317`.
11
+ */
12
+ endpoint?: string;
13
+ /**
14
+ * OTel service name. Falls back to `OTEL_SERVICE_NAME` env var,
15
+ * then `AWS_LAMBDA_FUNCTION_NAME`, then `'temporal-lambda-worker'`.
16
+ */
17
+ serviceName?: string;
18
+ }
19
+ /**
20
+ * Configure OpenTelemetry for a Lambda worker:
21
+ *
22
+ * - Registers Temporal SDK interceptors (`@temporalio/interceptors-opentelemetry`) for
23
+ * tracing Workflow, Activity, and Nexus calls via the `OpenTelemetryPlugin`.
24
+ * - Configures Core-side telemetry so the Temporal Rust SDK exports its own metrics
25
+ * (workflow/activity task latencies, poll counts, etc.) via OTLP.
26
+ *
27
+ * Node.js-side Lambda auto-instrumentation (root spans, HTTP calls, etc.) is handled
28
+ * by the ADOT JS Lambda layer — this function does not set up a separate `NodeSDK` or
29
+ * `TracerProvider` to avoid conflicting with the layer.
30
+ *
31
+ * **Required AWS setup**: attach both Lambda layers:
32
+ *
33
+ * 1. [ADOT JavaScript layer](https://aws-otel.github.io/docs/getting-started/lambda/lambda-js)
34
+ * — auto-instruments the handler and exports Node.js-side traces.
35
+ * 2. [ADOT Collector layer](https://aws-otel.github.io/docs/getting-started/lambda)
36
+ * (`aws-otel-collector-amd64`) — runs the OTel Collector as a Lambda extension,
37
+ * receiving Core SDK metrics via OTLP on `localhost:4317` and forwarding them to
38
+ * CloudWatch/X-Ray.
39
+ *
40
+ * Then set these environment variables:
41
+ *
42
+ * - `AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument`
43
+ * - `OPENTELEMETRY_COLLECTOR_CONFIG_URI=/var/task/otel-collector-config.yaml`
44
+ *
45
+ * **Important**: When pre-bundling Workflow code with `bundleWorkflowCode()`, you must
46
+ * pass `makeOtelPlugin()` so Workflow interceptor modules are included in the bundle.
47
+ * See {@link makeOtelPlugin}.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * import { runWorker } from '@temporalio/lambda-worker';
52
+ * import { applyDefaults } from '@temporalio/lambda-worker/otel';
53
+ *
54
+ * export const handler = runWorker(version, (config) => {
55
+ * applyDefaults(config);
56
+ * config.workerOptions.taskQueue = 'my-queue';
57
+ * // ...
58
+ * });
59
+ * ```
60
+ */
61
+ export declare function applyDefaults(config: LambdaWorkerConfig, options?: OtelOptions): void;
62
+ /**
63
+ * Create the OpenTelemetry plugin for use with `Worker.create()` and
64
+ * `bundleWorkflowCode()`. When pre-bundling workflows, pass the returned plugin
65
+ * to `bundleWorkflowCode({ plugins: [plugin] })` so workflow interceptor modules
66
+ * are included in the bundle.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import { bundleWorkflowCode } from '@temporalio/worker';
71
+ * import { makeOtelPlugin } from '@temporalio/lambda-worker/otel';
72
+ *
73
+ * const { plugin } = makeOtelPlugin();
74
+ * const bundle = await bundleWorkflowCode({
75
+ * workflowsPath: require.resolve('./workflows'),
76
+ * plugins: [plugin],
77
+ * });
78
+ * ```
79
+ */
80
+ export declare function makeOtelPlugin(endpoint?: string, serviceName?: string): {
81
+ plugin: OpenTelemetryPlugin;
82
+ spanProcessor: SimpleSpanProcessor;
83
+ };
package/lib/otel.js ADDED
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyDefaults = applyDefaults;
4
+ exports.makeOtelPlugin = makeOtelPlugin;
5
+ const exporter_trace_otlp_grpc_1 = require("@opentelemetry/exporter-trace-otlp-grpc");
6
+ const resources_1 = require("@opentelemetry/resources");
7
+ const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
8
+ const interceptors_opentelemetry_1 = require("@temporalio/interceptors-opentelemetry");
9
+ /**
10
+ * Configure OpenTelemetry for a Lambda worker:
11
+ *
12
+ * - Registers Temporal SDK interceptors (`@temporalio/interceptors-opentelemetry`) for
13
+ * tracing Workflow, Activity, and Nexus calls via the `OpenTelemetryPlugin`.
14
+ * - Configures Core-side telemetry so the Temporal Rust SDK exports its own metrics
15
+ * (workflow/activity task latencies, poll counts, etc.) via OTLP.
16
+ *
17
+ * Node.js-side Lambda auto-instrumentation (root spans, HTTP calls, etc.) is handled
18
+ * by the ADOT JS Lambda layer — this function does not set up a separate `NodeSDK` or
19
+ * `TracerProvider` to avoid conflicting with the layer.
20
+ *
21
+ * **Required AWS setup**: attach both Lambda layers:
22
+ *
23
+ * 1. [ADOT JavaScript layer](https://aws-otel.github.io/docs/getting-started/lambda/lambda-js)
24
+ * — auto-instruments the handler and exports Node.js-side traces.
25
+ * 2. [ADOT Collector layer](https://aws-otel.github.io/docs/getting-started/lambda)
26
+ * (`aws-otel-collector-amd64`) — runs the OTel Collector as a Lambda extension,
27
+ * receiving Core SDK metrics via OTLP on `localhost:4317` and forwarding them to
28
+ * CloudWatch/X-Ray.
29
+ *
30
+ * Then set these environment variables:
31
+ *
32
+ * - `AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument`
33
+ * - `OPENTELEMETRY_COLLECTOR_CONFIG_URI=/var/task/otel-collector-config.yaml`
34
+ *
35
+ * **Important**: When pre-bundling Workflow code with `bundleWorkflowCode()`, you must
36
+ * pass `makeOtelPlugin()` so Workflow interceptor modules are included in the bundle.
37
+ * See {@link makeOtelPlugin}.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { runWorker } from '@temporalio/lambda-worker';
42
+ * import { applyDefaults } from '@temporalio/lambda-worker/otel';
43
+ *
44
+ * export const handler = runWorker(version, (config) => {
45
+ * applyDefaults(config);
46
+ * config.workerOptions.taskQueue = 'my-queue';
47
+ * // ...
48
+ * });
49
+ * ```
50
+ */
51
+ function applyDefaults(config, options) {
52
+ const endpoint = options?.endpoint ?? process.env['OTEL_EXPORTER_OTLP_ENDPOINT'] ?? 'grpc://localhost:4317';
53
+ // Configure Core-side telemetry so the Temporal Rust SDK exports its own
54
+ // metrics (workflow/activity task latencies, poll counts, etc.) to the
55
+ // standalone ADOT collector extension running as a Lambda layer.
56
+ config.runtimeOptions.telemetryOptions = {
57
+ ...config.runtimeOptions.telemetryOptions,
58
+ metrics: {
59
+ otel: {
60
+ url: endpoint,
61
+ },
62
+ },
63
+ };
64
+ // Set up the OpenTelemetry plugin for Temporal SDK interceptors.
65
+ // This traces Workflow, Activity, and Nexus calls.
66
+ const { plugin, spanProcessor } = makeOtelPlugin(endpoint, options?.serviceName);
67
+ config.workerOptions.plugins = [...(config.workerOptions.plugins ?? []), plugin];
68
+ config.shutdownHooks.push(async () => {
69
+ await spanProcessor.forceFlush();
70
+ });
71
+ }
72
+ // TODO: Spans don't automatically get parented to the lambda invocation span, and it's not clear
73
+ // how we'd make that work, but is worth doing in the future if possible.
74
+ /**
75
+ * Create the OpenTelemetry plugin for use with `Worker.create()` and
76
+ * `bundleWorkflowCode()`. When pre-bundling workflows, pass the returned plugin
77
+ * to `bundleWorkflowCode({ plugins: [plugin] })` so workflow interceptor modules
78
+ * are included in the bundle.
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * import { bundleWorkflowCode } from '@temporalio/worker';
83
+ * import { makeOtelPlugin } from '@temporalio/lambda-worker/otel';
84
+ *
85
+ * const { plugin } = makeOtelPlugin();
86
+ * const bundle = await bundleWorkflowCode({
87
+ * workflowsPath: require.resolve('./workflows'),
88
+ * plugins: [plugin],
89
+ * });
90
+ * ```
91
+ */
92
+ function makeOtelPlugin(endpoint, serviceName) {
93
+ const resolvedEndpoint = endpoint ?? process.env['OTEL_EXPORTER_OTLP_ENDPOINT'] ?? 'grpc://localhost:4317';
94
+ const resolvedServiceName = serviceName ??
95
+ process.env['OTEL_SERVICE_NAME'] ??
96
+ process.env['AWS_LAMBDA_FUNCTION_NAME'] ??
97
+ 'temporal-lambda-worker';
98
+ const resource = new resources_1.Resource({ 'service.name': resolvedServiceName });
99
+ const traceExporter = new exporter_trace_otlp_grpc_1.OTLPTraceExporter({ url: resolvedEndpoint });
100
+ const spanProcessor = new sdk_trace_base_1.SimpleSpanProcessor(traceExporter);
101
+ return { plugin: new interceptors_opentelemetry_1.OpenTelemetryPlugin({ resource, spanProcessor }), spanProcessor };
102
+ }
103
+ //# sourceMappingURL=otel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.js","sourceRoot":"","sources":["../src/otel.ts"],"names":[],"mappings":";;AAiEA,sCAuBC;AAsBD,wCAgBC;AA9HD,sFAA4E;AAC5E,wDAAoD;AACpD,kEAAoE;AACpE,uFAA6E;AAoB7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,SAAgB,aAAa,CAAC,MAA0B,EAAE,OAAqB;IAC7E,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,IAAI,uBAAuB,CAAC;IAE5G,yEAAyE;IACzE,uEAAuE;IACvE,iEAAiE;IACjE,MAAM,CAAC,cAAc,CAAC,gBAAgB,GAAG;QACvC,GAAG,MAAM,CAAC,cAAc,CAAC,gBAAgB;QACzC,OAAO,EAAE;YACP,IAAI,EAAE;gBACJ,GAAG,EAAE,QAAQ;aACd;SACF;KACF,CAAC;IAEF,iEAAiE;IACjE,mDAAmD;IACnD,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IACjF,MAAM,CAAC,aAAa,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IAEjF,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QACnC,MAAM,aAAa,CAAC,UAAU,EAAE,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,iGAAiG;AACjG,yEAAyE;AACzE;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,cAAc,CAC5B,QAAiB,EACjB,WAAoB;IAEpB,MAAM,gBAAgB,GAAG,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,IAAI,uBAAuB,CAAC;IAC3G,MAAM,mBAAmB,GACvB,WAAW;QACX,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;QACvC,wBAAwB,CAAC;IAE3B,MAAM,QAAQ,GAAG,IAAI,oBAAQ,CAAC,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAC,CAAC;IACvE,MAAM,aAAa,GAAG,IAAI,4CAAiB,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACvE,MAAM,aAAa,GAAG,IAAI,oCAAmB,CAAC,aAAa,CAAC,CAAC;IAE7D,OAAO,EAAE,MAAM,EAAE,IAAI,gDAAmB,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC;AACzF,CAAC"}
package/lib/types.d.ts ADDED
@@ -0,0 +1,70 @@
1
+ import type { Context } from 'aws-lambda';
2
+ import type { VersioningBehavior } from '@temporalio/common';
3
+ import type { WorkerOptions, NativeConnectionOptions, RuntimeOptions } from '@temporalio/worker';
4
+ /**
5
+ * A function called after the worker stops on each invocation.
6
+ * Errors are caught, logged, and do not prevent subsequent hooks from running.
7
+ */
8
+ export type ShutdownHook = () => Promise<void> | void;
9
+ /**
10
+ * Configuration object passed to the {@link runWorker} configure callback.
11
+ *
12
+ * Pre-populated with Lambda-tuned defaults. You should set `workerOptions.taskQueue`, register
13
+ * activities/workflows, and override any defaults as needed.
14
+ */
15
+ export interface LambdaWorkerConfig {
16
+ /**
17
+ * Worker options, pre-populated with Lambda-appropriate defaults.
18
+ *
19
+ * You must set at least `taskQueue` (or set the `TEMPORAL_TASK_QUEUE` env var). Typically you'll
20
+ * also set `activities` and `workflowBundle` (prefer pre-bundled workflows over `workflowsPath`
21
+ * to avoid bundling overhead on Lambda cold starts).
22
+ *
23
+ * The following fields are managed by settings elsewhere and will be overridden per-invocation:
24
+ * `connection`, `namespace`, `identity`.
25
+ */
26
+ workerOptions: Partial<Omit<WorkerOptions, 'connection' | 'namespace' | 'identity' | 'workerDeploymentOptions'>> & {
27
+ /**
28
+ * `version` and `useWorkerVersioning` are managed by `runWorker` and cannot be set here.
29
+ *
30
+ * @default { defaultVersioningBehavior: 'PINNED' }
31
+ */
32
+ workerDeploymentOptions?: {
33
+ defaultVersioningBehavior?: VersioningBehavior;
34
+ };
35
+ };
36
+ /**
37
+ * Connection options overrides, merged on top of values loaded via envconfig.
38
+ */
39
+ connectionOptions?: Partial<NativeConnectionOptions>;
40
+ /**
41
+ * Namespace override. Falls back to the envconfig-loaded value, then `"default"`.
42
+ */
43
+ namespace?: string;
44
+ /**
45
+ * Time in milliseconds before the Lambda invocation deadline at which the worker
46
+ * begins its shutdown sequence (graceful drain + shutdown hooks).
47
+ *
48
+ * @default 7000 (5s graceful shutdown + 2s margin)
49
+ */
50
+ shutdownDeadlineBufferMs?: number;
51
+ /**
52
+ * Options for the Temporal {@link Runtime} singleton, installed automatically by `runWorker`.
53
+ *
54
+ * Pre-populated with a Powertools JSON logger (if `@aws-lambda-powertools/logger` is installed)
55
+ * and `shutdownSignals: []` (Lambda manages its own lifecycle).
56
+ *
57
+ * Override `runtimeOptions.logger` to use a custom logger, or modify `runtimeOptions.telemetryOptions`
58
+ * to configure Core-side telemetry.
59
+ */
60
+ runtimeOptions: RuntimeOptions;
61
+ /**
62
+ * Hooks executed in order after the worker stops on each invocation.
63
+ * Each hook's errors are caught and logged without preventing subsequent hooks.
64
+ */
65
+ shutdownHooks: ShutdownHook[];
66
+ }
67
+ /**
68
+ * The Lambda handler function returned by {@link runWorker}.
69
+ */
70
+ export type LambdaHandler = (event: unknown, context: Context) => Promise<void>;
package/lib/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,86 @@
1
+ {
2
+ "name": "@temporalio/lambda-worker",
3
+ "version": "1.17.0",
4
+ "description": "Temporal.io SDK AWS Lambda Worker",
5
+ "main": "lib/index.js",
6
+ "types": "./lib/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./lib/index.d.ts",
10
+ "default": "./lib/index.js"
11
+ },
12
+ "./otel": {
13
+ "types": "./lib/otel.d.ts",
14
+ "default": "./lib/otel.js"
15
+ },
16
+ "./lib/*": {
17
+ "types": "./lib/*.d.ts",
18
+ "default": "./lib/*.js"
19
+ }
20
+ },
21
+ "keywords": [
22
+ "temporal",
23
+ "aws",
24
+ "lambda",
25
+ "worker"
26
+ ],
27
+ "author": "Temporal Technologies Inc. <sdk@temporal.io>",
28
+ "license": "MIT",
29
+ "dependencies": {
30
+ "@temporalio/common": "1.17.0",
31
+ "@temporalio/envconfig": "1.17.0",
32
+ "@temporalio/worker": "1.17.0"
33
+ },
34
+ "devDependencies": {
35
+ "@aws-lambda-powertools/logger": "^2.0.0",
36
+ "@types/aws-lambda": "^8.10.145"
37
+ },
38
+ "peerDependencies": {
39
+ "@aws-lambda-powertools/logger": "^2.0.0",
40
+ "@opentelemetry/exporter-trace-otlp-grpc": "^0.52.0",
41
+ "@opentelemetry/resources": "^1.25.1",
42
+ "@opentelemetry/sdk-trace-base": "^1.25.1",
43
+ "@types/aws-lambda": "^8.10.145",
44
+ "@temporalio/interceptors-opentelemetry": "1.17.0"
45
+ },
46
+ "peerDependenciesMeta": {
47
+ "@aws-lambda-powertools/logger": {
48
+ "optional": true
49
+ },
50
+ "@temporalio/interceptors-opentelemetry": {
51
+ "optional": true
52
+ },
53
+ "@opentelemetry/exporter-trace-otlp-grpc": {
54
+ "optional": true
55
+ },
56
+ "@opentelemetry/resources": {
57
+ "optional": true
58
+ },
59
+ "@opentelemetry/sdk-trace-base": {
60
+ "optional": true
61
+ },
62
+ "@types/aws-lambda": {
63
+ "optional": true
64
+ }
65
+ },
66
+ "engines": {
67
+ "node": ">= 20.0.0"
68
+ },
69
+ "bugs": {
70
+ "url": "https://github.com/temporalio/sdk-typescript/issues"
71
+ },
72
+ "repository": {
73
+ "type": "git",
74
+ "url": "git+https://github.com/temporalio/sdk-typescript.git",
75
+ "directory": "packages/lambda-worker"
76
+ },
77
+ "homepage": "https://github.com/temporalio/sdk-typescript/tree/main/packages/lambda-worker",
78
+ "publishConfig": {
79
+ "access": "public"
80
+ },
81
+ "files": [
82
+ "src",
83
+ "lib"
84
+ ],
85
+ "scripts": {}
86
+ }
package/src/config.ts ADDED
@@ -0,0 +1,53 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import {
4
+ type ClientConnectConfig,
5
+ type LoadClientProfileOptions,
6
+ loadClientConnectConfig,
7
+ } from '@temporalio/envconfig';
8
+
9
+ /**
10
+ * Load client connection config with Lambda-aware config file resolution.
11
+ *
12
+ * Resolution order:
13
+ * 1. User-provided `configSource` in options (passthrough)
14
+ * 2. `TEMPORAL_CONFIG_FILE` env var (handled by envconfig)
15
+ * 3. `$LAMBDA_TASK_ROOT/temporal.toml`
16
+ * 4. `process.cwd()/temporal.toml`
17
+ * 5. Envconfig default (XDG paths / env-only)
18
+ */
19
+ export function loadLambdaClientConnectConfig(options?: Partial<LoadClientProfileOptions>): ClientConnectConfig {
20
+ const resolvedOptions: LoadClientProfileOptions = { ...options };
21
+
22
+ // If the user provided a configSource or TEMPORAL_CONFIG_FILE is set, let envconfig handle it
23
+ if (!resolvedOptions.configSource && !process.env['TEMPORAL_CONFIG_FILE']) {
24
+ const lambdaConfigPath = findLambdaConfigFile();
25
+ if (lambdaConfigPath) {
26
+ resolvedOptions.configSource = { path: lambdaConfigPath };
27
+ }
28
+ }
29
+
30
+ return loadClientConnectConfig(resolvedOptions);
31
+ }
32
+
33
+ function findLambdaConfigFile(): string | undefined {
34
+ const candidates: string[] = [];
35
+
36
+ const lambdaTaskRoot = process.env['LAMBDA_TASK_ROOT'];
37
+ if (lambdaTaskRoot) {
38
+ candidates.push(path.join(lambdaTaskRoot, 'temporal.toml'));
39
+ }
40
+
41
+ candidates.push(path.join(process.cwd(), 'temporal.toml'));
42
+
43
+ for (const candidate of candidates) {
44
+ try {
45
+ fs.accessSync(candidate, fs.constants.R_OK);
46
+ return candidate;
47
+ } catch {
48
+ // File doesn't exist or isn't readable, try next
49
+ }
50
+ }
51
+
52
+ return undefined;
53
+ }
@@ -0,0 +1,30 @@
1
+ import type { WorkerOptions } from '@temporalio/worker';
2
+
3
+ /** Minimum work time in ms — error if less. */
4
+ export const MINIMUM_WORK_TIME_MS = 1000;
5
+
6
+ /** Low work time threshold in ms — warn if less. */
7
+ export const WARN_WORK_TIME_MS = 5000;
8
+
9
+ /**
10
+ * Default buffer in ms before the Lambda deadline to begin shutdown.
11
+ * Equals the default shutdownGraceTime (5s) + 2s margin.
12
+ */
13
+ export const DEFAULT_SHUTDOWN_DEADLINE_BUFFER_MS = 7000;
14
+
15
+ /**
16
+ * Lambda-tuned worker defaults. These are conservative values appropriate for
17
+ * Lambda's memory and CPU constraints. Users can override any of these via the
18
+ * configure callback.
19
+ */
20
+ export const LAMBDA_WORKER_DEFAULTS: Partial<WorkerOptions> = {
21
+ maxConcurrentActivityTaskExecutions: 2,
22
+ maxConcurrentWorkflowTaskExecutions: 10,
23
+ maxConcurrentLocalActivityExecutions: 2,
24
+ maxConcurrentNexusTaskExecutions: 5,
25
+ shutdownGraceTime: '5s',
26
+ maxCachedWorkflows: 30,
27
+ workflowTaskPollerBehavior: { type: 'simple-maximum', maximum: 2 },
28
+ activityTaskPollerBehavior: { type: 'simple-maximum', maximum: 1 },
29
+ nexusTaskPollerBehavior: { type: 'simple-maximum', maximum: 1 },
30
+ };
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { runWorker } from './lambda-worker';
2
+ export { PowertoolsLoggerAdapter } from './json-logger';
3
+ export type { LambdaWorkerConfig, LambdaHandler, ShutdownHook } from './types';
@@ -0,0 +1,69 @@
1
+ import type { Logger as PowertoolsLogger } from '@aws-lambda-powertools/logger';
2
+ import type { Context } from 'aws-lambda';
3
+ import type { LogLevel, LogMetadata } from '@temporalio/common';
4
+ import type { Logger } from '@temporalio/worker';
5
+
6
+ /**
7
+ * Adapter that wraps an AWS Lambda Powertools Logger to implement the Temporal SDK Logger interface.
8
+ *
9
+ * This is used as the default logger for the Lambda worker, producing structured JSON output
10
+ * that CloudWatch Logs automatically parses.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { Logger } from '@aws-lambda-powertools/logger';
15
+ * import { PowertoolsLoggerAdapter } from '@temporalio/lambda-worker';
16
+ *
17
+ * const adapter = new PowertoolsLoggerAdapter(new Logger({ serviceName: 'my-worker' }));
18
+ * ```
19
+ */
20
+ export class PowertoolsLoggerAdapter implements Logger {
21
+ constructor(private readonly ptLogger: PowertoolsLogger) {}
22
+
23
+ addContext(context: Context): void {
24
+ this.ptLogger.addContext(context);
25
+ }
26
+
27
+ log(level: LogLevel, message: string, meta?: LogMetadata): void {
28
+ switch (level) {
29
+ case 'TRACE':
30
+ this.ptLogger.debug(message, { ...meta, traceLevel: true });
31
+ break;
32
+ case 'DEBUG':
33
+ this.ptLogger.debug(message, meta as Record<string, unknown>);
34
+ break;
35
+ case 'INFO':
36
+ this.ptLogger.info(message, meta as Record<string, unknown>);
37
+ break;
38
+ case 'WARN':
39
+ this.ptLogger.warn(message, meta as Record<string, unknown>);
40
+ break;
41
+ case 'ERROR':
42
+ this.ptLogger.error(message, meta as Record<string, unknown>);
43
+ break;
44
+ default:
45
+ level satisfies never;
46
+ break;
47
+ }
48
+ }
49
+
50
+ trace(message: string, meta?: LogMetadata): void {
51
+ this.log('TRACE', message, meta);
52
+ }
53
+
54
+ debug(message: string, meta?: LogMetadata): void {
55
+ this.log('DEBUG', message, meta);
56
+ }
57
+
58
+ info(message: string, meta?: LogMetadata): void {
59
+ this.log('INFO', message, meta);
60
+ }
61
+
62
+ warn(message: string, meta?: LogMetadata): void {
63
+ this.log('WARN', message, meta);
64
+ }
65
+
66
+ error(message: string, meta?: LogMetadata): void {
67
+ this.log('ERROR', message, meta);
68
+ }
69
+ }