inngest 3.48.0 → 3.48.2-pr-1209.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # inngest
2
2
 
3
+ ## 3.48.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1205](https://github.com/inngest/inngest-js/pull/1205) [`8ca992e9`](https://github.com/inngest/inngest-js/commit/8ca992e913d1d41c5704dfd7b0d262848b9fb84f) Thanks [@Linell](https://github.com/Linell)! - Include client headers, such as `x-inngest-env` in trace exports.
8
+
3
9
  ## 3.48.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -21,7 +21,6 @@ Read the <a href="https://www.inngest.com/docs?ref=github-inngest-js-readme">doc
21
21
  <p>
22
22
 
23
23
  <a href="https://www.npmjs.com/package/inngest"><img src="https://img.shields.io/npm/v/inngest" /></a>
24
- <a href="https://jsr.io/@inngest/sdk"><img src="https://jsr.io/badges/@inngest/sdk" /></a>
25
24
  <br/>
26
25
  <a href="https://www.inngest.com/discord"><img src="https://img.shields.io/discord/842170679536517141?label=discord" /></a>
27
26
  <a href="https://twitter.com/inngest"><img src="https://img.shields.io/twitter/follow/inngest?style=social" /></a>
@@ -64,12 +63,6 @@ Install Inngest:
64
63
  npm install inngest
65
64
  ```
66
65
 
67
- Or get it from [JSR](https://jsr.io/@inngest/sdk):
68
-
69
- ```bash
70
- deno add jsr:@inngest/sdk
71
- ```
72
-
73
66
  ### Writing functions
74
67
 
75
68
  Write serverless functions and background jobs right in your own code:
@@ -149,7 +149,10 @@ var InngestSpanProcessor = class InngestSpanProcessor {
149
149
  processorDebug("batcher lazily accessed; creating new batcher with URL", url);
150
150
  resolve(new __opentelemetry_sdk_trace_base.BatchSpanProcessor(new __opentelemetry_exporter_trace_otlp_http.OTLPTraceExporter({
151
151
  url: url.href,
152
- headers: { Authorization: `Bearer ${app["inngestApi"]["signingKey"]}` }
152
+ headers: {
153
+ ...app["headers"],
154
+ Authorization: `Bearer ${app["inngestApi"]["signingKey"]}`
155
+ }
153
156
  })));
154
157
  } catch (err) {
155
158
  reject(err);
@@ -1 +1 @@
1
- {"version":3,"file":"processor.cjs","names":["debugPrefix","_resourceAttributes: Resource | undefined","#traceParents","appId: string | undefined","functionId: string | undefined","traceRef: string | undefined","TraceStateKey","osDetector","envDetector","hostDetector","processDetector","serviceInstanceIdDetector","#batcher","getAsyncCtx","url: URL","defaultInngestApiBaseUrl","devServerHost","defaultDevServerHost","devServerAvailable","BatchSpanProcessor","OTLPTraceExporter","#spanCleanup","#spansToExport","Attribute","debug"],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport {\n detectResources,\n envDetector,\n hostDetector,\n osDetector,\n processDetector,\n type Resource,\n serviceInstanceIdDetector,\n} from \"@opentelemetry/resources\";\nimport {\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport Debug from \"debug\";\nimport {\n defaultDevServerHost,\n defaultInngestApiBaseUrl,\n} from \"../../../helpers/consts.ts\";\nimport { devServerAvailable } from \"../../../helpers/devserver.ts\";\nimport { devServerHost } from \"../../../helpers/env.ts\";\nimport type { Inngest } from \"../../Inngest.ts\";\nimport { getAsyncCtx } from \"../als.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { Attribute, debugPrefix, TraceStateKey } from \"./consts.ts\";\n\nconst processorDebug = Debug(`${debugPrefix}:InngestSpanProcessor`);\n\n/**\n * A set of resource attributes that are used to identify the Inngest app and\n * the function that is being executed. This is used to store the resource\n * attributes for the spans that are exported to the Inngest endpoint, and cache\n * them for later use.\n */\nlet _resourceAttributes: Resource | undefined;\n\n/**\n * A set of information about an execution that's used to set attributes on\n * userland spans sent to Inngest for proper indexing.\n */\nexport type ParentState = {\n traceparent: string;\n runId: string;\n appId: string | undefined;\n functionId: string | undefined;\n traceRef: string | undefined;\n};\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n *\n * THIS IS THE INTERNAL IMPLEMENTATION OF THE SPAN PROCESSOR AND SHOULD NOT BE\n * USED BY USERS DIRECTLY. USE THE {@link PublicInngestSpanProcessor} CLASS\n * INSTEAD.\n */\nexport class InngestSpanProcessor implements SpanProcessor {\n /**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n *\n * It is optional here as this is the private constructor and only used\n * internally; we set `app` elsewhere as when we create the processor (as\n * early as possible when the process starts) we don't necessarily have the\n * app available yet.\n *\n * So, internally we can delay setting ths until later.\n */\n app?: Inngest.Like,\n ) {\n if (app) {\n clientProcessorMap.set(app as Inngest.Any, this);\n }\n }\n\n /**\n * A `BatchSpanProcessor` that is used to export spans to the Inngest\n * endpoint. This is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n */\n #batcher: Promise<BatchSpanProcessor> | undefined;\n\n /**\n * A set of spans used to track spans that we care about, so that we can\n * export them to the OTel endpoint.\n *\n * If a span falls out of reference, it will be removed from this set as we'll\n * never get a chance to export it or remove it anyway.\n */\n #spansToExport = new WeakSet<Span>();\n\n /**\n * A map of span IDs to their parent state, which includes a block of\n * information that can be used and pushed back to the Inngest endpoint to\n * ingest spans.\n */\n #traceParents = new Map<string, ParentState>();\n\n /**\n * A registry used to clean up items from the `traceParents` map when spans\n * fall out of reference. This is used to avoid memory leaks in the case where\n * a span is not exported, remains unended, and is left in memory before being\n * GC'd.\n */\n #spanCleanup = new FinalizationRegistry<string>((spanId) => {\n if (spanId) {\n this.#traceParents.delete(spanId);\n }\n });\n\n /**\n * In order to only capture a subset of spans, we need to declare the initial\n * span that we care about and then export its children.\n *\n * Call this method (ideally just before execution starts) with that initial\n * span to trigger capturing all following children as well as initialize the\n * batcher.\n */\n public declareStartingSpan({\n span,\n runId,\n traceparent,\n tracestate,\n }: {\n span: Span;\n runId: string;\n traceparent: string | undefined;\n tracestate: string | undefined;\n }): void {\n // Upsert the batcher ready for later. We do this here to bootstrap it with\n // the correct async context as soon as we can. As this method is only\n // called just before execution, we know we're all set up.\n //\n // Waiting to call this until we actually need the batcher would mean that\n // we might not have the correct async context set up, as we'd likely be in\n // some span lifecycle method that doesn't have the same chain of execution.\n void this.ensureBatcherInitialized();\n\n // If we don't have a traceparent, then we can't track this span. This is\n // likely a span that we don't care about, so we can ignore it.\n if (!traceparent) {\n return processorDebug(\n \"no traceparent found for span\",\n span.spanContext().spanId,\n \"so skipping it\",\n );\n }\n\n // We also attempt to use `tracestate`. The values we fetch from these\n // should be optional, as it's likely the Executor won't need us to parrot\n // them back in later versions.\n let appId: string | undefined;\n let functionId: string | undefined;\n let traceRef: string | undefined;\n\n if (tracestate) {\n try {\n const entries = Object.fromEntries(\n tracestate.split(\",\").map((kv) => kv.split(\"=\") as [string, string]),\n );\n\n appId = entries[TraceStateKey.AppId];\n functionId = entries[TraceStateKey.FunctionId];\n traceRef = entries[TraceStateKey.TraceRef];\n } catch (err) {\n processorDebug(\n \"failed to parse tracestate\",\n tracestate,\n \"so skipping it;\",\n err,\n );\n }\n }\n\n // This is a span that we care about, so let's make sure it and its\n // children are exported.\n processorDebug.extend(\"declareStartingSpan\")(\n \"declaring:\",\n span.spanContext().spanId,\n \"for traceparent\",\n traceparent,\n );\n\n // Set a load of attributes on this span so that we can nicely identify\n // runtime, paths, etc. Only this span will have these attributes.\n span.setAttributes(InngestSpanProcessor.resourceAttributes.attributes);\n\n this.trackSpan(\n {\n appId,\n functionId,\n runId,\n traceparent,\n traceRef,\n },\n span,\n );\n }\n\n /**\n * A getter for retrieving resource attributes for the current process. This\n * is used to set the resource attributes for the spans that are exported to\n * the Inngest endpoint, and cache them for later use.\n */\n static get resourceAttributes(): Resource {\n if (!_resourceAttributes) {\n _resourceAttributes = detectResources({\n detectors: [\n osDetector,\n envDetector,\n hostDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n });\n }\n\n return _resourceAttributes;\n }\n\n /**\n * The batcher is a singleton that is used to export spans to the OTel\n * endpoint. It is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n *\n * The batcher is only referenced once we've found a span we're interested in,\n * so this should always have everything it needs on the app by then.\n */\n private ensureBatcherInitialized(): Promise<BatchSpanProcessor> {\n if (!this.#batcher) {\n this.#batcher = new Promise(async (resolve, reject) => {\n try {\n // We retrieve the app from the async context, so we must make sure\n // that this function is called from the correct chain.\n const store = await getAsyncCtx();\n if (!store) {\n throw new Error(\n \"No async context found; cannot create batcher to export traces\",\n );\n }\n\n const app = store.app as Inngest.Any;\n\n // Fetch the URL for the Inngest endpoint using the app's config.\n let url: URL;\n const path = \"/v1/traces/userland\";\n if (app.apiBaseUrl) {\n url = new URL(path, app.apiBaseUrl);\n } else {\n url = new URL(path, defaultInngestApiBaseUrl);\n\n if (app[\"mode\"] && app[\"mode\"].isDev && app[\"mode\"].isInferred) {\n const devHost = devServerHost() || defaultDevServerHost;\n const hasDevServer = await devServerAvailable(\n devHost,\n app[\"fetch\"],\n );\n if (hasDevServer) {\n url = new URL(path, devHost);\n }\n } else if (app[\"mode\"]?.explicitDevUrl) {\n url = new URL(path, app[\"mode\"].explicitDevUrl.href);\n }\n }\n\n processorDebug(\n \"batcher lazily accessed; creating new batcher with URL\",\n url,\n );\n\n const exporter = new OTLPTraceExporter({\n url: url.href,\n\n headers: {\n Authorization: `Bearer ${app[\"inngestApi\"][\"signingKey\"]}`,\n },\n });\n\n resolve(new BatchSpanProcessor(exporter));\n } catch (err) {\n reject(err);\n }\n });\n }\n\n return this.#batcher;\n }\n\n /**\n * Mark a span as being tracked by this processor, meaning it will be exported\n * to the Inggest endpoint when it ends.\n */\n private trackSpan(parentState: ParentState, span: Span): void {\n const spanId = span.spanContext().spanId;\n\n this.#spanCleanup.register(span, spanId, span);\n this.#spansToExport.add(span);\n this.#traceParents.set(spanId, parentState);\n\n span.setAttribute(Attribute.InngestTraceparent, parentState.traceparent);\n span.setAttribute(Attribute.InngestRunId, parentState.runId);\n\n // Setting app ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.appId) {\n span.setAttribute(Attribute.InngestAppId1, parentState.appId);\n span.setAttribute(Attribute.InngestAppId2, parentState.appId);\n }\n\n // Setting function ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.functionId) {\n span.setAttribute(Attribute.InngestFunctionId, parentState.functionId);\n }\n\n if (parentState.traceRef) {\n span.setAttribute(Attribute.InngestTraceRef, parentState.traceRef);\n }\n }\n\n /**\n * Clean up any references to a span that has ended. This is used to avoid\n * memory leaks in the case where a span is not exported, remains unended, and\n * is left in memory before being GC'd.\n */\n private cleanupSpan(span: Span): void {\n const spanId = span.spanContext().spanId;\n\n // This span is no longer in use, so we can remove it from the cleanup\n // registry.\n this.#spanCleanup.unregister(span);\n this.#spansToExport.delete(span);\n this.#traceParents.delete(spanId);\n }\n\n /**\n * An implementation of the `onStart` method from the `SpanProcessor`\n * interface. This is called when a span is started, and is used to track\n * spans that are children of spans we care about.\n */\n onStart(span: Span): void {\n const debug = processorDebug.extend(\"onStart\");\n const spanId = span.spanContext().spanId;\n // 🤫 It seems to work\n const parentSpanId = (span as unknown as ReadableSpan).parentSpanContext\n ?.spanId;\n\n // The root span isn't captured here, but we can capture children of it\n // here.\n\n if (!parentSpanId) {\n // All spans that Inngest cares about will have a parent, so ignore this\n debug(\"no parent span ID for\", spanId, \"so skipping it\");\n\n return;\n }\n\n const parentState = this.#traceParents.get(parentSpanId);\n if (parentState) {\n // This span is a child of a span we care about, so add it to the list of\n // tracked spans so that we also capture its children\n debug(\n \"found traceparent\",\n parentState,\n \"in span ID\",\n parentSpanId,\n \"so adding\",\n spanId,\n );\n\n this.trackSpan(parentState, span);\n }\n }\n\n /**\n * An implementation of the `onEnd` method from the `SpanProcessor` interface.\n * This is called when a span ends, and is used to export spans to the Inngest\n * endpoint.\n */\n onEnd(span: ReadableSpan): void {\n const debug = processorDebug.extend(\"onEnd\");\n const spanId = span.spanContext().spanId;\n\n try {\n if (this.#spansToExport.has(span as unknown as Span)) {\n if (!this.#batcher) {\n return debug(\n \"batcher not initialized, so failed exporting span\",\n spanId,\n );\n }\n\n debug(\"exporting span\", spanId);\n return void this.#batcher.then((batcher) => batcher.onEnd(span));\n }\n\n debug(\"not exporting span\", spanId, \"as we don't care about it\");\n } finally {\n this.cleanupSpan(span as unknown as Span);\n }\n }\n\n /**\n * An implementation of the `forceFlush` method from the `SpanProcessor`\n * interface. This is called to force the processor to flush any spans that\n * are currently in the batcher. This is used to ensure that spans are\n * exported to the Inngest endpoint before the process exits.\n *\n * Notably, we call this in the `beforeResponse` middleware hook to ensure\n * that spans for a run as exported as soon as possible and before the\n * serverless process is killed.\n */\n async forceFlush(): Promise<void> {\n const flushDebug = processorDebug.extend(\"forceFlush\");\n flushDebug(\"force flushing batcher\");\n\n return this.#batcher\n ?.then((batcher) => batcher.forceFlush())\n .catch((err) => {\n flushDebug(\"error flushing batcher\", err, \"ignoring\");\n });\n }\n\n async shutdown(): Promise<void> {\n processorDebug.extend(\"shutdown\")(\"shutting down batcher\");\n\n return this.#batcher?.then((batcher) => batcher.shutdown());\n }\n}\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\nexport class PublicInngestSpanProcessor extends InngestSpanProcessor {\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n */\n app: Inngest.Like,\n ) {\n super(app);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"processor.cjs","names":["debugPrefix","_resourceAttributes: Resource | undefined","#traceParents","appId: string | undefined","functionId: string | undefined","traceRef: string | undefined","TraceStateKey","osDetector","envDetector","hostDetector","processDetector","serviceInstanceIdDetector","#batcher","getAsyncCtx","url: URL","defaultInngestApiBaseUrl","devServerHost","defaultDevServerHost","devServerAvailable","BatchSpanProcessor","OTLPTraceExporter","#spanCleanup","#spansToExport","Attribute","debug"],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport {\n detectResources,\n envDetector,\n hostDetector,\n osDetector,\n processDetector,\n type Resource,\n serviceInstanceIdDetector,\n} from \"@opentelemetry/resources\";\nimport {\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport Debug from \"debug\";\nimport {\n defaultDevServerHost,\n defaultInngestApiBaseUrl,\n} from \"../../../helpers/consts.ts\";\nimport { devServerAvailable } from \"../../../helpers/devserver.ts\";\nimport { devServerHost } from \"../../../helpers/env.ts\";\nimport type { Inngest } from \"../../Inngest.ts\";\nimport { getAsyncCtx } from \"../als.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { Attribute, debugPrefix, TraceStateKey } from \"./consts.ts\";\n\nconst processorDebug = Debug(`${debugPrefix}:InngestSpanProcessor`);\n\n/**\n * A set of resource attributes that are used to identify the Inngest app and\n * the function that is being executed. This is used to store the resource\n * attributes for the spans that are exported to the Inngest endpoint, and cache\n * them for later use.\n */\nlet _resourceAttributes: Resource | undefined;\n\n/**\n * A set of information about an execution that's used to set attributes on\n * userland spans sent to Inngest for proper indexing.\n */\nexport type ParentState = {\n traceparent: string;\n runId: string;\n appId: string | undefined;\n functionId: string | undefined;\n traceRef: string | undefined;\n};\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n *\n * THIS IS THE INTERNAL IMPLEMENTATION OF THE SPAN PROCESSOR AND SHOULD NOT BE\n * USED BY USERS DIRECTLY. USE THE {@link PublicInngestSpanProcessor} CLASS\n * INSTEAD.\n */\nexport class InngestSpanProcessor implements SpanProcessor {\n /**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n *\n * It is optional here as this is the private constructor and only used\n * internally; we set `app` elsewhere as when we create the processor (as\n * early as possible when the process starts) we don't necessarily have the\n * app available yet.\n *\n * So, internally we can delay setting ths until later.\n */\n app?: Inngest.Like,\n ) {\n if (app) {\n clientProcessorMap.set(app as Inngest.Any, this);\n }\n }\n\n /**\n * A `BatchSpanProcessor` that is used to export spans to the Inngest\n * endpoint. This is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n */\n #batcher: Promise<BatchSpanProcessor> | undefined;\n\n /**\n * A set of spans used to track spans that we care about, so that we can\n * export them to the OTel endpoint.\n *\n * If a span falls out of reference, it will be removed from this set as we'll\n * never get a chance to export it or remove it anyway.\n */\n #spansToExport = new WeakSet<Span>();\n\n /**\n * A map of span IDs to their parent state, which includes a block of\n * information that can be used and pushed back to the Inngest endpoint to\n * ingest spans.\n */\n #traceParents = new Map<string, ParentState>();\n\n /**\n * A registry used to clean up items from the `traceParents` map when spans\n * fall out of reference. This is used to avoid memory leaks in the case where\n * a span is not exported, remains unended, and is left in memory before being\n * GC'd.\n */\n #spanCleanup = new FinalizationRegistry<string>((spanId) => {\n if (spanId) {\n this.#traceParents.delete(spanId);\n }\n });\n\n /**\n * In order to only capture a subset of spans, we need to declare the initial\n * span that we care about and then export its children.\n *\n * Call this method (ideally just before execution starts) with that initial\n * span to trigger capturing all following children as well as initialize the\n * batcher.\n */\n public declareStartingSpan({\n span,\n runId,\n traceparent,\n tracestate,\n }: {\n span: Span;\n runId: string;\n traceparent: string | undefined;\n tracestate: string | undefined;\n }): void {\n // Upsert the batcher ready for later. We do this here to bootstrap it with\n // the correct async context as soon as we can. As this method is only\n // called just before execution, we know we're all set up.\n //\n // Waiting to call this until we actually need the batcher would mean that\n // we might not have the correct async context set up, as we'd likely be in\n // some span lifecycle method that doesn't have the same chain of execution.\n void this.ensureBatcherInitialized();\n\n // If we don't have a traceparent, then we can't track this span. This is\n // likely a span that we don't care about, so we can ignore it.\n if (!traceparent) {\n return processorDebug(\n \"no traceparent found for span\",\n span.spanContext().spanId,\n \"so skipping it\",\n );\n }\n\n // We also attempt to use `tracestate`. The values we fetch from these\n // should be optional, as it's likely the Executor won't need us to parrot\n // them back in later versions.\n let appId: string | undefined;\n let functionId: string | undefined;\n let traceRef: string | undefined;\n\n if (tracestate) {\n try {\n const entries = Object.fromEntries(\n tracestate.split(\",\").map((kv) => kv.split(\"=\") as [string, string]),\n );\n\n appId = entries[TraceStateKey.AppId];\n functionId = entries[TraceStateKey.FunctionId];\n traceRef = entries[TraceStateKey.TraceRef];\n } catch (err) {\n processorDebug(\n \"failed to parse tracestate\",\n tracestate,\n \"so skipping it;\",\n err,\n );\n }\n }\n\n // This is a span that we care about, so let's make sure it and its\n // children are exported.\n processorDebug.extend(\"declareStartingSpan\")(\n \"declaring:\",\n span.spanContext().spanId,\n \"for traceparent\",\n traceparent,\n );\n\n // Set a load of attributes on this span so that we can nicely identify\n // runtime, paths, etc. Only this span will have these attributes.\n span.setAttributes(InngestSpanProcessor.resourceAttributes.attributes);\n\n this.trackSpan(\n {\n appId,\n functionId,\n runId,\n traceparent,\n traceRef,\n },\n span,\n );\n }\n\n /**\n * A getter for retrieving resource attributes for the current process. This\n * is used to set the resource attributes for the spans that are exported to\n * the Inngest endpoint, and cache them for later use.\n */\n static get resourceAttributes(): Resource {\n if (!_resourceAttributes) {\n _resourceAttributes = detectResources({\n detectors: [\n osDetector,\n envDetector,\n hostDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n });\n }\n\n return _resourceAttributes;\n }\n\n /**\n * The batcher is a singleton that is used to export spans to the OTel\n * endpoint. It is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n *\n * The batcher is only referenced once we've found a span we're interested in,\n * so this should always have everything it needs on the app by then.\n */\n private ensureBatcherInitialized(): Promise<BatchSpanProcessor> {\n if (!this.#batcher) {\n this.#batcher = new Promise(async (resolve, reject) => {\n try {\n // We retrieve the app from the async context, so we must make sure\n // that this function is called from the correct chain.\n const store = await getAsyncCtx();\n if (!store) {\n throw new Error(\n \"No async context found; cannot create batcher to export traces\",\n );\n }\n\n const app = store.app as Inngest.Any;\n\n // Fetch the URL for the Inngest endpoint using the app's config.\n let url: URL;\n const path = \"/v1/traces/userland\";\n if (app.apiBaseUrl) {\n url = new URL(path, app.apiBaseUrl);\n } else {\n url = new URL(path, defaultInngestApiBaseUrl);\n\n if (app[\"mode\"] && app[\"mode\"].isDev && app[\"mode\"].isInferred) {\n const devHost = devServerHost() || defaultDevServerHost;\n const hasDevServer = await devServerAvailable(\n devHost,\n app[\"fetch\"],\n );\n if (hasDevServer) {\n url = new URL(path, devHost);\n }\n } else if (app[\"mode\"]?.explicitDevUrl) {\n url = new URL(path, app[\"mode\"].explicitDevUrl.href);\n }\n }\n\n processorDebug(\n \"batcher lazily accessed; creating new batcher with URL\",\n url,\n );\n\n const exporter = new OTLPTraceExporter({\n url: url.href,\n\n headers: {\n ...app[\"headers\"],\n Authorization: `Bearer ${app[\"inngestApi\"][\"signingKey\"]}`,\n },\n });\n\n resolve(new BatchSpanProcessor(exporter));\n } catch (err) {\n reject(err);\n }\n });\n }\n\n return this.#batcher;\n }\n\n /**\n * Mark a span as being tracked by this processor, meaning it will be exported\n * to the Inggest endpoint when it ends.\n */\n private trackSpan(parentState: ParentState, span: Span): void {\n const spanId = span.spanContext().spanId;\n\n this.#spanCleanup.register(span, spanId, span);\n this.#spansToExport.add(span);\n this.#traceParents.set(spanId, parentState);\n\n span.setAttribute(Attribute.InngestTraceparent, parentState.traceparent);\n span.setAttribute(Attribute.InngestRunId, parentState.runId);\n\n // Setting app ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.appId) {\n span.setAttribute(Attribute.InngestAppId1, parentState.appId);\n span.setAttribute(Attribute.InngestAppId2, parentState.appId);\n }\n\n // Setting function ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.functionId) {\n span.setAttribute(Attribute.InngestFunctionId, parentState.functionId);\n }\n\n if (parentState.traceRef) {\n span.setAttribute(Attribute.InngestTraceRef, parentState.traceRef);\n }\n }\n\n /**\n * Clean up any references to a span that has ended. This is used to avoid\n * memory leaks in the case where a span is not exported, remains unended, and\n * is left in memory before being GC'd.\n */\n private cleanupSpan(span: Span): void {\n const spanId = span.spanContext().spanId;\n\n // This span is no longer in use, so we can remove it from the cleanup\n // registry.\n this.#spanCleanup.unregister(span);\n this.#spansToExport.delete(span);\n this.#traceParents.delete(spanId);\n }\n\n /**\n * An implementation of the `onStart` method from the `SpanProcessor`\n * interface. This is called when a span is started, and is used to track\n * spans that are children of spans we care about.\n */\n onStart(span: Span): void {\n const debug = processorDebug.extend(\"onStart\");\n const spanId = span.spanContext().spanId;\n // 🤫 It seems to work\n const parentSpanId = (span as unknown as ReadableSpan).parentSpanContext\n ?.spanId;\n\n // The root span isn't captured here, but we can capture children of it\n // here.\n\n if (!parentSpanId) {\n // All spans that Inngest cares about will have a parent, so ignore this\n debug(\"no parent span ID for\", spanId, \"so skipping it\");\n\n return;\n }\n\n const parentState = this.#traceParents.get(parentSpanId);\n if (parentState) {\n // This span is a child of a span we care about, so add it to the list of\n // tracked spans so that we also capture its children\n debug(\n \"found traceparent\",\n parentState,\n \"in span ID\",\n parentSpanId,\n \"so adding\",\n spanId,\n );\n\n this.trackSpan(parentState, span);\n }\n }\n\n /**\n * An implementation of the `onEnd` method from the `SpanProcessor` interface.\n * This is called when a span ends, and is used to export spans to the Inngest\n * endpoint.\n */\n onEnd(span: ReadableSpan): void {\n const debug = processorDebug.extend(\"onEnd\");\n const spanId = span.spanContext().spanId;\n\n try {\n if (this.#spansToExport.has(span as unknown as Span)) {\n if (!this.#batcher) {\n return debug(\n \"batcher not initialized, so failed exporting span\",\n spanId,\n );\n }\n\n debug(\"exporting span\", spanId);\n return void this.#batcher.then((batcher) => batcher.onEnd(span));\n }\n\n debug(\"not exporting span\", spanId, \"as we don't care about it\");\n } finally {\n this.cleanupSpan(span as unknown as Span);\n }\n }\n\n /**\n * An implementation of the `forceFlush` method from the `SpanProcessor`\n * interface. This is called to force the processor to flush any spans that\n * are currently in the batcher. This is used to ensure that spans are\n * exported to the Inngest endpoint before the process exits.\n *\n * Notably, we call this in the `beforeResponse` middleware hook to ensure\n * that spans for a run as exported as soon as possible and before the\n * serverless process is killed.\n */\n async forceFlush(): Promise<void> {\n const flushDebug = processorDebug.extend(\"forceFlush\");\n flushDebug(\"force flushing batcher\");\n\n return this.#batcher\n ?.then((batcher) => batcher.forceFlush())\n .catch((err) => {\n flushDebug(\"error flushing batcher\", err, \"ignoring\");\n });\n }\n\n async shutdown(): Promise<void> {\n processorDebug.extend(\"shutdown\")(\"shutting down batcher\");\n\n return this.#batcher?.then((batcher) => batcher.shutdown());\n }\n}\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\nexport class PublicInngestSpanProcessor extends InngestSpanProcessor {\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n */\n app: Inngest.Like,\n ) {\n super(app);\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"processor.d.cts","names":[],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAucA;;;;;;cAzYa,oBAAA,YAAgC;;;;;;;;;;;;;;;;;;;;;;QAqBnC,OAAA,CAAQ;;;;;;;;;;;;;;;UAyDR;;;;;;;;;;mCAgFyB;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAyInB;;;;;;cAuCF;;;;;;;;;;;gBAiCQ;cAWF;;;;;;;;;;cAeP,0BAAA,SAAmC,oBAAA;;;;;;OAMvC,OAAA,CAAQ"}
1
+ {"version":3,"file":"processor.d.cts","names":[],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAwcA;;;;;;cA1Ya,oBAAA,YAAgC;;;;;;;;;;;;;;;;;;;;;;QAqBnC,OAAA,CAAQ;;;;;;;;;;;;;;;UAyDR;;;;;;;;;;mCAgFyB;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA0InB;;;;;;cAuCF;;;;;;;;;;;gBAiCQ;cAWF;;;;;;;;;;cAeP,0BAAA,SAAmC,oBAAA;;;;;;OAMvC,OAAA,CAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"processor.d.ts","names":[],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAucA;;;;;;cAzYa,oBAAA,YAAgC;;;;;;;;;;;;;;;;;;;;;;QAqBnC,OAAA,CAAQ;;;;;;;;;;;;;;;UAyDR;;;;;;;;;;mCAgFyB;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAyInB;;;;;;cAuCF;;;;;;;;;;;gBAiCQ;cAWF;;;;;;;;;;cAeP,0BAAA,SAAmC,oBAAA;;;;;;OAMvC,OAAA,CAAQ"}
1
+ {"version":3,"file":"processor.d.ts","names":[],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAwcA;;;;;;cA1Ya,oBAAA,YAAgC;;;;;;;;;;;;;;;;;;;;;;QAqBnC,OAAA,CAAQ;;;;;;;;;;;;;;;UAyDR;;;;;;;;;;mCAgFyB;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA0InB;;;;;;cAuCF;;;;;;;;;;;gBAiCQ;cAWF;;;;;;;;;;cAeP,0BAAA,SAAmC,oBAAA;;;;;;OAMvC,OAAA,CAAQ"}
@@ -147,7 +147,10 @@ var InngestSpanProcessor = class InngestSpanProcessor {
147
147
  processorDebug("batcher lazily accessed; creating new batcher with URL", url);
148
148
  resolve(new BatchSpanProcessor(new OTLPTraceExporter({
149
149
  url: url.href,
150
- headers: { Authorization: `Bearer ${app["inngestApi"]["signingKey"]}` }
150
+ headers: {
151
+ ...app["headers"],
152
+ Authorization: `Bearer ${app["inngestApi"]["signingKey"]}`
153
+ }
151
154
  })));
152
155
  } catch (err) {
153
156
  reject(err);
@@ -1 +1 @@
1
- {"version":3,"file":"processor.js","names":["Debug","_resourceAttributes: Resource | undefined","#traceParents","appId: string | undefined","functionId: string | undefined","traceRef: string | undefined","#batcher","url: URL","#spanCleanup","#spansToExport","debug"],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport {\n detectResources,\n envDetector,\n hostDetector,\n osDetector,\n processDetector,\n type Resource,\n serviceInstanceIdDetector,\n} from \"@opentelemetry/resources\";\nimport {\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport Debug from \"debug\";\nimport {\n defaultDevServerHost,\n defaultInngestApiBaseUrl,\n} from \"../../../helpers/consts.ts\";\nimport { devServerAvailable } from \"../../../helpers/devserver.ts\";\nimport { devServerHost } from \"../../../helpers/env.ts\";\nimport type { Inngest } from \"../../Inngest.ts\";\nimport { getAsyncCtx } from \"../als.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { Attribute, debugPrefix, TraceStateKey } from \"./consts.ts\";\n\nconst processorDebug = Debug(`${debugPrefix}:InngestSpanProcessor`);\n\n/**\n * A set of resource attributes that are used to identify the Inngest app and\n * the function that is being executed. This is used to store the resource\n * attributes for the spans that are exported to the Inngest endpoint, and cache\n * them for later use.\n */\nlet _resourceAttributes: Resource | undefined;\n\n/**\n * A set of information about an execution that's used to set attributes on\n * userland spans sent to Inngest for proper indexing.\n */\nexport type ParentState = {\n traceparent: string;\n runId: string;\n appId: string | undefined;\n functionId: string | undefined;\n traceRef: string | undefined;\n};\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n *\n * THIS IS THE INTERNAL IMPLEMENTATION OF THE SPAN PROCESSOR AND SHOULD NOT BE\n * USED BY USERS DIRECTLY. USE THE {@link PublicInngestSpanProcessor} CLASS\n * INSTEAD.\n */\nexport class InngestSpanProcessor implements SpanProcessor {\n /**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n *\n * It is optional here as this is the private constructor and only used\n * internally; we set `app` elsewhere as when we create the processor (as\n * early as possible when the process starts) we don't necessarily have the\n * app available yet.\n *\n * So, internally we can delay setting ths until later.\n */\n app?: Inngest.Like,\n ) {\n if (app) {\n clientProcessorMap.set(app as Inngest.Any, this);\n }\n }\n\n /**\n * A `BatchSpanProcessor` that is used to export spans to the Inngest\n * endpoint. This is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n */\n #batcher: Promise<BatchSpanProcessor> | undefined;\n\n /**\n * A set of spans used to track spans that we care about, so that we can\n * export them to the OTel endpoint.\n *\n * If a span falls out of reference, it will be removed from this set as we'll\n * never get a chance to export it or remove it anyway.\n */\n #spansToExport = new WeakSet<Span>();\n\n /**\n * A map of span IDs to their parent state, which includes a block of\n * information that can be used and pushed back to the Inngest endpoint to\n * ingest spans.\n */\n #traceParents = new Map<string, ParentState>();\n\n /**\n * A registry used to clean up items from the `traceParents` map when spans\n * fall out of reference. This is used to avoid memory leaks in the case where\n * a span is not exported, remains unended, and is left in memory before being\n * GC'd.\n */\n #spanCleanup = new FinalizationRegistry<string>((spanId) => {\n if (spanId) {\n this.#traceParents.delete(spanId);\n }\n });\n\n /**\n * In order to only capture a subset of spans, we need to declare the initial\n * span that we care about and then export its children.\n *\n * Call this method (ideally just before execution starts) with that initial\n * span to trigger capturing all following children as well as initialize the\n * batcher.\n */\n public declareStartingSpan({\n span,\n runId,\n traceparent,\n tracestate,\n }: {\n span: Span;\n runId: string;\n traceparent: string | undefined;\n tracestate: string | undefined;\n }): void {\n // Upsert the batcher ready for later. We do this here to bootstrap it with\n // the correct async context as soon as we can. As this method is only\n // called just before execution, we know we're all set up.\n //\n // Waiting to call this until we actually need the batcher would mean that\n // we might not have the correct async context set up, as we'd likely be in\n // some span lifecycle method that doesn't have the same chain of execution.\n void this.ensureBatcherInitialized();\n\n // If we don't have a traceparent, then we can't track this span. This is\n // likely a span that we don't care about, so we can ignore it.\n if (!traceparent) {\n return processorDebug(\n \"no traceparent found for span\",\n span.spanContext().spanId,\n \"so skipping it\",\n );\n }\n\n // We also attempt to use `tracestate`. The values we fetch from these\n // should be optional, as it's likely the Executor won't need us to parrot\n // them back in later versions.\n let appId: string | undefined;\n let functionId: string | undefined;\n let traceRef: string | undefined;\n\n if (tracestate) {\n try {\n const entries = Object.fromEntries(\n tracestate.split(\",\").map((kv) => kv.split(\"=\") as [string, string]),\n );\n\n appId = entries[TraceStateKey.AppId];\n functionId = entries[TraceStateKey.FunctionId];\n traceRef = entries[TraceStateKey.TraceRef];\n } catch (err) {\n processorDebug(\n \"failed to parse tracestate\",\n tracestate,\n \"so skipping it;\",\n err,\n );\n }\n }\n\n // This is a span that we care about, so let's make sure it and its\n // children are exported.\n processorDebug.extend(\"declareStartingSpan\")(\n \"declaring:\",\n span.spanContext().spanId,\n \"for traceparent\",\n traceparent,\n );\n\n // Set a load of attributes on this span so that we can nicely identify\n // runtime, paths, etc. Only this span will have these attributes.\n span.setAttributes(InngestSpanProcessor.resourceAttributes.attributes);\n\n this.trackSpan(\n {\n appId,\n functionId,\n runId,\n traceparent,\n traceRef,\n },\n span,\n );\n }\n\n /**\n * A getter for retrieving resource attributes for the current process. This\n * is used to set the resource attributes for the spans that are exported to\n * the Inngest endpoint, and cache them for later use.\n */\n static get resourceAttributes(): Resource {\n if (!_resourceAttributes) {\n _resourceAttributes = detectResources({\n detectors: [\n osDetector,\n envDetector,\n hostDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n });\n }\n\n return _resourceAttributes;\n }\n\n /**\n * The batcher is a singleton that is used to export spans to the OTel\n * endpoint. It is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n *\n * The batcher is only referenced once we've found a span we're interested in,\n * so this should always have everything it needs on the app by then.\n */\n private ensureBatcherInitialized(): Promise<BatchSpanProcessor> {\n if (!this.#batcher) {\n this.#batcher = new Promise(async (resolve, reject) => {\n try {\n // We retrieve the app from the async context, so we must make sure\n // that this function is called from the correct chain.\n const store = await getAsyncCtx();\n if (!store) {\n throw new Error(\n \"No async context found; cannot create batcher to export traces\",\n );\n }\n\n const app = store.app as Inngest.Any;\n\n // Fetch the URL for the Inngest endpoint using the app's config.\n let url: URL;\n const path = \"/v1/traces/userland\";\n if (app.apiBaseUrl) {\n url = new URL(path, app.apiBaseUrl);\n } else {\n url = new URL(path, defaultInngestApiBaseUrl);\n\n if (app[\"mode\"] && app[\"mode\"].isDev && app[\"mode\"].isInferred) {\n const devHost = devServerHost() || defaultDevServerHost;\n const hasDevServer = await devServerAvailable(\n devHost,\n app[\"fetch\"],\n );\n if (hasDevServer) {\n url = new URL(path, devHost);\n }\n } else if (app[\"mode\"]?.explicitDevUrl) {\n url = new URL(path, app[\"mode\"].explicitDevUrl.href);\n }\n }\n\n processorDebug(\n \"batcher lazily accessed; creating new batcher with URL\",\n url,\n );\n\n const exporter = new OTLPTraceExporter({\n url: url.href,\n\n headers: {\n Authorization: `Bearer ${app[\"inngestApi\"][\"signingKey\"]}`,\n },\n });\n\n resolve(new BatchSpanProcessor(exporter));\n } catch (err) {\n reject(err);\n }\n });\n }\n\n return this.#batcher;\n }\n\n /**\n * Mark a span as being tracked by this processor, meaning it will be exported\n * to the Inggest endpoint when it ends.\n */\n private trackSpan(parentState: ParentState, span: Span): void {\n const spanId = span.spanContext().spanId;\n\n this.#spanCleanup.register(span, spanId, span);\n this.#spansToExport.add(span);\n this.#traceParents.set(spanId, parentState);\n\n span.setAttribute(Attribute.InngestTraceparent, parentState.traceparent);\n span.setAttribute(Attribute.InngestRunId, parentState.runId);\n\n // Setting app ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.appId) {\n span.setAttribute(Attribute.InngestAppId1, parentState.appId);\n span.setAttribute(Attribute.InngestAppId2, parentState.appId);\n }\n\n // Setting function ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.functionId) {\n span.setAttribute(Attribute.InngestFunctionId, parentState.functionId);\n }\n\n if (parentState.traceRef) {\n span.setAttribute(Attribute.InngestTraceRef, parentState.traceRef);\n }\n }\n\n /**\n * Clean up any references to a span that has ended. This is used to avoid\n * memory leaks in the case where a span is not exported, remains unended, and\n * is left in memory before being GC'd.\n */\n private cleanupSpan(span: Span): void {\n const spanId = span.spanContext().spanId;\n\n // This span is no longer in use, so we can remove it from the cleanup\n // registry.\n this.#spanCleanup.unregister(span);\n this.#spansToExport.delete(span);\n this.#traceParents.delete(spanId);\n }\n\n /**\n * An implementation of the `onStart` method from the `SpanProcessor`\n * interface. This is called when a span is started, and is used to track\n * spans that are children of spans we care about.\n */\n onStart(span: Span): void {\n const debug = processorDebug.extend(\"onStart\");\n const spanId = span.spanContext().spanId;\n // 🤫 It seems to work\n const parentSpanId = (span as unknown as ReadableSpan).parentSpanContext\n ?.spanId;\n\n // The root span isn't captured here, but we can capture children of it\n // here.\n\n if (!parentSpanId) {\n // All spans that Inngest cares about will have a parent, so ignore this\n debug(\"no parent span ID for\", spanId, \"so skipping it\");\n\n return;\n }\n\n const parentState = this.#traceParents.get(parentSpanId);\n if (parentState) {\n // This span is a child of a span we care about, so add it to the list of\n // tracked spans so that we also capture its children\n debug(\n \"found traceparent\",\n parentState,\n \"in span ID\",\n parentSpanId,\n \"so adding\",\n spanId,\n );\n\n this.trackSpan(parentState, span);\n }\n }\n\n /**\n * An implementation of the `onEnd` method from the `SpanProcessor` interface.\n * This is called when a span ends, and is used to export spans to the Inngest\n * endpoint.\n */\n onEnd(span: ReadableSpan): void {\n const debug = processorDebug.extend(\"onEnd\");\n const spanId = span.spanContext().spanId;\n\n try {\n if (this.#spansToExport.has(span as unknown as Span)) {\n if (!this.#batcher) {\n return debug(\n \"batcher not initialized, so failed exporting span\",\n spanId,\n );\n }\n\n debug(\"exporting span\", spanId);\n return void this.#batcher.then((batcher) => batcher.onEnd(span));\n }\n\n debug(\"not exporting span\", spanId, \"as we don't care about it\");\n } finally {\n this.cleanupSpan(span as unknown as Span);\n }\n }\n\n /**\n * An implementation of the `forceFlush` method from the `SpanProcessor`\n * interface. This is called to force the processor to flush any spans that\n * are currently in the batcher. This is used to ensure that spans are\n * exported to the Inngest endpoint before the process exits.\n *\n * Notably, we call this in the `beforeResponse` middleware hook to ensure\n * that spans for a run as exported as soon as possible and before the\n * serverless process is killed.\n */\n async forceFlush(): Promise<void> {\n const flushDebug = processorDebug.extend(\"forceFlush\");\n flushDebug(\"force flushing batcher\");\n\n return this.#batcher\n ?.then((batcher) => batcher.forceFlush())\n .catch((err) => {\n flushDebug(\"error flushing batcher\", err, \"ignoring\");\n });\n }\n\n async shutdown(): Promise<void> {\n processorDebug.extend(\"shutdown\")(\"shutting down batcher\");\n\n return this.#batcher?.then((batcher) => batcher.shutdown());\n }\n}\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\nexport class PublicInngestSpanProcessor extends InngestSpanProcessor {\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n */\n app: Inngest.Like,\n ) {\n super(app);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"processor.js","names":["Debug","_resourceAttributes: Resource | undefined","#traceParents","appId: string | undefined","functionId: string | undefined","traceRef: string | undefined","#batcher","url: URL","#spanCleanup","#spansToExport","debug"],"sources":["../../../../src/components/execution/otel/processor.ts"],"sourcesContent":["import type { Span } from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport {\n detectResources,\n envDetector,\n hostDetector,\n osDetector,\n processDetector,\n type Resource,\n serviceInstanceIdDetector,\n} from \"@opentelemetry/resources\";\nimport {\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace-base\";\nimport Debug from \"debug\";\nimport {\n defaultDevServerHost,\n defaultInngestApiBaseUrl,\n} from \"../../../helpers/consts.ts\";\nimport { devServerAvailable } from \"../../../helpers/devserver.ts\";\nimport { devServerHost } from \"../../../helpers/env.ts\";\nimport type { Inngest } from \"../../Inngest.ts\";\nimport { getAsyncCtx } from \"../als.ts\";\nimport { clientProcessorMap } from \"./access.ts\";\nimport { Attribute, debugPrefix, TraceStateKey } from \"./consts.ts\";\n\nconst processorDebug = Debug(`${debugPrefix}:InngestSpanProcessor`);\n\n/**\n * A set of resource attributes that are used to identify the Inngest app and\n * the function that is being executed. This is used to store the resource\n * attributes for the spans that are exported to the Inngest endpoint, and cache\n * them for later use.\n */\nlet _resourceAttributes: Resource | undefined;\n\n/**\n * A set of information about an execution that's used to set attributes on\n * userland spans sent to Inngest for proper indexing.\n */\nexport type ParentState = {\n traceparent: string;\n runId: string;\n appId: string | undefined;\n functionId: string | undefined;\n traceRef: string | undefined;\n};\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n *\n * THIS IS THE INTERNAL IMPLEMENTATION OF THE SPAN PROCESSOR AND SHOULD NOT BE\n * USED BY USERS DIRECTLY. USE THE {@link PublicInngestSpanProcessor} CLASS\n * INSTEAD.\n */\nexport class InngestSpanProcessor implements SpanProcessor {\n /**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n *\n * It is optional here as this is the private constructor and only used\n * internally; we set `app` elsewhere as when we create the processor (as\n * early as possible when the process starts) we don't necessarily have the\n * app available yet.\n *\n * So, internally we can delay setting ths until later.\n */\n app?: Inngest.Like,\n ) {\n if (app) {\n clientProcessorMap.set(app as Inngest.Any, this);\n }\n }\n\n /**\n * A `BatchSpanProcessor` that is used to export spans to the Inngest\n * endpoint. This is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n */\n #batcher: Promise<BatchSpanProcessor> | undefined;\n\n /**\n * A set of spans used to track spans that we care about, so that we can\n * export them to the OTel endpoint.\n *\n * If a span falls out of reference, it will be removed from this set as we'll\n * never get a chance to export it or remove it anyway.\n */\n #spansToExport = new WeakSet<Span>();\n\n /**\n * A map of span IDs to their parent state, which includes a block of\n * information that can be used and pushed back to the Inngest endpoint to\n * ingest spans.\n */\n #traceParents = new Map<string, ParentState>();\n\n /**\n * A registry used to clean up items from the `traceParents` map when spans\n * fall out of reference. This is used to avoid memory leaks in the case where\n * a span is not exported, remains unended, and is left in memory before being\n * GC'd.\n */\n #spanCleanup = new FinalizationRegistry<string>((spanId) => {\n if (spanId) {\n this.#traceParents.delete(spanId);\n }\n });\n\n /**\n * In order to only capture a subset of spans, we need to declare the initial\n * span that we care about and then export its children.\n *\n * Call this method (ideally just before execution starts) with that initial\n * span to trigger capturing all following children as well as initialize the\n * batcher.\n */\n public declareStartingSpan({\n span,\n runId,\n traceparent,\n tracestate,\n }: {\n span: Span;\n runId: string;\n traceparent: string | undefined;\n tracestate: string | undefined;\n }): void {\n // Upsert the batcher ready for later. We do this here to bootstrap it with\n // the correct async context as soon as we can. As this method is only\n // called just before execution, we know we're all set up.\n //\n // Waiting to call this until we actually need the batcher would mean that\n // we might not have the correct async context set up, as we'd likely be in\n // some span lifecycle method that doesn't have the same chain of execution.\n void this.ensureBatcherInitialized();\n\n // If we don't have a traceparent, then we can't track this span. This is\n // likely a span that we don't care about, so we can ignore it.\n if (!traceparent) {\n return processorDebug(\n \"no traceparent found for span\",\n span.spanContext().spanId,\n \"so skipping it\",\n );\n }\n\n // We also attempt to use `tracestate`. The values we fetch from these\n // should be optional, as it's likely the Executor won't need us to parrot\n // them back in later versions.\n let appId: string | undefined;\n let functionId: string | undefined;\n let traceRef: string | undefined;\n\n if (tracestate) {\n try {\n const entries = Object.fromEntries(\n tracestate.split(\",\").map((kv) => kv.split(\"=\") as [string, string]),\n );\n\n appId = entries[TraceStateKey.AppId];\n functionId = entries[TraceStateKey.FunctionId];\n traceRef = entries[TraceStateKey.TraceRef];\n } catch (err) {\n processorDebug(\n \"failed to parse tracestate\",\n tracestate,\n \"so skipping it;\",\n err,\n );\n }\n }\n\n // This is a span that we care about, so let's make sure it and its\n // children are exported.\n processorDebug.extend(\"declareStartingSpan\")(\n \"declaring:\",\n span.spanContext().spanId,\n \"for traceparent\",\n traceparent,\n );\n\n // Set a load of attributes on this span so that we can nicely identify\n // runtime, paths, etc. Only this span will have these attributes.\n span.setAttributes(InngestSpanProcessor.resourceAttributes.attributes);\n\n this.trackSpan(\n {\n appId,\n functionId,\n runId,\n traceparent,\n traceRef,\n },\n span,\n );\n }\n\n /**\n * A getter for retrieving resource attributes for the current process. This\n * is used to set the resource attributes for the spans that are exported to\n * the Inngest endpoint, and cache them for later use.\n */\n static get resourceAttributes(): Resource {\n if (!_resourceAttributes) {\n _resourceAttributes = detectResources({\n detectors: [\n osDetector,\n envDetector,\n hostDetector,\n processDetector,\n serviceInstanceIdDetector,\n ],\n });\n }\n\n return _resourceAttributes;\n }\n\n /**\n * The batcher is a singleton that is used to export spans to the OTel\n * endpoint. It is created lazily to avoid creating it until the Inngest App\n * has been initialized and has had a chance to receive environment variables,\n * which may be from an incoming request.\n *\n * The batcher is only referenced once we've found a span we're interested in,\n * so this should always have everything it needs on the app by then.\n */\n private ensureBatcherInitialized(): Promise<BatchSpanProcessor> {\n if (!this.#batcher) {\n this.#batcher = new Promise(async (resolve, reject) => {\n try {\n // We retrieve the app from the async context, so we must make sure\n // that this function is called from the correct chain.\n const store = await getAsyncCtx();\n if (!store) {\n throw new Error(\n \"No async context found; cannot create batcher to export traces\",\n );\n }\n\n const app = store.app as Inngest.Any;\n\n // Fetch the URL for the Inngest endpoint using the app's config.\n let url: URL;\n const path = \"/v1/traces/userland\";\n if (app.apiBaseUrl) {\n url = new URL(path, app.apiBaseUrl);\n } else {\n url = new URL(path, defaultInngestApiBaseUrl);\n\n if (app[\"mode\"] && app[\"mode\"].isDev && app[\"mode\"].isInferred) {\n const devHost = devServerHost() || defaultDevServerHost;\n const hasDevServer = await devServerAvailable(\n devHost,\n app[\"fetch\"],\n );\n if (hasDevServer) {\n url = new URL(path, devHost);\n }\n } else if (app[\"mode\"]?.explicitDevUrl) {\n url = new URL(path, app[\"mode\"].explicitDevUrl.href);\n }\n }\n\n processorDebug(\n \"batcher lazily accessed; creating new batcher with URL\",\n url,\n );\n\n const exporter = new OTLPTraceExporter({\n url: url.href,\n\n headers: {\n ...app[\"headers\"],\n Authorization: `Bearer ${app[\"inngestApi\"][\"signingKey\"]}`,\n },\n });\n\n resolve(new BatchSpanProcessor(exporter));\n } catch (err) {\n reject(err);\n }\n });\n }\n\n return this.#batcher;\n }\n\n /**\n * Mark a span as being tracked by this processor, meaning it will be exported\n * to the Inggest endpoint when it ends.\n */\n private trackSpan(parentState: ParentState, span: Span): void {\n const spanId = span.spanContext().spanId;\n\n this.#spanCleanup.register(span, spanId, span);\n this.#spansToExport.add(span);\n this.#traceParents.set(spanId, parentState);\n\n span.setAttribute(Attribute.InngestTraceparent, parentState.traceparent);\n span.setAttribute(Attribute.InngestRunId, parentState.runId);\n\n // Setting app ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.appId) {\n span.setAttribute(Attribute.InngestAppId1, parentState.appId);\n span.setAttribute(Attribute.InngestAppId2, parentState.appId);\n }\n\n // Setting function ID is optional; it's likely in future versions of the\n // Executor that we don't need to parrot this back.\n if (parentState.functionId) {\n span.setAttribute(Attribute.InngestFunctionId, parentState.functionId);\n }\n\n if (parentState.traceRef) {\n span.setAttribute(Attribute.InngestTraceRef, parentState.traceRef);\n }\n }\n\n /**\n * Clean up any references to a span that has ended. This is used to avoid\n * memory leaks in the case where a span is not exported, remains unended, and\n * is left in memory before being GC'd.\n */\n private cleanupSpan(span: Span): void {\n const spanId = span.spanContext().spanId;\n\n // This span is no longer in use, so we can remove it from the cleanup\n // registry.\n this.#spanCleanup.unregister(span);\n this.#spansToExport.delete(span);\n this.#traceParents.delete(spanId);\n }\n\n /**\n * An implementation of the `onStart` method from the `SpanProcessor`\n * interface. This is called when a span is started, and is used to track\n * spans that are children of spans we care about.\n */\n onStart(span: Span): void {\n const debug = processorDebug.extend(\"onStart\");\n const spanId = span.spanContext().spanId;\n // 🤫 It seems to work\n const parentSpanId = (span as unknown as ReadableSpan).parentSpanContext\n ?.spanId;\n\n // The root span isn't captured here, but we can capture children of it\n // here.\n\n if (!parentSpanId) {\n // All spans that Inngest cares about will have a parent, so ignore this\n debug(\"no parent span ID for\", spanId, \"so skipping it\");\n\n return;\n }\n\n const parentState = this.#traceParents.get(parentSpanId);\n if (parentState) {\n // This span is a child of a span we care about, so add it to the list of\n // tracked spans so that we also capture its children\n debug(\n \"found traceparent\",\n parentState,\n \"in span ID\",\n parentSpanId,\n \"so adding\",\n spanId,\n );\n\n this.trackSpan(parentState, span);\n }\n }\n\n /**\n * An implementation of the `onEnd` method from the `SpanProcessor` interface.\n * This is called when a span ends, and is used to export spans to the Inngest\n * endpoint.\n */\n onEnd(span: ReadableSpan): void {\n const debug = processorDebug.extend(\"onEnd\");\n const spanId = span.spanContext().spanId;\n\n try {\n if (this.#spansToExport.has(span as unknown as Span)) {\n if (!this.#batcher) {\n return debug(\n \"batcher not initialized, so failed exporting span\",\n spanId,\n );\n }\n\n debug(\"exporting span\", spanId);\n return void this.#batcher.then((batcher) => batcher.onEnd(span));\n }\n\n debug(\"not exporting span\", spanId, \"as we don't care about it\");\n } finally {\n this.cleanupSpan(span as unknown as Span);\n }\n }\n\n /**\n * An implementation of the `forceFlush` method from the `SpanProcessor`\n * interface. This is called to force the processor to flush any spans that\n * are currently in the batcher. This is used to ensure that spans are\n * exported to the Inngest endpoint before the process exits.\n *\n * Notably, we call this in the `beforeResponse` middleware hook to ensure\n * that spans for a run as exported as soon as possible and before the\n * serverless process is killed.\n */\n async forceFlush(): Promise<void> {\n const flushDebug = processorDebug.extend(\"forceFlush\");\n flushDebug(\"force flushing batcher\");\n\n return this.#batcher\n ?.then((batcher) => batcher.forceFlush())\n .catch((err) => {\n flushDebug(\"error flushing batcher\", err, \"ignoring\");\n });\n }\n\n async shutdown(): Promise<void> {\n processorDebug.extend(\"shutdown\")(\"shutting down batcher\");\n\n return this.#batcher?.then((batcher) => batcher.shutdown());\n }\n}\n\n/**\n * An OTel span processor that is used to export spans to the Inngest endpoint.\n * This is used to track spans that are created within an Inngest run and export\n * them to the Inngest endpoint for tracing.\n *\n * It's careful to only pick relevant spans to export and will not send any\n * irrelevant spans to the Inngest endpoint.\n */\nexport class PublicInngestSpanProcessor extends InngestSpanProcessor {\n constructor(\n /**\n * The app that this span processor is associated with. This is used to\n * determine the Inngest endpoint to export spans to.\n */\n app: Inngest.Like,\n ) {\n super(app);\n }\n}\n"],"mappings":"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"}
package/h3.cjs CHANGED
@@ -1,4 +1,5 @@
1
1
  const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const require_strings = require('./helpers/strings.cjs');
2
3
  const require_env = require('./helpers/env.cjs');
3
4
  const require_InngestCommHandler = require('./components/InngestCommHandler.cjs');
4
5
  let h3 = require("h3");
@@ -37,6 +38,50 @@ let h3 = require("h3");
37
38
  * dashboards and during testing.
38
39
  */
39
40
  const frameworkName = "h3";
41
+ const commHandler = (options, syncOptions) => {
42
+ return new require_InngestCommHandler.InngestCommHandler({
43
+ frameworkName,
44
+ ...options,
45
+ syncOptions,
46
+ handler: (event) => {
47
+ return {
48
+ body: () => (0, h3.readBody)(event),
49
+ textBody: async () => {
50
+ const method = event.method;
51
+ return method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE" ? await (0, h3.readRawBody)(event, "utf-8") ?? "" : "";
52
+ },
53
+ headers: (key) => (0, h3.getHeader)(event, key),
54
+ method: () => event.method,
55
+ url: () => {
56
+ let scheme = "https";
57
+ if ((require_env.processEnv("NODE_ENV") ?? "dev").startsWith("dev")) scheme = "http";
58
+ return new URL(String(event.path), `${scheme}://${String((0, h3.getHeader)(event, "host"))}`);
59
+ },
60
+ queryString: (key) => {
61
+ const param = (0, h3.getQuery)(event)[key];
62
+ if (param) return String(param);
63
+ },
64
+ transformResponse: (actionRes) => {
65
+ const { res } = event.node;
66
+ res.statusCode = actionRes.status;
67
+ (0, h3.setHeaders)(event, actionRes.headers);
68
+ return (0, h3.send)(event, actionRes.body);
69
+ },
70
+ experimentalTransformSyncResponse: async (data) => {
71
+ const headers = Object.entries((0, h3.getResponseHeaders)(event) ?? {}).reduce((acc, [key, value]) => {
72
+ acc[key] = Array.isArray(value) ? value.join(",") : `${value}`;
73
+ return acc;
74
+ }, {});
75
+ return {
76
+ body: typeof data === "string" ? data : require_strings.stringify(data),
77
+ headers,
78
+ status: (0, h3.getResponseStatus)(event) ?? 200
79
+ };
80
+ }
81
+ };
82
+ }
83
+ });
84
+ };
40
85
  /**
41
86
  * In h3, serve and register any declared functions with Inngest, making
42
87
  * them available to be triggered by events.
@@ -66,35 +111,45 @@ const frameworkName = "h3";
66
111
  * @public
67
112
  */
68
113
  const serve = (options) => {
69
- return new require_InngestCommHandler.InngestCommHandler({
70
- frameworkName,
71
- ...options,
72
- handler: (event) => {
73
- return {
74
- body: () => (0, h3.readBody)(event),
75
- headers: (key) => (0, h3.getHeader)(event, key),
76
- method: () => event.method,
77
- url: () => {
78
- let scheme = "https";
79
- if ((require_env.processEnv("NODE_ENV") ?? "dev").startsWith("dev")) scheme = "http";
80
- return new URL(String(event.path), `${scheme}://${String((0, h3.getHeader)(event, "host"))}`);
81
- },
82
- queryString: (key) => {
83
- const param = (0, h3.getQuery)(event)[key];
84
- if (param) return String(param);
85
- },
86
- transformResponse: (actionRes) => {
87
- const { res } = event.node;
88
- res.statusCode = actionRes.status;
89
- (0, h3.setHeaders)(event, actionRes.headers);
90
- return (0, h3.send)(event, actionRes.body);
91
- }
92
- };
93
- }
94
- }).createHandler();
114
+ return commHandler(options).createHandler();
115
+ };
116
+ /**
117
+ * In h3, create a function that can define an event handler with Inngest steps
118
+ * enabled, allowing you to use steps seamlessly within that API.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * import { Inngest, step } from "inngest";
123
+ * import { createExperimentalEndpointWrapper } from "inngest/h3";
124
+ *
125
+ * const inngestEventHandler = createExperimentalEndpointWrapper({
126
+ * client: new Inngest({ id: "h3-sync-example" }),
127
+ * });
128
+ *
129
+ *
130
+ * export default inngestEventHandler(async (event) => {
131
+ * const foo = await step.run("example/step", async () => {
132
+ * return "Hello from step!";
133
+ * });
134
+ *
135
+ * return `
136
+ * <meta charset="utf-8">
137
+ * <h1>This endpoint worked!</h1>
138
+ * <p>The step's result was: ${foo}</p>
139
+ * `;
140
+ * });
141
+ * ```
142
+ */
143
+ const createExperimentalEndpointWrapper = (options) => {
144
+ const inngestWrapper = commHandler(options, options).createSyncHandler();
145
+ const h3Handler = (userlandHandler) => {
146
+ return (0, h3.defineEventHandler)(inngestWrapper(userlandHandler));
147
+ };
148
+ return h3Handler;
95
149
  };
96
150
 
97
151
  //#endregion
152
+ exports.createExperimentalEndpointWrapper = createExperimentalEndpointWrapper;
98
153
  exports.frameworkName = frameworkName;
99
154
  exports.serve = serve;
100
155
  //# sourceMappingURL=h3.cjs.map
package/h3.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"h3.cjs","names":["frameworkName: SupportedFrameworkName","InngestCommHandler","processEnv"],"sources":["../src/h3.ts"],"sourcesContent":["/**\n * An adapter for H3 to serve and register any declared functions with Inngest,\n * making them available to be triggered by events.\n *\n * @example\n * ```ts\n * import { createApp, eventHandler, toNodeListener } from \"h3\";\n * import { serve } from \"inngest/h3\";\n * import { createServer } from \"node:http\";\n * import { inngest } from \"./inngest/client\";\n * import fnA from \"./inngest/fnA\";\n *\n * const app = createApp();\n * app.use(\n * \"/api/inngest\",\n * eventHandler(\n * serve({\n * client: inngest,\n * functions: [fnA],\n * })\n * )\n * );\n *\n * createServer(toNodeListener(app)).listen(process.env.PORT || 3000);\n * ```\n *\n * @module\n */\n\nimport {\n type EventHandlerRequest,\n getHeader,\n getQuery,\n type H3Event,\n readBody,\n send,\n setHeaders,\n} from \"h3\";\nimport {\n InngestCommHandler,\n type ServeHandlerOptions,\n} from \"./components/InngestCommHandler.ts\";\nimport { processEnv } from \"./helpers/env.ts\";\nimport type { SupportedFrameworkName } from \"./types.ts\";\n\n/**\n * The name of the framework, used to identify the framework in Inngest\n * dashboards and during testing.\n */\nexport const frameworkName: SupportedFrameworkName = \"h3\";\n\n/**\n * In h3, serve and register any declared functions with Inngest, making\n * them available to be triggered by events.\n *\n * @example\n * ```ts\n * import { createApp, eventHandler, toNodeListener } from \"h3\";\n * import { serve } from \"inngest/h3\";\n * import { createServer } from \"node:http\";\n * import { inngest } from \"./inngest/client\";\n * import fnA from \"./inngest/fnA\";\n *\n * const app = createApp();\n * app.use(\n * \"/api/inngest\",\n * eventHandler(\n * serve({\n * client: inngest,\n * functions: [fnA],\n * })\n * )\n * );\n *\n * createServer(toNodeListener(app)).listen(process.env.PORT || 3000);\n * ```\n *\n * @public\n */\n// Has explicit return type to avoid JSR-defined \"slow types\"\nexport const serve = (\n options: ServeHandlerOptions,\n): ((event: H3Event<EventHandlerRequest>) => Promise<void>) => {\n const handler = new InngestCommHandler({\n frameworkName,\n ...options,\n handler: (event: H3Event<EventHandlerRequest>) => {\n return {\n body: () => readBody(event),\n headers: (key) => getHeader(event, key),\n method: () => event.method,\n url: () => {\n let scheme = \"https\";\n if ((processEnv(\"NODE_ENV\") ?? \"dev\").startsWith(\"dev\")) {\n scheme = \"http\";\n }\n\n return new URL(\n String(event.path),\n `${scheme}://${String(getHeader(event, \"host\"))}`,\n );\n },\n queryString: (key) => {\n const param = getQuery(event)[key];\n if (param) {\n return String(param);\n }\n\n return;\n },\n transformResponse: (actionRes) => {\n const { res } = event.node;\n res.statusCode = actionRes.status;\n setHeaders(event, actionRes.headers);\n return send(event, actionRes.body);\n },\n };\n },\n });\n\n return handler.createHandler();\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,MAAaA,gBAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BrD,MAAa,SACX,YAC6D;AAsC7D,QArCgB,IAAIC,8CAAmB;EACrC;EACA,GAAG;EACH,UAAU,UAAwC;AAChD,UAAO;IACL,6BAAqB,MAAM;IAC3B,UAAU,0BAAkB,OAAO,IAAI;IACvC,cAAc,MAAM;IACpB,WAAW;KACT,IAAI,SAAS;AACb,UAAKC,uBAAW,WAAW,IAAI,OAAO,WAAW,MAAM,CACrD,UAAS;AAGX,YAAO,IAAI,IACT,OAAO,MAAM,KAAK,EAClB,GAAG,OAAO,KAAK,yBAAiB,OAAO,OAAO,CAAC,GAChD;;IAEH,cAAc,QAAQ;KACpB,MAAM,yBAAiB,MAAM,CAAC;AAC9B,SAAI,MACF,QAAO,OAAO,MAAM;;IAKxB,oBAAoB,cAAc;KAChC,MAAM,EAAE,QAAQ,MAAM;AACtB,SAAI,aAAa,UAAU;AAC3B,wBAAW,OAAO,UAAU,QAAQ;AACpC,yBAAY,OAAO,UAAU,KAAK;;IAErC;;EAEJ,CAAC,CAEa,eAAe"}
1
+ {"version":3,"file":"h3.cjs","names":["frameworkName: SupportedFrameworkName","InngestCommHandler","processEnv","stringify","h3Handler: typeof inngestWrapper"],"sources":["../src/h3.ts"],"sourcesContent":["/**\n * An adapter for H3 to serve and register any declared functions with Inngest,\n * making them available to be triggered by events.\n *\n * @example\n * ```ts\n * import { createApp, eventHandler, toNodeListener } from \"h3\";\n * import { serve } from \"inngest/h3\";\n * import { createServer } from \"node:http\";\n * import { inngest } from \"./inngest/client\";\n * import fnA from \"./inngest/fnA\";\n *\n * const app = createApp();\n * app.use(\n * \"/api/inngest\",\n * eventHandler(\n * serve({\n * client: inngest,\n * functions: [fnA],\n * })\n * )\n * );\n *\n * createServer(toNodeListener(app)).listen(process.env.PORT || 3000);\n * ```\n *\n * @module\n */\n\nimport {\n defineEventHandler,\n type EventHandlerRequest,\n type EventHandlerResponse,\n getHeader,\n getQuery,\n getResponseHeaders,\n getResponseStatus,\n type H3Event,\n readBody,\n readRawBody,\n send,\n setHeaders,\n} from \"h3\";\nimport type { Inngest } from \"./components/Inngest.ts\";\nimport {\n InngestCommHandler,\n type ServeHandlerOptions,\n type SyncHandlerOptions,\n} from \"./components/InngestCommHandler.ts\";\nimport { processEnv } from \"./helpers/env.ts\";\nimport { stringify } from \"./helpers/strings.ts\";\nimport type { RegisterOptions, SupportedFrameworkName } from \"./types.ts\";\n\n/**\n * The name of the framework, used to identify the framework in Inngest\n * dashboards and during testing.\n */\nexport const frameworkName: SupportedFrameworkName = \"h3\";\n\nconst commHandler = (\n options: RegisterOptions & { client: Inngest.Like },\n syncOptions?: SyncHandlerOptions,\n) => {\n const handler = new InngestCommHandler({\n frameworkName,\n ...options,\n syncOptions,\n handler: (event: H3Event<EventHandlerRequest>) => {\n return {\n body: () => readBody(event),\n textBody: async () => {\n const method = event.method;\n const body =\n method === \"POST\" ||\n method === \"PUT\" ||\n method === \"PATCH\" ||\n method === \"DELETE\"\n ? ((await readRawBody(event, \"utf-8\")) ?? \"\")\n : \"\";\n\n return body;\n },\n headers: (key) => getHeader(event, key),\n method: () => event.method,\n url: () => {\n let scheme = \"https\";\n if ((processEnv(\"NODE_ENV\") ?? \"dev\").startsWith(\"dev\")) {\n scheme = \"http\";\n }\n\n return new URL(\n String(event.path),\n `${scheme}://${String(getHeader(event, \"host\"))}`,\n );\n },\n queryString: (key) => {\n const param = getQuery(event)[key];\n if (param) {\n return String(param);\n }\n\n return;\n },\n transformResponse: (actionRes): EventHandlerResponse => {\n const { res } = event.node;\n res.statusCode = actionRes.status;\n setHeaders(event, actionRes.headers);\n return send(event, actionRes.body);\n },\n experimentalTransformSyncResponse: async (data) => {\n const headers = Object.entries(\n getResponseHeaders(event) ?? {},\n ).reduce(\n (acc, [key, value]) => {\n acc[key] = Array.isArray(value) ? value.join(\",\") : `${value}`;\n\n return acc;\n },\n {} as Record<string, string>,\n );\n\n return {\n body: typeof data === \"string\" ? data : stringify(data),\n headers,\n status: getResponseStatus(event) ?? 200,\n };\n },\n };\n },\n });\n\n return handler;\n};\n\n/**\n * In h3, serve and register any declared functions with Inngest, making\n * them available to be triggered by events.\n *\n * @example\n * ```ts\n * import { createApp, eventHandler, toNodeListener } from \"h3\";\n * import { serve } from \"inngest/h3\";\n * import { createServer } from \"node:http\";\n * import { inngest } from \"./inngest/client\";\n * import fnA from \"./inngest/fnA\";\n *\n * const app = createApp();\n * app.use(\n * \"/api/inngest\",\n * eventHandler(\n * serve({\n * client: inngest,\n * functions: [fnA],\n * })\n * )\n * );\n *\n * createServer(toNodeListener(app)).listen(process.env.PORT || 3000);\n * ```\n *\n * @public\n */\n// Has explicit return type to avoid JSR-defined \"slow types\"\nexport const serve = (\n options: ServeHandlerOptions,\n): ((event: H3Event<EventHandlerRequest>) => Promise<void>) => {\n return commHandler(options).createHandler();\n};\n\n/**\n * In h3, create a function that can define an event handler with Inngest steps\n * enabled, allowing you to use steps seamlessly within that API.\n *\n * @example\n * ```ts\n * import { Inngest, step } from \"inngest\";\n * import { createExperimentalEndpointWrapper } from \"inngest/h3\";\n *\n * const inngestEventHandler = createExperimentalEndpointWrapper({\n * client: new Inngest({ id: \"h3-sync-example\" }),\n * });\n *\n *\n * export default inngestEventHandler(async (event) => {\n * const foo = await step.run(\"example/step\", async () => {\n * return \"Hello from step!\";\n * });\n *\n * return `\n * <meta charset=\"utf-8\">\n * <h1>This endpoint worked!</h1>\n * <p>The step's result was: ${foo}</p>\n * `;\n * });\n * ```\n */\nexport const createExperimentalEndpointWrapper = (\n options: SyncHandlerOptions,\n) => {\n const inngestWrapper = commHandler(options, options).createSyncHandler();\n\n const h3Handler: typeof inngestWrapper = (userlandHandler) => {\n return defineEventHandler(inngestWrapper(userlandHandler));\n };\n\n return h3Handler;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,MAAaA,gBAAwC;AAErD,MAAM,eACJ,SACA,gBACG;AAqEH,QApEgB,IAAIC,8CAAmB;EACrC;EACA,GAAG;EACH;EACA,UAAU,UAAwC;AAChD,UAAO;IACL,6BAAqB,MAAM;IAC3B,UAAU,YAAY;KACpB,MAAM,SAAS,MAAM;AASrB,YAPE,WAAW,UACX,WAAW,SACX,WAAW,WACX,WAAW,WACL,0BAAkB,OAAO,QAAQ,IAAK,KACxC;;IAIR,UAAU,0BAAkB,OAAO,IAAI;IACvC,cAAc,MAAM;IACpB,WAAW;KACT,IAAI,SAAS;AACb,UAAKC,uBAAW,WAAW,IAAI,OAAO,WAAW,MAAM,CACrD,UAAS;AAGX,YAAO,IAAI,IACT,OAAO,MAAM,KAAK,EAClB,GAAG,OAAO,KAAK,yBAAiB,OAAO,OAAO,CAAC,GAChD;;IAEH,cAAc,QAAQ;KACpB,MAAM,yBAAiB,MAAM,CAAC;AAC9B,SAAI,MACF,QAAO,OAAO,MAAM;;IAKxB,oBAAoB,cAAoC;KACtD,MAAM,EAAE,QAAQ,MAAM;AACtB,SAAI,aAAa,UAAU;AAC3B,wBAAW,OAAO,UAAU,QAAQ;AACpC,yBAAY,OAAO,UAAU,KAAK;;IAEpC,mCAAmC,OAAO,SAAS;KACjD,MAAM,UAAU,OAAO,mCACF,MAAM,IAAI,EAAE,CAChC,CAAC,QACC,KAAK,CAAC,KAAK,WAAW;AACrB,UAAI,OAAO,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,IAAI,GAAG,GAAG;AAEvD,aAAO;QAET,EAAE,CACH;AAED,YAAO;MACL,MAAM,OAAO,SAAS,WAAW,OAAOC,0BAAU,KAAK;MACvD;MACA,kCAA0B,MAAM,IAAI;MACrC;;IAEJ;;EAEJ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCJ,MAAa,SACX,YAC6D;AAC7D,QAAO,YAAY,QAAQ,CAAC,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8B7C,MAAa,qCACX,YACG;CACH,MAAM,iBAAiB,YAAY,SAAS,QAAQ,CAAC,mBAAmB;CAExE,MAAMC,aAAoC,oBAAoB;AAC5D,oCAA0B,eAAe,gBAAgB,CAAC;;AAG5D,QAAO"}
package/h3.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { SupportedFrameworkName } from "./types.cjs";
2
- import { ServeHandlerOptions } from "./components/InngestCommHandler.cjs";
2
+ import { ServeHandlerOptions, SyncHandlerOptions } from "./components/InngestCommHandler.cjs";
3
3
  import { EventHandlerRequest, H3Event } from "h3";
4
4
 
5
5
  //#region src/h3.d.ts
@@ -38,6 +38,34 @@ declare const frameworkName: SupportedFrameworkName;
38
38
  * @public
39
39
  */
40
40
  declare const serve: (options: ServeHandlerOptions) => ((event: H3Event<EventHandlerRequest>) => Promise<void>);
41
+ /**
42
+ * In h3, create a function that can define an event handler with Inngest steps
43
+ * enabled, allowing you to use steps seamlessly within that API.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * import { Inngest, step } from "inngest";
48
+ * import { createExperimentalEndpointWrapper } from "inngest/h3";
49
+ *
50
+ * const inngestEventHandler = createExperimentalEndpointWrapper({
51
+ * client: new Inngest({ id: "h3-sync-example" }),
52
+ * });
53
+ *
54
+ *
55
+ * export default inngestEventHandler(async (event) => {
56
+ * const foo = await step.run("example/step", async () => {
57
+ * return "Hello from step!";
58
+ * });
59
+ *
60
+ * return `
61
+ * <meta charset="utf-8">
62
+ * <h1>This endpoint worked!</h1>
63
+ * <p>The step's result was: ${foo}</p>
64
+ * `;
65
+ * });
66
+ * ```
67
+ */
68
+ declare const createExperimentalEndpointWrapper: (options: SyncHandlerOptions) => (handler: (event: H3Event<EventHandlerRequest>) => Promise<any>) => (event: H3Event<EventHandlerRequest>) => Promise<any>;
41
69
  //#endregion
42
- export { frameworkName, serve };
70
+ export { createExperimentalEndpointWrapper, frameworkName, serve };
43
71
  //# sourceMappingURL=h3.d.cts.map
package/h3.d.cts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"h3.d.cts","names":[],"sources":["../src/h3.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAiDa,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA+Bf,iBACF,iCACC,QAAQ,yBAAyB"}
1
+ {"version":3,"file":"h3.d.cts","names":[],"sources":["../src/h3.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAyDa,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA0Gf,iBACF,iCACC,QAAQ,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA+BhC,6CACF,yCAAkB,QAAA,yBAAA,yBAAA,QAAA,yBAAA"}
package/h3.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { SupportedFrameworkName } from "./types.js";
2
- import { ServeHandlerOptions } from "./components/InngestCommHandler.js";
2
+ import { ServeHandlerOptions, SyncHandlerOptions } from "./components/InngestCommHandler.js";
3
3
  import { EventHandlerRequest, H3Event } from "h3";
4
4
 
5
5
  //#region src/h3.d.ts
@@ -38,6 +38,34 @@ declare const frameworkName: SupportedFrameworkName;
38
38
  * @public
39
39
  */
40
40
  declare const serve: (options: ServeHandlerOptions) => ((event: H3Event<EventHandlerRequest>) => Promise<void>);
41
+ /**
42
+ * In h3, create a function that can define an event handler with Inngest steps
43
+ * enabled, allowing you to use steps seamlessly within that API.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * import { Inngest, step } from "inngest";
48
+ * import { createExperimentalEndpointWrapper } from "inngest/h3";
49
+ *
50
+ * const inngestEventHandler = createExperimentalEndpointWrapper({
51
+ * client: new Inngest({ id: "h3-sync-example" }),
52
+ * });
53
+ *
54
+ *
55
+ * export default inngestEventHandler(async (event) => {
56
+ * const foo = await step.run("example/step", async () => {
57
+ * return "Hello from step!";
58
+ * });
59
+ *
60
+ * return `
61
+ * <meta charset="utf-8">
62
+ * <h1>This endpoint worked!</h1>
63
+ * <p>The step's result was: ${foo}</p>
64
+ * `;
65
+ * });
66
+ * ```
67
+ */
68
+ declare const createExperimentalEndpointWrapper: (options: SyncHandlerOptions) => (handler: (event: H3Event<EventHandlerRequest>) => Promise<any>) => (event: H3Event<EventHandlerRequest>) => Promise<any>;
41
69
  //#endregion
42
- export { frameworkName, serve };
70
+ export { createExperimentalEndpointWrapper, frameworkName, serve };
43
71
  //# sourceMappingURL=h3.d.ts.map
package/h3.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"h3.d.ts","names":[],"sources":["../src/h3.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAiDa,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA+Bf,iBACF,iCACC,QAAQ,yBAAyB"}
1
+ {"version":3,"file":"h3.d.ts","names":[],"sources":["../src/h3.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAyDa,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA0Gf,iBACF,iCACC,QAAQ,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA+BhC,6CACF,yCAAkB,QAAA,yBAAA,yBAAA,QAAA,yBAAA"}
package/h3.js CHANGED
@@ -1,6 +1,7 @@
1
+ import { stringify } from "./helpers/strings.js";
1
2
  import { processEnv } from "./helpers/env.js";
2
3
  import { InngestCommHandler } from "./components/InngestCommHandler.js";
3
- import { getHeader, getQuery, readBody, send, setHeaders } from "h3";
4
+ import { defineEventHandler, getHeader, getQuery, getResponseHeaders, getResponseStatus, readBody, readRawBody, send, setHeaders } from "h3";
4
5
 
5
6
  //#region src/h3.ts
6
7
  /**
@@ -36,6 +37,50 @@ import { getHeader, getQuery, readBody, send, setHeaders } from "h3";
36
37
  * dashboards and during testing.
37
38
  */
38
39
  const frameworkName = "h3";
40
+ const commHandler = (options, syncOptions) => {
41
+ return new InngestCommHandler({
42
+ frameworkName,
43
+ ...options,
44
+ syncOptions,
45
+ handler: (event) => {
46
+ return {
47
+ body: () => readBody(event),
48
+ textBody: async () => {
49
+ const method = event.method;
50
+ return method === "POST" || method === "PUT" || method === "PATCH" || method === "DELETE" ? await readRawBody(event, "utf-8") ?? "" : "";
51
+ },
52
+ headers: (key) => getHeader(event, key),
53
+ method: () => event.method,
54
+ url: () => {
55
+ let scheme = "https";
56
+ if ((processEnv("NODE_ENV") ?? "dev").startsWith("dev")) scheme = "http";
57
+ return new URL(String(event.path), `${scheme}://${String(getHeader(event, "host"))}`);
58
+ },
59
+ queryString: (key) => {
60
+ const param = getQuery(event)[key];
61
+ if (param) return String(param);
62
+ },
63
+ transformResponse: (actionRes) => {
64
+ const { res } = event.node;
65
+ res.statusCode = actionRes.status;
66
+ setHeaders(event, actionRes.headers);
67
+ return send(event, actionRes.body);
68
+ },
69
+ experimentalTransformSyncResponse: async (data) => {
70
+ const headers = Object.entries(getResponseHeaders(event) ?? {}).reduce((acc, [key, value]) => {
71
+ acc[key] = Array.isArray(value) ? value.join(",") : `${value}`;
72
+ return acc;
73
+ }, {});
74
+ return {
75
+ body: typeof data === "string" ? data : stringify(data),
76
+ headers,
77
+ status: getResponseStatus(event) ?? 200
78
+ };
79
+ }
80
+ };
81
+ }
82
+ });
83
+ };
39
84
  /**
40
85
  * In h3, serve and register any declared functions with Inngest, making
41
86
  * them available to be triggered by events.
@@ -65,34 +110,43 @@ const frameworkName = "h3";
65
110
  * @public
66
111
  */
67
112
  const serve = (options) => {
68
- return new InngestCommHandler({
69
- frameworkName,
70
- ...options,
71
- handler: (event) => {
72
- return {
73
- body: () => readBody(event),
74
- headers: (key) => getHeader(event, key),
75
- method: () => event.method,
76
- url: () => {
77
- let scheme = "https";
78
- if ((processEnv("NODE_ENV") ?? "dev").startsWith("dev")) scheme = "http";
79
- return new URL(String(event.path), `${scheme}://${String(getHeader(event, "host"))}`);
80
- },
81
- queryString: (key) => {
82
- const param = getQuery(event)[key];
83
- if (param) return String(param);
84
- },
85
- transformResponse: (actionRes) => {
86
- const { res } = event.node;
87
- res.statusCode = actionRes.status;
88
- setHeaders(event, actionRes.headers);
89
- return send(event, actionRes.body);
90
- }
91
- };
92
- }
93
- }).createHandler();
113
+ return commHandler(options).createHandler();
114
+ };
115
+ /**
116
+ * In h3, create a function that can define an event handler with Inngest steps
117
+ * enabled, allowing you to use steps seamlessly within that API.
118
+ *
119
+ * @example
120
+ * ```ts
121
+ * import { Inngest, step } from "inngest";
122
+ * import { createExperimentalEndpointWrapper } from "inngest/h3";
123
+ *
124
+ * const inngestEventHandler = createExperimentalEndpointWrapper({
125
+ * client: new Inngest({ id: "h3-sync-example" }),
126
+ * });
127
+ *
128
+ *
129
+ * export default inngestEventHandler(async (event) => {
130
+ * const foo = await step.run("example/step", async () => {
131
+ * return "Hello from step!";
132
+ * });
133
+ *
134
+ * return `
135
+ * <meta charset="utf-8">
136
+ * <h1>This endpoint worked!</h1>
137
+ * <p>The step's result was: ${foo}</p>
138
+ * `;
139
+ * });
140
+ * ```
141
+ */
142
+ const createExperimentalEndpointWrapper = (options) => {
143
+ const inngestWrapper = commHandler(options, options).createSyncHandler();
144
+ const h3Handler = (userlandHandler) => {
145
+ return defineEventHandler(inngestWrapper(userlandHandler));
146
+ };
147
+ return h3Handler;
94
148
  };
95
149
 
96
150
  //#endregion
97
- export { frameworkName, serve };
151
+ export { createExperimentalEndpointWrapper, frameworkName, serve };
98
152
  //# sourceMappingURL=h3.js.map
package/h3.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"h3.js","names":["frameworkName: SupportedFrameworkName"],"sources":["../src/h3.ts"],"sourcesContent":["/**\n * An adapter for H3 to serve and register any declared functions with Inngest,\n * making them available to be triggered by events.\n *\n * @example\n * ```ts\n * import { createApp, eventHandler, toNodeListener } from \"h3\";\n * import { serve } from \"inngest/h3\";\n * import { createServer } from \"node:http\";\n * import { inngest } from \"./inngest/client\";\n * import fnA from \"./inngest/fnA\";\n *\n * const app = createApp();\n * app.use(\n * \"/api/inngest\",\n * eventHandler(\n * serve({\n * client: inngest,\n * functions: [fnA],\n * })\n * )\n * );\n *\n * createServer(toNodeListener(app)).listen(process.env.PORT || 3000);\n * ```\n *\n * @module\n */\n\nimport {\n type EventHandlerRequest,\n getHeader,\n getQuery,\n type H3Event,\n readBody,\n send,\n setHeaders,\n} from \"h3\";\nimport {\n InngestCommHandler,\n type ServeHandlerOptions,\n} from \"./components/InngestCommHandler.ts\";\nimport { processEnv } from \"./helpers/env.ts\";\nimport type { SupportedFrameworkName } from \"./types.ts\";\n\n/**\n * The name of the framework, used to identify the framework in Inngest\n * dashboards and during testing.\n */\nexport const frameworkName: SupportedFrameworkName = \"h3\";\n\n/**\n * In h3, serve and register any declared functions with Inngest, making\n * them available to be triggered by events.\n *\n * @example\n * ```ts\n * import { createApp, eventHandler, toNodeListener } from \"h3\";\n * import { serve } from \"inngest/h3\";\n * import { createServer } from \"node:http\";\n * import { inngest } from \"./inngest/client\";\n * import fnA from \"./inngest/fnA\";\n *\n * const app = createApp();\n * app.use(\n * \"/api/inngest\",\n * eventHandler(\n * serve({\n * client: inngest,\n * functions: [fnA],\n * })\n * )\n * );\n *\n * createServer(toNodeListener(app)).listen(process.env.PORT || 3000);\n * ```\n *\n * @public\n */\n// Has explicit return type to avoid JSR-defined \"slow types\"\nexport const serve = (\n options: ServeHandlerOptions,\n): ((event: H3Event<EventHandlerRequest>) => Promise<void>) => {\n const handler = new InngestCommHandler({\n frameworkName,\n ...options,\n handler: (event: H3Event<EventHandlerRequest>) => {\n return {\n body: () => readBody(event),\n headers: (key) => getHeader(event, key),\n method: () => event.method,\n url: () => {\n let scheme = \"https\";\n if ((processEnv(\"NODE_ENV\") ?? \"dev\").startsWith(\"dev\")) {\n scheme = \"http\";\n }\n\n return new URL(\n String(event.path),\n `${scheme}://${String(getHeader(event, \"host\"))}`,\n );\n },\n queryString: (key) => {\n const param = getQuery(event)[key];\n if (param) {\n return String(param);\n }\n\n return;\n },\n transformResponse: (actionRes) => {\n const { res } = event.node;\n res.statusCode = actionRes.status;\n setHeaders(event, actionRes.headers);\n return send(event, actionRes.body);\n },\n };\n },\n });\n\n return handler.createHandler();\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA,MAAaA,gBAAwC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BrD,MAAa,SACX,YAC6D;AAsC7D,QArCgB,IAAI,mBAAmB;EACrC;EACA,GAAG;EACH,UAAU,UAAwC;AAChD,UAAO;IACL,YAAY,SAAS,MAAM;IAC3B,UAAU,QAAQ,UAAU,OAAO,IAAI;IACvC,cAAc,MAAM;IACpB,WAAW;KACT,IAAI,SAAS;AACb,UAAK,WAAW,WAAW,IAAI,OAAO,WAAW,MAAM,CACrD,UAAS;AAGX,YAAO,IAAI,IACT,OAAO,MAAM,KAAK,EAClB,GAAG,OAAO,KAAK,OAAO,UAAU,OAAO,OAAO,CAAC,GAChD;;IAEH,cAAc,QAAQ;KACpB,MAAM,QAAQ,SAAS,MAAM,CAAC;AAC9B,SAAI,MACF,QAAO,OAAO,MAAM;;IAKxB,oBAAoB,cAAc;KAChC,MAAM,EAAE,QAAQ,MAAM;AACtB,SAAI,aAAa,UAAU;AAC3B,gBAAW,OAAO,UAAU,QAAQ;AACpC,YAAO,KAAK,OAAO,UAAU,KAAK;;IAErC;;EAEJ,CAAC,CAEa,eAAe"}
1
+ {"version":3,"file":"h3.js","names":["frameworkName: SupportedFrameworkName","h3Handler: typeof inngestWrapper"],"sources":["../src/h3.ts"],"sourcesContent":["/**\n * An adapter for H3 to serve and register any declared functions with Inngest,\n * making them available to be triggered by events.\n *\n * @example\n * ```ts\n * import { createApp, eventHandler, toNodeListener } from \"h3\";\n * import { serve } from \"inngest/h3\";\n * import { createServer } from \"node:http\";\n * import { inngest } from \"./inngest/client\";\n * import fnA from \"./inngest/fnA\";\n *\n * const app = createApp();\n * app.use(\n * \"/api/inngest\",\n * eventHandler(\n * serve({\n * client: inngest,\n * functions: [fnA],\n * })\n * )\n * );\n *\n * createServer(toNodeListener(app)).listen(process.env.PORT || 3000);\n * ```\n *\n * @module\n */\n\nimport {\n defineEventHandler,\n type EventHandlerRequest,\n type EventHandlerResponse,\n getHeader,\n getQuery,\n getResponseHeaders,\n getResponseStatus,\n type H3Event,\n readBody,\n readRawBody,\n send,\n setHeaders,\n} from \"h3\";\nimport type { Inngest } from \"./components/Inngest.ts\";\nimport {\n InngestCommHandler,\n type ServeHandlerOptions,\n type SyncHandlerOptions,\n} from \"./components/InngestCommHandler.ts\";\nimport { processEnv } from \"./helpers/env.ts\";\nimport { stringify } from \"./helpers/strings.ts\";\nimport type { RegisterOptions, SupportedFrameworkName } from \"./types.ts\";\n\n/**\n * The name of the framework, used to identify the framework in Inngest\n * dashboards and during testing.\n */\nexport const frameworkName: SupportedFrameworkName = \"h3\";\n\nconst commHandler = (\n options: RegisterOptions & { client: Inngest.Like },\n syncOptions?: SyncHandlerOptions,\n) => {\n const handler = new InngestCommHandler({\n frameworkName,\n ...options,\n syncOptions,\n handler: (event: H3Event<EventHandlerRequest>) => {\n return {\n body: () => readBody(event),\n textBody: async () => {\n const method = event.method;\n const body =\n method === \"POST\" ||\n method === \"PUT\" ||\n method === \"PATCH\" ||\n method === \"DELETE\"\n ? ((await readRawBody(event, \"utf-8\")) ?? \"\")\n : \"\";\n\n return body;\n },\n headers: (key) => getHeader(event, key),\n method: () => event.method,\n url: () => {\n let scheme = \"https\";\n if ((processEnv(\"NODE_ENV\") ?? \"dev\").startsWith(\"dev\")) {\n scheme = \"http\";\n }\n\n return new URL(\n String(event.path),\n `${scheme}://${String(getHeader(event, \"host\"))}`,\n );\n },\n queryString: (key) => {\n const param = getQuery(event)[key];\n if (param) {\n return String(param);\n }\n\n return;\n },\n transformResponse: (actionRes): EventHandlerResponse => {\n const { res } = event.node;\n res.statusCode = actionRes.status;\n setHeaders(event, actionRes.headers);\n return send(event, actionRes.body);\n },\n experimentalTransformSyncResponse: async (data) => {\n const headers = Object.entries(\n getResponseHeaders(event) ?? {},\n ).reduce(\n (acc, [key, value]) => {\n acc[key] = Array.isArray(value) ? value.join(\",\") : `${value}`;\n\n return acc;\n },\n {} as Record<string, string>,\n );\n\n return {\n body: typeof data === \"string\" ? data : stringify(data),\n headers,\n status: getResponseStatus(event) ?? 200,\n };\n },\n };\n },\n });\n\n return handler;\n};\n\n/**\n * In h3, serve and register any declared functions with Inngest, making\n * them available to be triggered by events.\n *\n * @example\n * ```ts\n * import { createApp, eventHandler, toNodeListener } from \"h3\";\n * import { serve } from \"inngest/h3\";\n * import { createServer } from \"node:http\";\n * import { inngest } from \"./inngest/client\";\n * import fnA from \"./inngest/fnA\";\n *\n * const app = createApp();\n * app.use(\n * \"/api/inngest\",\n * eventHandler(\n * serve({\n * client: inngest,\n * functions: [fnA],\n * })\n * )\n * );\n *\n * createServer(toNodeListener(app)).listen(process.env.PORT || 3000);\n * ```\n *\n * @public\n */\n// Has explicit return type to avoid JSR-defined \"slow types\"\nexport const serve = (\n options: ServeHandlerOptions,\n): ((event: H3Event<EventHandlerRequest>) => Promise<void>) => {\n return commHandler(options).createHandler();\n};\n\n/**\n * In h3, create a function that can define an event handler with Inngest steps\n * enabled, allowing you to use steps seamlessly within that API.\n *\n * @example\n * ```ts\n * import { Inngest, step } from \"inngest\";\n * import { createExperimentalEndpointWrapper } from \"inngest/h3\";\n *\n * const inngestEventHandler = createExperimentalEndpointWrapper({\n * client: new Inngest({ id: \"h3-sync-example\" }),\n * });\n *\n *\n * export default inngestEventHandler(async (event) => {\n * const foo = await step.run(\"example/step\", async () => {\n * return \"Hello from step!\";\n * });\n *\n * return `\n * <meta charset=\"utf-8\">\n * <h1>This endpoint worked!</h1>\n * <p>The step's result was: ${foo}</p>\n * `;\n * });\n * ```\n */\nexport const createExperimentalEndpointWrapper = (\n options: SyncHandlerOptions,\n) => {\n const inngestWrapper = commHandler(options, options).createSyncHandler();\n\n const h3Handler: typeof inngestWrapper = (userlandHandler) => {\n return defineEventHandler(inngestWrapper(userlandHandler));\n };\n\n return h3Handler;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,MAAaA,gBAAwC;AAErD,MAAM,eACJ,SACA,gBACG;AAqEH,QApEgB,IAAI,mBAAmB;EACrC;EACA,GAAG;EACH;EACA,UAAU,UAAwC;AAChD,UAAO;IACL,YAAY,SAAS,MAAM;IAC3B,UAAU,YAAY;KACpB,MAAM,SAAS,MAAM;AASrB,YAPE,WAAW,UACX,WAAW,SACX,WAAW,WACX,WAAW,WACL,MAAM,YAAY,OAAO,QAAQ,IAAK,KACxC;;IAIR,UAAU,QAAQ,UAAU,OAAO,IAAI;IACvC,cAAc,MAAM;IACpB,WAAW;KACT,IAAI,SAAS;AACb,UAAK,WAAW,WAAW,IAAI,OAAO,WAAW,MAAM,CACrD,UAAS;AAGX,YAAO,IAAI,IACT,OAAO,MAAM,KAAK,EAClB,GAAG,OAAO,KAAK,OAAO,UAAU,OAAO,OAAO,CAAC,GAChD;;IAEH,cAAc,QAAQ;KACpB,MAAM,QAAQ,SAAS,MAAM,CAAC;AAC9B,SAAI,MACF,QAAO,OAAO,MAAM;;IAKxB,oBAAoB,cAAoC;KACtD,MAAM,EAAE,QAAQ,MAAM;AACtB,SAAI,aAAa,UAAU;AAC3B,gBAAW,OAAO,UAAU,QAAQ;AACpC,YAAO,KAAK,OAAO,UAAU,KAAK;;IAEpC,mCAAmC,OAAO,SAAS;KACjD,MAAM,UAAU,OAAO,QACrB,mBAAmB,MAAM,IAAI,EAAE,CAChC,CAAC,QACC,KAAK,CAAC,KAAK,WAAW;AACrB,UAAI,OAAO,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,IAAI,GAAG,GAAG;AAEvD,aAAO;QAET,EAAE,CACH;AAED,YAAO;MACL,MAAM,OAAO,SAAS,WAAW,OAAO,UAAU,KAAK;MACvD;MACA,QAAQ,kBAAkB,MAAM,IAAI;MACrC;;IAEJ;;EAEJ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCJ,MAAa,SACX,YAC6D;AAC7D,QAAO,YAAY,QAAQ,CAAC,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8B7C,MAAa,qCACX,YACG;CACH,MAAM,iBAAiB,YAAY,SAAS,QAAQ,CAAC,mBAAmB;CAExE,MAAMC,aAAoC,oBAAoB;AAC5D,SAAO,mBAAmB,eAAe,gBAAgB,CAAC;;AAG5D,QAAO"}
package/nitro.cjs CHANGED
@@ -18,8 +18,42 @@ const serve = (options) => {
18
18
  frameworkName
19
19
  });
20
20
  };
21
+ /**
22
+ * In Nitro, create a function that can define an event handler with Inngest
23
+ * steps enabled, allowing you to use steps seamlessly within that API.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { Inngest, step } from "inngest";
28
+ * import { createExperimentalEndpointWrapper } from "inngest/nitro";
29
+ *
30
+ * const inngestEventHandler = createExperimentalEndpointWrapper({
31
+ * client: new Inngest({ id: "nitro-sync-example" }),
32
+ * });
33
+ *
34
+ *
35
+ * export default inngestEventHandler(async (event) => {
36
+ * const foo = await step.run("example/step", async () => {
37
+ * return "Hello from step!";
38
+ * });
39
+ *
40
+ * return `
41
+ * <meta charset="utf-8">
42
+ * <h1>This endpoint worked!</h1>
43
+ * <p>The step's result was: ${foo}</p>
44
+ * `;
45
+ * });
46
+ * ```
47
+ */
48
+ const createExperimentalEndpointWrapper = (options) => {
49
+ return require_h3.createExperimentalEndpointWrapper({
50
+ ...options,
51
+ frameworkName
52
+ });
53
+ };
21
54
 
22
55
  //#endregion
56
+ exports.createExperimentalEndpointWrapper = createExperimentalEndpointWrapper;
23
57
  exports.frameworkName = frameworkName;
24
58
  exports.serve = serve;
25
59
  //# sourceMappingURL=nitro.cjs.map
package/nitro.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"nitro.cjs","names":["frameworkName: SupportedFrameworkName","serveH3"],"sources":["../src/nitro.ts"],"sourcesContent":["/**\n * An adapter for Nitro to serve and register any declared functions with\n * Inngest, making them available to be triggered by events.\n *\n * @module\n */\n\nimport type {\n InternalServeHandlerOptions,\n ServeHandlerOptions,\n} from \"./components/InngestCommHandler.ts\";\nimport { serve as serveH3 } from \"./h3.ts\";\nimport type { SupportedFrameworkName } from \"./types.ts\";\n\n/**\n * The name of the framework, used to identify the framework in Inngest\n * dashboards and during testing.\n */\nexport const frameworkName: SupportedFrameworkName = \"nitro\";\n\n/**\n * In Nitro, serve and register any declared functions with Inngest, making them\n * available to be triggered by events.\n *\n * @public\n */\n// Has explicit return type to avoid JSR-defined \"slow types\"\nexport const serve = (\n options: ServeHandlerOptions,\n): ReturnType<typeof serveH3> => {\n const optsOverrides: InternalServeHandlerOptions = {\n ...options,\n frameworkName,\n };\n\n return serveH3(optsOverrides);\n};\n"],"mappings":";;;;;;;AAkBA,MAAaA,gBAAwC;;;;;;;AASrD,MAAa,SACX,YAC+B;AAM/B,QAAOC,iBAL4C;EACjD,GAAG;EACH;EACD,CAE4B"}
1
+ {"version":3,"file":"nitro.cjs","names":["frameworkName: SupportedFrameworkName","serveH3","createExperimentalEndpointWrapperH3"],"sources":["../src/nitro.ts"],"sourcesContent":["/**\n * An adapter for Nitro to serve and register any declared functions with\n * Inngest, making them available to be triggered by events.\n *\n * @module\n */\n\nimport type {\n InternalServeHandlerOptions,\n ServeHandlerOptions,\n SyncHandlerOptions,\n} from \"./components/InngestCommHandler.ts\";\nimport {\n createExperimentalEndpointWrapper as createExperimentalEndpointWrapperH3,\n serve as serveH3,\n} from \"./h3.ts\";\nimport type { SupportedFrameworkName } from \"./types.ts\";\n\n/**\n * The name of the framework, used to identify the framework in Inngest\n * dashboards and during testing.\n */\nexport const frameworkName: SupportedFrameworkName = \"nitro\";\n\n/**\n * In Nitro, serve and register any declared functions with Inngest, making them\n * available to be triggered by events.\n *\n * @public\n */\n// Has explicit return type to avoid JSR-defined \"slow types\"\nexport const serve = (\n options: ServeHandlerOptions,\n): ReturnType<typeof serveH3> => {\n const optsOverrides: InternalServeHandlerOptions = {\n ...options,\n frameworkName,\n };\n\n return serveH3(optsOverrides);\n};\n\n/**\n * In Nitro, create a function that can define an event handler with Inngest\n * steps enabled, allowing you to use steps seamlessly within that API.\n *\n * @example\n * ```ts\n * import { Inngest, step } from \"inngest\";\n * import { createExperimentalEndpointWrapper } from \"inngest/nitro\";\n *\n * const inngestEventHandler = createExperimentalEndpointWrapper({\n * client: new Inngest({ id: \"nitro-sync-example\" }),\n * });\n *\n *\n * export default inngestEventHandler(async (event) => {\n * const foo = await step.run(\"example/step\", async () => {\n * return \"Hello from step!\";\n * });\n *\n * return `\n * <meta charset=\"utf-8\">\n * <h1>This endpoint worked!</h1>\n * <p>The step's result was: ${foo}</p>\n * `;\n * });\n * ```\n */\nexport const createExperimentalEndpointWrapper = (\n options: SyncHandlerOptions,\n) => {\n const optsOverrides = {\n ...options,\n frameworkName,\n };\n\n return createExperimentalEndpointWrapperH3(optsOverrides);\n};\n"],"mappings":";;;;;;;AAsBA,MAAaA,gBAAwC;;;;;;;AASrD,MAAa,SACX,YAC+B;AAM/B,QAAOC,iBAL4C;EACjD,GAAG;EACH;EACD,CAE4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8B/B,MAAa,qCACX,YACG;AAMH,QAAOC,6CALe;EACpB,GAAG;EACH;EACD,CAEwD"}
package/nitro.d.cts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { SupportedFrameworkName } from "./types.cjs";
2
- import { ServeHandlerOptions } from "./components/InngestCommHandler.cjs";
2
+ import { ServeHandlerOptions, SyncHandlerOptions } from "./components/InngestCommHandler.cjs";
3
3
  import { serve as serve$1 } from "./h3.cjs";
4
+ import * as h30 from "h3";
4
5
 
5
6
  //#region src/nitro.d.ts
6
7
 
@@ -16,6 +17,34 @@ declare const frameworkName: SupportedFrameworkName;
16
17
  * @public
17
18
  */
18
19
  declare const serve: (options: ServeHandlerOptions) => ReturnType<typeof serve$1>;
20
+ /**
21
+ * In Nitro, create a function that can define an event handler with Inngest
22
+ * steps enabled, allowing you to use steps seamlessly within that API.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import { Inngest, step } from "inngest";
27
+ * import { createExperimentalEndpointWrapper } from "inngest/nitro";
28
+ *
29
+ * const inngestEventHandler = createExperimentalEndpointWrapper({
30
+ * client: new Inngest({ id: "nitro-sync-example" }),
31
+ * });
32
+ *
33
+ *
34
+ * export default inngestEventHandler(async (event) => {
35
+ * const foo = await step.run("example/step", async () => {
36
+ * return "Hello from step!";
37
+ * });
38
+ *
39
+ * return `
40
+ * <meta charset="utf-8">
41
+ * <h1>This endpoint worked!</h1>
42
+ * <p>The step's result was: ${foo}</p>
43
+ * `;
44
+ * });
45
+ * ```
46
+ */
47
+ declare const createExperimentalEndpointWrapper: (options: SyncHandlerOptions) => (handler: (event: h30.H3Event<h30.EventHandlerRequest>) => Promise<any>) => (event: h30.H3Event<h30.EventHandlerRequest>) => Promise<any>;
19
48
  //#endregion
20
- export { frameworkName, serve };
49
+ export { createExperimentalEndpointWrapper, frameworkName, serve };
21
50
  //# sourceMappingURL=nitro.d.cts.map
package/nitro.d.cts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"nitro.d.cts","names":[],"sources":["../src/nitro.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAkBa,eAAe;;;;;;;cASf,iBACF,wBACR,kBAAkB"}
1
+ {"version":3,"file":"nitro.d.cts","names":[],"sources":["../src/nitro.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AAqEa,cA/CA,aA+CA,EA/Ce,sBAwD3B;;;;;;;AAR4B,cAvChB,KAuCgB,EAAA,CAAA,OAAA,EAtClB,mBAsCkB,EAAA,GArC1B,UAqC0B,CAAA,OArCR,OAqCQ,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;cADhB,6CACF,yCAAkB,GAAA,CAAA,QAAA,GAAA,CAAA,mBAAA,MAAA,yBAAA,GAAA,CAAA,QAAA,GAAA,CAAA,mBAAA,MAAA"}
package/nitro.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { SupportedFrameworkName } from "./types.js";
2
- import { ServeHandlerOptions } from "./components/InngestCommHandler.js";
2
+ import { ServeHandlerOptions, SyncHandlerOptions } from "./components/InngestCommHandler.js";
3
3
  import { serve as serve$1 } from "./h3.js";
4
+ import * as h30 from "h3";
4
5
 
5
6
  //#region src/nitro.d.ts
6
7
 
@@ -16,6 +17,34 @@ declare const frameworkName: SupportedFrameworkName;
16
17
  * @public
17
18
  */
18
19
  declare const serve: (options: ServeHandlerOptions) => ReturnType<typeof serve$1>;
20
+ /**
21
+ * In Nitro, create a function that can define an event handler with Inngest
22
+ * steps enabled, allowing you to use steps seamlessly within that API.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import { Inngest, step } from "inngest";
27
+ * import { createExperimentalEndpointWrapper } from "inngest/nitro";
28
+ *
29
+ * const inngestEventHandler = createExperimentalEndpointWrapper({
30
+ * client: new Inngest({ id: "nitro-sync-example" }),
31
+ * });
32
+ *
33
+ *
34
+ * export default inngestEventHandler(async (event) => {
35
+ * const foo = await step.run("example/step", async () => {
36
+ * return "Hello from step!";
37
+ * });
38
+ *
39
+ * return `
40
+ * <meta charset="utf-8">
41
+ * <h1>This endpoint worked!</h1>
42
+ * <p>The step's result was: ${foo}</p>
43
+ * `;
44
+ * });
45
+ * ```
46
+ */
47
+ declare const createExperimentalEndpointWrapper: (options: SyncHandlerOptions) => (handler: (event: h30.H3Event<h30.EventHandlerRequest>) => Promise<any>) => (event: h30.H3Event<h30.EventHandlerRequest>) => Promise<any>;
19
48
  //#endregion
20
- export { frameworkName, serve };
49
+ export { createExperimentalEndpointWrapper, frameworkName, serve };
21
50
  //# sourceMappingURL=nitro.d.ts.map
package/nitro.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"nitro.d.ts","names":[],"sources":["../src/nitro.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAkBa,eAAe;;;;;;;cASf,iBACF,wBACR,kBAAkB"}
1
+ {"version":3,"file":"nitro.d.ts","names":[],"sources":["../src/nitro.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AAqEa,cA/CA,aA+CA,EA/Ce,sBAwD3B;;;;;;;AAR4B,cAvChB,KAuCgB,EAAA,CAAA,OAAA,EAtClB,mBAsCkB,EAAA,GArC1B,UAqC0B,CAAA,OArCR,OAqCQ,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;cADhB,6CACF,yCAAkB,GAAA,CAAA,QAAA,GAAA,CAAA,mBAAA,MAAA,yBAAA,GAAA,CAAA,QAAA,GAAA,CAAA,mBAAA,MAAA"}
package/nitro.js CHANGED
@@ -1,4 +1,4 @@
1
- import { serve as serve$1 } from "./h3.js";
1
+ import { createExperimentalEndpointWrapper as createExperimentalEndpointWrapper$1, serve as serve$1 } from "./h3.js";
2
2
 
3
3
  //#region src/nitro.ts
4
4
  /**
@@ -18,7 +18,40 @@ const serve = (options) => {
18
18
  frameworkName
19
19
  });
20
20
  };
21
+ /**
22
+ * In Nitro, create a function that can define an event handler with Inngest
23
+ * steps enabled, allowing you to use steps seamlessly within that API.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { Inngest, step } from "inngest";
28
+ * import { createExperimentalEndpointWrapper } from "inngest/nitro";
29
+ *
30
+ * const inngestEventHandler = createExperimentalEndpointWrapper({
31
+ * client: new Inngest({ id: "nitro-sync-example" }),
32
+ * });
33
+ *
34
+ *
35
+ * export default inngestEventHandler(async (event) => {
36
+ * const foo = await step.run("example/step", async () => {
37
+ * return "Hello from step!";
38
+ * });
39
+ *
40
+ * return `
41
+ * <meta charset="utf-8">
42
+ * <h1>This endpoint worked!</h1>
43
+ * <p>The step's result was: ${foo}</p>
44
+ * `;
45
+ * });
46
+ * ```
47
+ */
48
+ const createExperimentalEndpointWrapper = (options) => {
49
+ return createExperimentalEndpointWrapper$1({
50
+ ...options,
51
+ frameworkName
52
+ });
53
+ };
21
54
 
22
55
  //#endregion
23
- export { frameworkName, serve };
56
+ export { createExperimentalEndpointWrapper, frameworkName, serve };
24
57
  //# sourceMappingURL=nitro.js.map
package/nitro.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"nitro.js","names":["frameworkName: SupportedFrameworkName","serveH3"],"sources":["../src/nitro.ts"],"sourcesContent":["/**\n * An adapter for Nitro to serve and register any declared functions with\n * Inngest, making them available to be triggered by events.\n *\n * @module\n */\n\nimport type {\n InternalServeHandlerOptions,\n ServeHandlerOptions,\n} from \"./components/InngestCommHandler.ts\";\nimport { serve as serveH3 } from \"./h3.ts\";\nimport type { SupportedFrameworkName } from \"./types.ts\";\n\n/**\n * The name of the framework, used to identify the framework in Inngest\n * dashboards and during testing.\n */\nexport const frameworkName: SupportedFrameworkName = \"nitro\";\n\n/**\n * In Nitro, serve and register any declared functions with Inngest, making them\n * available to be triggered by events.\n *\n * @public\n */\n// Has explicit return type to avoid JSR-defined \"slow types\"\nexport const serve = (\n options: ServeHandlerOptions,\n): ReturnType<typeof serveH3> => {\n const optsOverrides: InternalServeHandlerOptions = {\n ...options,\n frameworkName,\n };\n\n return serveH3(optsOverrides);\n};\n"],"mappings":";;;;;;;AAkBA,MAAaA,gBAAwC;;;;;;;AASrD,MAAa,SACX,YAC+B;AAM/B,QAAOC,QAL4C;EACjD,GAAG;EACH;EACD,CAE4B"}
1
+ {"version":3,"file":"nitro.js","names":["frameworkName: SupportedFrameworkName","serveH3","createExperimentalEndpointWrapperH3"],"sources":["../src/nitro.ts"],"sourcesContent":["/**\n * An adapter for Nitro to serve and register any declared functions with\n * Inngest, making them available to be triggered by events.\n *\n * @module\n */\n\nimport type {\n InternalServeHandlerOptions,\n ServeHandlerOptions,\n SyncHandlerOptions,\n} from \"./components/InngestCommHandler.ts\";\nimport {\n createExperimentalEndpointWrapper as createExperimentalEndpointWrapperH3,\n serve as serveH3,\n} from \"./h3.ts\";\nimport type { SupportedFrameworkName } from \"./types.ts\";\n\n/**\n * The name of the framework, used to identify the framework in Inngest\n * dashboards and during testing.\n */\nexport const frameworkName: SupportedFrameworkName = \"nitro\";\n\n/**\n * In Nitro, serve and register any declared functions with Inngest, making them\n * available to be triggered by events.\n *\n * @public\n */\n// Has explicit return type to avoid JSR-defined \"slow types\"\nexport const serve = (\n options: ServeHandlerOptions,\n): ReturnType<typeof serveH3> => {\n const optsOverrides: InternalServeHandlerOptions = {\n ...options,\n frameworkName,\n };\n\n return serveH3(optsOverrides);\n};\n\n/**\n * In Nitro, create a function that can define an event handler with Inngest\n * steps enabled, allowing you to use steps seamlessly within that API.\n *\n * @example\n * ```ts\n * import { Inngest, step } from \"inngest\";\n * import { createExperimentalEndpointWrapper } from \"inngest/nitro\";\n *\n * const inngestEventHandler = createExperimentalEndpointWrapper({\n * client: new Inngest({ id: \"nitro-sync-example\" }),\n * });\n *\n *\n * export default inngestEventHandler(async (event) => {\n * const foo = await step.run(\"example/step\", async () => {\n * return \"Hello from step!\";\n * });\n *\n * return `\n * <meta charset=\"utf-8\">\n * <h1>This endpoint worked!</h1>\n * <p>The step's result was: ${foo}</p>\n * `;\n * });\n * ```\n */\nexport const createExperimentalEndpointWrapper = (\n options: SyncHandlerOptions,\n) => {\n const optsOverrides = {\n ...options,\n frameworkName,\n };\n\n return createExperimentalEndpointWrapperH3(optsOverrides);\n};\n"],"mappings":";;;;;;;AAsBA,MAAaA,gBAAwC;;;;;;;AASrD,MAAa,SACX,YAC+B;AAM/B,QAAOC,QAL4C;EACjD,GAAG;EACH;EACD,CAE4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8B/B,MAAa,qCACX,YACG;AAMH,QAAOC,oCALe;EACpB,GAAG;EACH;EACD,CAEwD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inngest",
3
- "version": "3.48.0",
3
+ "version": "3.48.2-pr-1209.0",
4
4
  "description": "Official SDK for Inngest.com. Inngest is the reliability layer for modern applications. Inngest combines durable execution, events, and queues into a zero-infra platform with built-in observability.",
5
5
  "main": "./index.cjs",
6
6
  "module": "./index.js",
@@ -24,8 +24,7 @@
24
24
  "lint": "biome check",
25
25
  "lint:fix": "biome check --fix",
26
26
  "postversion": "pnpm run build",
27
- "release": "pnpm run test && pnpm run build && cross-env DIST_DIR=dist node ../../scripts/release/publish.js && pnpm dlx jsr publish --allow-slow-types --allow-dirty",
28
- "release:version": "node ../../scripts/release/jsrVersion.js",
27
+ "release": "pnpm run test && pnpm run build && cross-env DIST_DIR=dist node ../../scripts/release/publish.js",
29
28
  "dev": "pnpm install && concurrently --names Build,Lint --prefix-colors \"green.inverse,magenta.inverse\" --handle-input \"pnpm run dev:build\" \"pnpm run dev:lint\"",
30
29
  "dev:build": "nodemon -w src -e ts -i version.ts --delay 300ms -x 'pnpm run build'",
31
30
  "dev:lint": "nodemon -w src -e ts -i version.ts --delay 300ms -x 'pnpm run lint'",
package/types.d.cts CHANGED
@@ -1235,12 +1235,12 @@ declare const functionConfigSchema: z.ZodObject<{
1235
1235
  timeout: z.ZodOptional<z.ZodEffects<z.ZodString, "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`, string>>;
1236
1236
  }, "strict", z.ZodTypeAny, {
1237
1237
  period: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`;
1238
- timeout?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
1239
1238
  key?: string | undefined;
1239
+ timeout?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
1240
1240
  }, {
1241
1241
  period: string;
1242
- timeout?: string | undefined;
1243
1242
  key?: string | undefined;
1243
+ timeout?: string | undefined;
1244
1244
  }>>;
1245
1245
  timeouts: z.ZodOptional<z.ZodObject<{
1246
1246
  start: z.ZodOptional<z.ZodEffects<z.ZodString, "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`, string>>;
@@ -1341,8 +1341,8 @@ declare const functionConfigSchema: z.ZodObject<{
1341
1341
  } | undefined;
1342
1342
  debounce?: {
1343
1343
  period: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`;
1344
- timeout?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
1345
1344
  key?: string | undefined;
1345
+ timeout?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
1346
1346
  } | undefined;
1347
1347
  timeouts?: {
1348
1348
  finish?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
@@ -1401,8 +1401,8 @@ declare const functionConfigSchema: z.ZodObject<{
1401
1401
  } | undefined;
1402
1402
  debounce?: {
1403
1403
  period: string;
1404
- timeout?: string | undefined;
1405
1404
  key?: string | undefined;
1405
+ timeout?: string | undefined;
1406
1406
  } | undefined;
1407
1407
  timeouts?: {
1408
1408
  finish?: string | undefined;
package/types.d.ts CHANGED
@@ -1235,12 +1235,12 @@ declare const functionConfigSchema: z.ZodObject<{
1235
1235
  timeout: z.ZodOptional<z.ZodEffects<z.ZodString, "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`, string>>;
1236
1236
  }, "strict", z.ZodTypeAny, {
1237
1237
  period: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`;
1238
- timeout?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
1239
1238
  key?: string | undefined;
1239
+ timeout?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
1240
1240
  }, {
1241
1241
  period: string;
1242
- timeout?: string | undefined;
1243
1242
  key?: string | undefined;
1243
+ timeout?: string | undefined;
1244
1244
  }>>;
1245
1245
  timeouts: z.ZodOptional<z.ZodObject<{
1246
1246
  start: z.ZodOptional<z.ZodEffects<z.ZodString, "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`, string>>;
@@ -1341,8 +1341,8 @@ declare const functionConfigSchema: z.ZodObject<{
1341
1341
  } | undefined;
1342
1342
  debounce?: {
1343
1343
  period: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`;
1344
- timeout?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
1345
1344
  key?: string | undefined;
1345
+ timeout?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
1346
1346
  } | undefined;
1347
1347
  timeouts?: {
1348
1348
  finish?: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s` | undefined;
@@ -1401,8 +1401,8 @@ declare const functionConfigSchema: z.ZodObject<{
1401
1401
  } | undefined;
1402
1402
  debounce?: {
1403
1403
  period: string;
1404
- timeout?: string | undefined;
1405
1404
  key?: string | undefined;
1405
+ timeout?: string | undefined;
1406
1406
  } | undefined;
1407
1407
  timeouts?: {
1408
1408
  finish?: string | undefined;
package/version.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  //#region src/version.ts
3
- const version = "3.48.0";
3
+ const version = "3.48.2-pr-1209.0";
4
4
 
5
5
  //#endregion
6
6
  exports.version = version;
package/version.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"version.cjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Generated by genversion.\nexport const version = \"3.48.0\";\n"],"mappings":";;AACA,MAAa,UAAU"}
1
+ {"version":3,"file":"version.cjs","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Generated by genversion.\nexport const version = \"3.48.2-pr-1209.0\";\n"],"mappings":";;AACA,MAAa,UAAU"}
package/version.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.d.ts
2
- declare const version = "3.48.0";
2
+ declare const version = "3.48.2-pr-1209.0";
3
3
  //#endregion
4
4
  export { version };
5
5
  //# sourceMappingURL=version.d.cts.map
package/version.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.d.ts
2
- declare const version = "3.48.0";
2
+ declare const version = "3.48.2-pr-1209.0";
3
3
  //#endregion
4
4
  export { version };
5
5
  //# sourceMappingURL=version.d.ts.map
package/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region src/version.ts
2
- const version = "3.48.0";
2
+ const version = "3.48.2-pr-1209.0";
3
3
 
4
4
  //#endregion
5
5
  export { version };
package/version.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Generated by genversion.\nexport const version = \"3.48.0\";\n"],"mappings":";AACA,MAAa,UAAU"}
1
+ {"version":3,"file":"version.js","names":[],"sources":["../src/version.ts"],"sourcesContent":["// Generated by genversion.\nexport const version = \"3.48.2-pr-1209.0\";\n"],"mappings":";AACA,MAAa,UAAU"}