@saguiitay/eventhouse-ai-observability 0.1.1 → 0.1.2

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,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2 - 2026-11-14
4
+
5
+ - Publish to npmjs using GitHub Actions OIDC trusted publishing without a stored
6
+ npm token. Provenance requires a public source repository and is not generated
7
+ for this private repository.
8
+ - Preserve the separate GitHub Packages publishing workflow and registry defaults.
9
+ - Verify packed publication settings and the published npmjs version.
10
+ - Update the basic example's dependency pin and instrumentation scope to 0.1.2.
11
+ - No runtime behavior changes beyond the instrumentation scope version.
12
+
3
13
  ## 0.1.1 - 2026-11-12
4
14
 
5
15
  - Fix the reported development-dependency advisories by upgrading AJV to 8.18.0
package/README.md CHANGED
@@ -4,7 +4,7 @@ Instrument an **existing GitHub Copilot SDK session** and send OpenTelemetry spa
4
4
 
5
5
  1. In Fabric, add an Eventstream **Custom endpoint source**, then connect its output to an Eventhouse KQL database. Use the source's **Event Hub** producer credentials, not an outward destination. Apply the [schema and setup](docs/fabric-setup.md).
6
6
  2. Set `FABRIC_EVENTSTREAM_CONNECTION_STRING` to the Fabric-provided connection string. If it omits `EntityPath`, also set `FABRIC_EVENTSTREAM_ENTITY_NAME` to the provided event hub name.
7
- 3. Configure [GitHub Packages authentication](#installation-from-github-packages), then install and instrument:
7
+ 3. Install from npmjs (or your organization's approved npm mirror) and instrument:
8
8
 
9
9
  ```sh
10
10
  npm install @saguiitay/eventhouse-ai-observability
@@ -26,9 +26,9 @@ try {
26
26
  }
27
27
  ```
28
28
 
29
- Version 0.1.1 is published to **GitHub Packages**. A separate npmjs workflow
30
- stages the same version for human approval; it does not publish directly.
31
- Until the first npmjs approval, use the GitHub Packages installation below.
29
+ Version 0.1.1 is published to **GitHub Packages**, and its first npmjs release
30
+ was approved by the maintainer. A separate npmjs workflow publishes future
31
+ versions directly using GitHub Actions OIDC trusted publishing.
32
32
  To test an unpublished release,
33
33
  run `pnpm install` and `pnpm pack`; install the root tarball with npm.
34
34
  Node.js **22.15+** (including Node 24 LTS), ESM, Copilot SDK **1.0.31** / compatible
@@ -129,7 +129,7 @@ This scope mapping does not change the registry for dependencies outside `@sagui
129
129
 
130
130
  Run **Publish to GitHub Packages** from the repository's Actions tab on `main`,
131
131
  or publish a GitHub Release whose tag matches the package version, such as
132
- `v0.1.1`. Update `package.json`, the instrumentation scope version in `src/engine.ts`,
132
+ `v0.1.2`. Update `package.json`, the instrumentation scope version in `src/engine.ts`,
133
133
  and the basic example's dependency pin before releasing another version; published versions
134
134
  cannot be overwritten. Prerelease versions use the `next` dist-tag instead of `latest`.
135
135
 
@@ -148,35 +148,44 @@ the package is private or its visibility cannot be verified. New package names
148
148
  must be bootstrapped and made public before using this workflow.
149
149
  Public visibility still requires consumer authentication. See the [release notes](CHANGELOG.md).
150
150
 
151
- ## Staging on npmjs
151
+ ## Publishing to npmjs
152
152
 
153
- The separate **Stage package on npmjs** workflow runs manually on `main`. It uses
153
+ The separate **Publish to npmjs** workflow runs manually on `main`. It uses
154
154
  Node 24 and npm 12, validates the project, changes the registry only in its runner
155
- checkout, packs, smoke-tests, and stages the exact tested tarball. The committed
155
+ checkout, packs, smoke-tests, and publishes the exact tested tarball.
156
+ It then verifies the published version against the public registry. The committed
156
157
  GitHub Packages registry configuration and its publishing workflow are unchanged.
157
158
  Packed metadata is checked against the selected publication settings.
158
-
159
- For the first npmjs publication:
160
-
161
- 1. Own the `@saguiitay` npm scope and enable npm account 2FA.
162
- 2. Create a short-lived granular token with **Read and write (stage only)**
163
- permission for that scope. Leave **Bypass two-factor authentication** unchecked.
164
- 3. Store the token as the repository Actions secret **`NPM_STAGING_TOKEN`**.
165
- The workflow exposes it only to the staging step, never to dependency installation
166
- or package lifecycle scripts.
167
- 4. Run **Stage package on npmjs** from Actions. On npmjs.com, open **Account >
168
- Staged Packages**, review the package/version, and **Approve** with 2FA.
169
-
170
- For a new package, npm creates a publicly visible `0.0.0-stage` placeholder.
171
- The actual staged version's contents remain unavailable until approval. A staged
172
- version reserves that version number; do not rerun staging for an already staged
173
- or published version. `0.1.1` on GitHub Packages does not reserve `0.1.1` on npmjs.
174
-
175
- After bootstrap, configure npm's GitHub Actions trusted publisher for
176
- `saguiitay/ai-observability` and workflow filename `publish-npmjs.yml`, update the
177
- workflow to use OIDC, and revoke the bootstrap token. Approval still requires
178
- interactive 2FA if using staged publishing. See [npm staged publishing](https://docs.npmjs.com/staged-publishing/)
179
- and [trusted publishing](https://docs.npmjs.com/trusted-publishers/).
159
+ OIDC works with this private source repository, but npm provenance attestations
160
+ require a public source repository and are not generated here.
161
+
162
+ Configure the npm package's **Settings > Trusted publishing** with:
163
+
164
+ | Field | Value |
165
+ | -------------------- | --------------------------- |
166
+ | Provider | GitHub Actions |
167
+ | Organization or user | `saguiitay` |
168
+ | Repository | `ai-observability` |
169
+ | Workflow filename | `publish-npmjs.yml` |
170
+ | Environment | Leave blank |
171
+ | Allowed actions | Enable direct `npm publish` |
172
+
173
+ The workflow grants `id-token: write` to its publishing job and does not use
174
+ `NPM_STAGING_TOKEN` or another stored npm credential. A new trusted publisher
175
+ must complete its first successful publication within two days. After that
176
+ publication succeeds, revoke the bootstrap staging token on npmjs and delete
177
+ the repository's `NPM_STAGING_TOKEN` secret. Enable npm's **Require two-factor
178
+ authentication and disallow tokens** publishing setting.
179
+
180
+ Update the release versions described above before running this workflow;
181
+ published versions cannot be overwritten. Running it publishes immediately,
182
+ without a separate npm approval. The first npmjs release was bootstrapped using
183
+ staged publishing and interactive 2FA approval. See
184
+ [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/).
185
+
186
+ When installing from this source checkout, its `.npmrc` still maps `@saguiitay`
187
+ to GitHub Packages. Override that mapping in a consuming project to use npmjs
188
+ or your approved mirror instead; GitHub authentication is not needed for npmjs.
180
189
 
181
190
  ## Documentation
182
191
 
@@ -480,7 +480,7 @@ function createEngine(options) {
480
480
  });
481
481
  const tracer = provider.getTracer(
482
482
  "@saguiitay/eventhouse-ai-observability",
483
- "0.1.1"
483
+ "0.1.2"
484
484
  );
485
485
  const localContext = new AsyncLocalStorage();
486
486
  const active = /* @__PURE__ */ new Set();
@@ -943,4 +943,4 @@ export {
943
943
  createObservability,
944
944
  OTLPTraceExporter2 as OTLPTraceExporter
945
945
  };
946
- //# sourceMappingURL=chunk-XFSF25OP.js.map
946
+ //# sourceMappingURL=chunk-XQFUPGYU.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/engine.ts","../src/diagnostics.ts","../src/exporters/eventstream.ts","../src/exporters/serialize.ts","../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport {\n context,\n trace,\n ROOT_CONTEXT,\n INVALID_SPAN_CONTEXT,\n type Attributes,\n type AttributeValue,\n type Context,\n type Span,\n type SpanOptions,\n} from \"@opentelemetry/api\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport {\n classifyError,\n diagnosticEvent,\n type DiagnosticCategory,\n type DiagnosticEvent,\n} from \"./diagnostics.js\";\nimport {\n TracerProvider,\n ParentBasedSampler,\n TraceIdRatioBasedSampler,\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanExporter,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace\";\n\nexport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\nexport type { DiagnosticCategory, DiagnosticEvent } from \"./diagnostics.js\";\n\nexport interface Diagnostics {\n eventsGenerated: number;\n eventsExported: number;\n eventsRetried: number;\n eventsDropped: number;\n exportFailures: number;\n /** Admitted spans awaiting export; excludes batches already in flight. */\n queueDepth: number;\n activeSpans: number;\n /** Latest sanitized failure only; never includes the original error or configuration. */\n lastError?: DiagnosticEvent;\n}\n\nexport type Redactor = (\n key: string,\n value: AttributeValue,\n) => AttributeValue | undefined;\n\nexport interface CoreOptions {\n exporter: SpanExporter;\n serviceName?: string;\n serviceVersion?: string;\n environment?: string;\n resourceAttributes?: Attributes;\n captureContent?: boolean;\n redact?: Redactor;\n /** Receives sanitized failure categories. Callback exceptions are contained. */\n onDiagnostic?: (event: DiagnosticEvent) => void;\n /** Prints only sanitized failure categories and fixed troubleshooting hints. */\n debug?: boolean;\n samplingRatio?: number;\n batchSize?: number;\n flushIntervalMs?: number;\n /** Export callback deadline in milliseconds. Defaults to 30000. */\n exportTimeoutMs?: number;\n /** Underlying exports, including timed-out calls still pending. Defaults to 4. */\n maxConcurrentExports?: number;\n /** Overall shutdown deadline in milliseconds, including transport cleanup. Defaults to 30000. */\n shutdownTimeoutMs?: number;\n maxQueueSize?: number;\n maxActiveSpans?: number;\n}\n\nexport interface Observability {\n readonly captureContent: boolean;\n readonly maxActiveSpans: number;\n startSpan(\n name: string,\n options?: SpanOptions & { parent?: Span | Context },\n ): Span;\n withSpan<T>(span: Span, callback: () => T): T;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n getDiagnostics(): Readonly<Diagnostics>;\n}\n\nfunction bounded(\n value: number,\n name: string,\n min: number,\n max: number,\n): number {\n if (!Number.isFinite(value) || value < min || value > max) {\n throw new Error(`${name} must be between ${min} and ${max}`);\n }\n return value;\n}\n\nconst secretKey =\n /(?:password|secret|authorization|connection.?string|api[_.-]?key|sharedaccess|access[_.-]?token)/i;\nconst contentKey =\n /(?:prompt|completion|response\\.content|input\\.messages|output\\.messages|tool\\.(?:arguments|result|output))/i;\n\nexport function redactSecrets(value: string): string {\n return value\n .replace(/(?:Endpoint=sb:\\/\\/)[^\\s\"']+/gi, \"[REDACTED_CONNECTION_STRING]\")\n .replace(/SharedAccess(?:Key|Signature)(?:Name)?=[^;\\s\"']+/gi, \"[REDACTED]\")\n .replace(/\\bBearer\\s+[A-Za-z0-9._~+/-]+=*/gi, \"Bearer [REDACTED]\")\n .replace(/([?&](?:sig|token|key)=)[^&\\s\"']+/gi, \"$1[REDACTED]\");\n}\n\nfunction makeSanitizer(options: CoreOptions) {\n const cleanValue = (\n key: string,\n value: AttributeValue,\n ): AttributeValue | undefined => {\n if (\n secretKey.test(key) ||\n (!options.captureContent && contentKey.test(key))\n )\n return undefined;\n const clean = (item: string | number | boolean | null | undefined) =>\n typeof item === \"string\" ? redactSecrets(item).slice(0, 4096) : item;\n let result: AttributeValue = Array.isArray(value)\n ? (value.slice(0, 64).map(clean) as AttributeValue)\n : (clean(value as string | number | boolean) as AttributeValue);\n if (options.redact) {\n try {\n const redacted = options.redact(key, result);\n if (redacted === undefined) return undefined;\n result = Array.isArray(redacted)\n ? (redacted.slice(0, 64).map(clean) as AttributeValue)\n : (clean(redacted as string | number | boolean) as AttributeValue);\n } catch {\n return undefined;\n }\n }\n return result;\n };\n const cleanAttributes = (attributes: Attributes): Attributes => {\n const result: Attributes = {};\n for (const [key, value] of Object.entries(attributes).slice(0, 64)) {\n if (value !== undefined) {\n const cleaned = cleanValue(key, value);\n if (cleaned !== undefined)\n result[redactSecrets(key).slice(0, 256)] = cleaned;\n }\n }\n return result;\n };\n return (span: ReadableSpan): ReadableSpan => ({\n spanContext: () => span.spanContext(),\n ...(span.parentSpanContext\n ? { parentSpanContext: span.parentSpanContext }\n : {}),\n kind: span.kind,\n startTime: span.startTime,\n endTime: span.endTime,\n duration: span.duration,\n ended: span.ended,\n instrumentationScope: span.instrumentationScope,\n droppedAttributesCount: span.droppedAttributesCount,\n droppedEventsCount: span.droppedEventsCount,\n droppedLinksCount: span.droppedLinksCount,\n name: redactSecrets(span.name).slice(0, 512),\n attributes: cleanAttributes(span.attributes),\n resource: resourceFromAttributes(cleanAttributes(span.resource.attributes)),\n status: {\n code: span.status.code,\n ...(options.captureContent && span.status.message\n ? { message: redactSecrets(span.status.message).slice(0, 4096) }\n : {}),\n },\n events: span.events.map((event) => ({\n ...event,\n name: redactSecrets(event.name).slice(0, 512),\n ...(event.attributes\n ? { attributes: cleanAttributes(event.attributes) }\n : {}),\n })),\n links: span.links.map((link) => ({\n ...link,\n ...(link.attributes\n ? { attributes: cleanAttributes(link.attributes) }\n : {}),\n })),\n });\n}\n\nclass ManagedBatchProcessor implements SpanProcessor {\n private readonly processor: BatchSpanProcessor;\n private readonly inFlight = new Set<Promise<void>>();\n private flushPromise: Promise<void> | undefined;\n private closed = false;\n private shutdownPromise: Promise<void> | undefined;\n private exporterShutdownPromise: Promise<void> | undefined;\n private readonly finishers = new Set<() => void>();\n private readonly waiters = new Set<() => void>();\n private readonly shutdownController = new AbortController();\n private underlyingExports = 0;\n private disposed = false;\n readonly counters: Diagnostics = {\n eventsGenerated: 0,\n eventsExported: 0,\n eventsRetried: 0,\n eventsDropped: 0,\n exportFailures: 0,\n queueDepth: 0,\n activeSpans: 0,\n };\n\n constructor(\n private readonly exporter: SpanExporter,\n private readonly maxQueueSize: number,\n batchSize: number,\n interval: number,\n timeout: number,\n private readonly maxConcurrentExports: number,\n private readonly shutdownTimeout: number,\n private readonly sanitize: (span: ReadableSpan) => ReadableSpan,\n private readonly onDiagnostic: CoreOptions[\"onDiagnostic\"],\n private readonly debug: boolean,\n ) {\n this.processor = new BatchSpanProcessor({\n exporter: {\n export: (spans, callback) => {\n let complete!: () => void;\n const pending = new Promise<void>((resolve) => {\n complete = resolve;\n });\n this.inFlight.add(pending);\n let settled = false;\n let queued = true;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let attempt!: () => void;\n const dequeue = () => {\n if (!queued) return;\n queued = false;\n this.counters.queueDepth -= spans.length;\n };\n const controller = new AbortController();\n const expire = () => {\n controller.abort();\n finish(false, undefined, \"timeout\");\n };\n const finish = (\n success: boolean,\n result?: {\n exportedSpans?: number;\n droppedSpans?: number;\n error?: unknown;\n },\n category?: DiagnosticCategory,\n ) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n this.finishers.delete(expire);\n this.waiters.delete(attempt);\n dequeue();\n const exported = result?.exportedSpans;\n const dropped = result?.droppedSpans;\n const hasCounts =\n Number.isInteger(exported) &&\n Number.isInteger(dropped) &&\n exported! >= 0 &&\n dropped! >= 0 &&\n exported! + dropped! === spans.length;\n this.counters.eventsExported += hasCounts\n ? exported!\n : success\n ? spans.length\n : 0;\n this.counters.eventsDropped += hasCounts\n ? dropped!\n : success\n ? 0\n : spans.length;\n if (!success) {\n this.counters.exportFailures++;\n this.report(\"export\", result?.error, category);\n }\n this.inFlight.delete(pending);\n complete();\n // Failures are accounted for here, never forwarded to OTel's global logger.\n callback({ code: 0 });\n this.wakeWaiter();\n };\n this.finishers.add(expire);\n // BSP can start an export directly in onEnd when the batch fills.\n attempt = () => {\n if (settled) return;\n if (this.disposed) {\n finish(false, undefined, \"shutdown\");\n return;\n }\n if (this.underlyingExports >= this.maxConcurrentExports) {\n this.waiters.add(attempt);\n deadline ??= setTimeout(expire, timeout);\n return;\n }\n this.waiters.delete(attempt);\n dequeue();\n this.underlyingExports++;\n let released = false;\n const release = () => {\n if (released) return;\n released = true;\n this.underlyingExports--;\n this.wakeWaiter();\n };\n try {\n // Standard exporters ignore the optional signal; Eventstream honors it.\n const exporter = this.exporter as SpanExporter & {\n export(\n spans: ReadableSpan[],\n callback: Parameters<SpanExporter[\"export\"]>[1],\n signal?: AbortSignal,\n ): void;\n };\n const result = exporter.export(\n spans,\n (result) => {\n release();\n finish(\n result.code === 0,\n result as typeof result & {\n exportedSpans?: number;\n droppedSpans?: number;\n },\n );\n },\n controller.signal,\n );\n // Also contain exporters incorrectly returning a rejected promise.\n void Promise.resolve(result).catch((error: unknown) => {\n release();\n finish(false, { error });\n });\n } catch (error) {\n release();\n finish(false, { error });\n }\n if (!settled) deadline ??= setTimeout(expire, timeout);\n };\n queueMicrotask(attempt);\n },\n shutdown: async () => {\n await this.waitForExports();\n await this.shutdownExporter();\n },\n },\n maxExportBatchSize: batchSize,\n maxQueueSize,\n scheduledDelayMillis: interval,\n // The callback deadline settles batches before BSP's fallback timeout.\n exportTimeoutMillis: timeout + 1000,\n });\n }\n\n onStart(): void {}\n\n onEnd(span: ReadableSpan): void {\n this.counters.eventsGenerated++;\n if (this.closed || this.counters.queueDepth >= this.maxQueueSize) {\n this.counters.eventsDropped++;\n return;\n }\n try {\n const sanitized = this.sanitize(span);\n this.counters.queueDepth++;\n this.processor.onEnd(sanitized);\n } catch {\n this.counters.eventsDropped++;\n }\n }\n\n forceFlush(): Promise<void> {\n if (this.shutdownPromise) return this.shutdownPromise;\n this.flushPromise ??= Promise.resolve().then(async () => {\n try {\n do {\n await this.processor.forceFlush();\n await this.waitForExports();\n } while (this.counters.queueDepth > 0);\n } catch (error) {\n this.counters.exportFailures++;\n this.report(\"flush\", error);\n } finally {\n this.flushPromise = undefined;\n }\n });\n return this.flushPromise;\n }\n\n private async waitForExports(): Promise<void> {\n while (this.inFlight.size > 0) await Promise.all(this.inFlight);\n }\n\n private wakeWaiter(): void {\n if (this.underlyingExports >= this.maxConcurrentExports) return;\n const waiter = this.waiters.values().next().value;\n if (!waiter) return;\n this.waiters.delete(waiter);\n queueMicrotask(() => {\n waiter();\n this.wakeWaiter();\n });\n }\n\n shutdown(): Promise<void> {\n this.shutdownPromise ??= (async () => {\n this.closed = true;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n this.processor.shutdown(),\n new Promise<void>((resolve) => {\n deadline = setTimeout(() => {\n this.counters.exportFailures++;\n this.report(\"shutdown\", undefined, \"timeout\");\n this.shutdownController.abort();\n resolve();\n }, this.shutdownTimeout);\n }),\n ]);\n } catch (error) {\n this.counters.exportFailures++;\n this.report(\"shutdown\", error, \"shutdown\");\n } finally {\n clearTimeout(deadline);\n this.disposed = true;\n for (const finish of this.finishers) finish();\n this.counters.eventsDropped += this.counters.queueDepth;\n this.counters.queueDepth = 0;\n // Even when draining times out, initiate cleanup exactly once.\n void this.shutdownExporter();\n }\n })();\n return this.shutdownPromise;\n }\n\n private shutdownExporter(): Promise<void> {\n this.exporterShutdownPromise ??= Promise.resolve()\n .then(() => {\n const exporter = this.exporter as SpanExporter & {\n shutdown(signal?: AbortSignal): Promise<void>;\n };\n return exporter.shutdown(this.shutdownController.signal);\n })\n .catch((error: unknown) => {\n if (!this.disposed && !this.shutdownController.signal.aborted) {\n this.counters.exportFailures++;\n this.report(\"shutdown\", error, \"shutdown\");\n }\n });\n return this.exporterShutdownPromise;\n }\n\n getRetries(): number {\n try {\n const exporter = this.exporter as SpanExporter & {\n getDiagnostics?(): { eventsRetried: number };\n };\n return exporter.getDiagnostics?.().eventsRetried ?? 0;\n } catch {\n return 0;\n }\n }\n\n private report(\n operation: DiagnosticEvent[\"operation\"],\n error: unknown,\n fallback?: DiagnosticCategory,\n ): void {\n const event = diagnosticEvent(operation, classifyError(error, fallback));\n this.counters.lastError = event;\n try {\n void Promise.resolve(this.onDiagnostic?.(event)).catch(() => {});\n } catch {}\n if (this.debug) {\n try {\n console.warn(\n `[ai-observability] ${event.operation}: ${event.category}. ${event.message}`,\n );\n } catch {}\n }\n }\n}\n\nexport function createEngine(options: CoreOptions): Observability {\n const ratio = bounded(options.samplingRatio ?? 1, \"samplingRatio\", 0, 1);\n const maxQueue = bounded(\n options.maxQueueSize ?? 2048,\n \"maxQueueSize\",\n 1,\n 100000,\n );\n const batchSize = bounded(options.batchSize ?? 256, \"batchSize\", 1, maxQueue);\n const interval = bounded(\n options.flushIntervalMs ?? 5000,\n \"flushIntervalMs\",\n 1,\n 3600000,\n );\n const timeout = bounded(\n options.exportTimeoutMs ?? 30000,\n \"exportTimeoutMs\",\n 1,\n 3600000,\n );\n const maxConcurrentExports = bounded(\n options.maxConcurrentExports ?? 4,\n \"maxConcurrentExports\",\n 1,\n 1024,\n );\n const shutdownTimeout = bounded(\n options.shutdownTimeoutMs ?? 30000,\n \"shutdownTimeoutMs\",\n 1,\n 3600000,\n );\n const maxActiveSpans = bounded(\n options.maxActiveSpans ?? 4096,\n \"maxActiveSpans\",\n 1,\n 100000,\n );\n for (const [name, value] of Object.entries({\n maxQueue,\n batchSize,\n interval,\n timeout,\n maxConcurrentExports,\n shutdownTimeout,\n maxActiveSpans,\n })) {\n if (!Number.isInteger(value)) throw new Error(`${name} must be an integer`);\n }\n const processor = new ManagedBatchProcessor(\n options.exporter,\n maxQueue,\n batchSize,\n interval,\n timeout,\n maxConcurrentExports,\n shutdownTimeout,\n makeSanitizer(options),\n options.onDiagnostic,\n options.debug ?? false,\n );\n const provider = new TracerProvider({\n resource: resourceFromAttributes({\n ...options.resourceAttributes,\n \"service.name\": options.serviceName ?? \"ai-application\",\n ...(options.serviceVersion\n ? { \"service.version\": options.serviceVersion }\n : {}),\n ...(options.environment\n ? { \"deployment.environment.name\": options.environment }\n : {}),\n }),\n sampler: new ParentBasedSampler({\n root: new TraceIdRatioBasedSampler(ratio),\n }),\n spanProcessors: [processor],\n spanLimits: {\n attributeCountLimit: 64,\n attributeValueLengthLimit: 4096,\n eventCountLimit: 64,\n linkCountLimit: 32,\n attributePerEventCountLimit: 32,\n attributePerLinkCountLimit: 32,\n },\n });\n const tracer = provider.getTracer(\n \"@saguiitay/eventhouse-ai-observability\",\n \"0.1.1\",\n );\n const localContext = new AsyncLocalStorage<Context>();\n const active = new Set<Span>();\n let closed = false;\n let shutdownPromise: Promise<void> | undefined;\n const engine: Observability = {\n captureContent: options.captureContent ?? false,\n maxActiveSpans,\n startSpan(name, spanOptions = {}) {\n if (closed || active.size >= maxActiveSpans) {\n processor.counters.eventsDropped++;\n return trace.wrapSpanContext(INVALID_SPAN_CONTEXT);\n }\n const { parent, ...otelOptions } = spanOptions;\n const ambient = localContext.getStore() ?? context.active();\n const parentContext = parent\n ? \"spanContext\" in parent\n ? trace.setSpan(ambient, parent)\n : parent\n : ambient;\n const span = tracer.startSpan(name, otelOptions, parentContext);\n if (span.isRecording()) {\n active.add(span);\n const end = span.end.bind(span);\n span.end = (time) => {\n active.delete(span);\n end(time);\n };\n }\n return span;\n },\n withSpan(span, callback) {\n if (closed) return callback();\n const parent =\n localContext.getStore() ?? context.active() ?? ROOT_CONTEXT;\n const current = trace.setSpan(parent, span);\n return localContext.run(current, () => context.with(current, callback));\n },\n flush: () => processor.forceFlush(),\n shutdown() {\n shutdownPromise ??= (async () => {\n closed = true;\n for (const span of active) {\n span.setAttribute(\"observability.incomplete\", true);\n span.end();\n }\n try {\n await provider.shutdown();\n } finally {\n localContext.disable();\n }\n })();\n return shutdownPromise;\n },\n getDiagnostics() {\n return {\n ...processor.counters,\n eventsRetried: processor.getRetries(),\n activeSpans: active.size,\n };\n },\n };\n return engine;\n}\n","export type DiagnosticCategory =\n | \"authentication\"\n | \"network\"\n | \"timeout\"\n | \"throttling\"\n | \"oversized\"\n | \"capacity\"\n | \"shutdown\"\n | \"unknown\";\n\nexport interface DiagnosticEvent {\n readonly operation: \"export\" | \"flush\" | \"shutdown\";\n readonly category: DiagnosticCategory;\n readonly message: string;\n}\n\nconst messages: Record<DiagnosticCategory, string> = {\n authentication:\n \"Check transport credentials and permissions; Eventstream requires producer Send access.\",\n network: \"Check endpoint availability, DNS, and required network egress.\",\n timeout: \"The operation exceeded its deadline; delivery may be uncertain.\",\n throttling: \"The service is throttling; check capacity and reduce load.\",\n oversized:\n \"Reduce span content or attributes to fit the service message limit.\",\n capacity:\n \"The local export bound was reached; check load and exporter health.\",\n shutdown: \"Exporter cleanup did not complete successfully.\",\n unknown: \"Check transport configuration and endpoint health.\",\n};\n\nconst codes = new Map<string | number, DiagnosticCategory>([\n [401, \"authentication\"],\n [403, \"authentication\"],\n [429, \"throttling\"],\n [\"unauthorizedaccess\", \"authentication\"],\n [\"unauthorizederror\", \"authentication\"],\n [\"authenticationerror\", \"authentication\"],\n [\"authenticationfailed\", \"authentication\"],\n [\"amqp:unauthorized-access\", \"authentication\"],\n [\"enotfound\", \"network\"],\n [\"eai_again\", \"network\"],\n [\"econnrefused\", \"network\"],\n [\"econnreset\", \"network\"],\n [\"servicecommunicationerror\", \"network\"],\n [\"serviceunavailableerror\", \"network\"],\n [\"messagingcommunicationerror\", \"network\"],\n [\"connectionlosterror\", \"network\"],\n [\"etimedout\", \"timeout\"],\n [\"timeouterror\", \"timeout\"],\n [\"operationtimeouterror\", \"timeout\"],\n [\"aborterror\", \"timeout\"],\n [\"serverbusyerror\", \"throttling\"],\n [\"servicebusyerror\", \"throttling\"],\n [\"amqp:resource-limit-exceeded\", \"throttling\"],\n]);\nfor (const category of Object.keys(messages) as DiagnosticCategory[])\n codes.set(`eventhouse_${category}`, category);\n\nexport function classifyError(\n error: unknown,\n fallback: DiagnosticCategory = \"unknown\",\n): DiagnosticCategory {\n try {\n for (\n let depth = 0;\n depth < 3 && error && typeof error === \"object\";\n depth++\n ) {\n const current = error as {\n code?: unknown;\n name?: unknown;\n statusCode?: unknown;\n cause?: unknown;\n };\n for (const value of [current.code, current.name, current.statusCode]) {\n const key =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\" && value.length <= 128\n ? value.toLowerCase()\n : undefined;\n const category = key === undefined ? undefined : codes.get(key);\n if (category) return category;\n }\n error = current.cause;\n }\n } catch {\n // Error objects and their getters belong to third-party exporters.\n }\n return fallback;\n}\n\nexport function diagnosticEvent(\n operation: DiagnosticEvent[\"operation\"],\n category: DiagnosticCategory,\n): DiagnosticEvent {\n return Object.freeze({ operation, category, message: messages[category] });\n}\n\nexport function categorizedError(\n category: DiagnosticCategory,\n message: string,\n) {\n return Object.assign(new Error(message), { code: `EVENTHOUSE_${category}` });\n}\n","import { EventHubProducerClient } from \"@azure/event-hubs\";\nimport type { ReadableSpan, SpanExporter } from \"@opentelemetry/sdk-trace\";\nimport { serializeSpan } from \"./serialize.js\";\nimport { categorizedError, classifyError } from \"../diagnostics.js\";\n\nexport { serializeSpan } from \"./serialize.js\";\nexport type { SerializedSpan } from \"./serialize.js\";\n\nexport interface EventstreamExporterOptions {\n connectionString: string;\n entityName?: string;\n maxBatchSizeBytes?: number;\n /** Total deadline for one export, including SDK retries. Defaults to 30000. */\n exportTimeoutMs?: number;\n /** Overall drain/close deadline. Defaults to 30000. */\n shutdownTimeoutMs?: number;\n /** Maximum underlying operations, including aborted operations still pending. Defaults to 4. */\n maxConcurrentExports?: number;\n}\n\nfunction positiveInteger(value: number, name: string, max: number): number {\n if (!Number.isSafeInteger(value) || value < 1 || value > max)\n throw new Error(\n `Eventstream ${name} must be an integer between 1 and ${max}.`,\n );\n return value;\n}\n\nfunction invalidConfiguration(): never {\n throw new Error(\"Invalid Eventstream connection configuration.\");\n}\n\nfunction validateConnection(\n options: EventstreamExporterOptions,\n): string | undefined {\n if (\n typeof options.connectionString !== \"string\" ||\n !options.connectionString.trim()\n ) {\n invalidConfiguration();\n }\n const fields = new Map<string, string>();\n for (const part of options.connectionString.trim().split(\";\")) {\n if (!part.trim()) continue;\n const separator = part.indexOf(\"=\");\n if (separator <= 0) invalidConfiguration();\n const name = part.slice(0, separator).trim().toLowerCase();\n const value = part.slice(separator + 1).trim();\n if (fields.has(name) || !value || /[\\r\\n\\0]/u.test(value))\n invalidConfiguration();\n if (\n ![\n \"endpoint\",\n \"sharedaccesskeyname\",\n \"sharedaccesskey\",\n \"entitypath\",\n ].includes(name)\n ) {\n invalidConfiguration();\n }\n fields.set(name, value);\n }\n if (!fields.has(\"sharedaccesskeyname\") || !fields.has(\"sharedaccesskey\")) {\n invalidConfiguration();\n }\n try {\n const endpoint = new URL(fields.get(\"endpoint\") ?? \"\");\n if (\n endpoint.protocol !== \"sb:\" ||\n !endpoint.hostname ||\n endpoint.username ||\n endpoint.password ||\n endpoint.search ||\n endpoint.hash ||\n (endpoint.pathname !== \"/\" && endpoint.pathname !== \"\")\n )\n invalidConfiguration();\n } catch {\n invalidConfiguration();\n }\n const entityPath = fields.get(\"entitypath\");\n if (\n options.entityName !== undefined &&\n (typeof options.entityName !== \"string\" ||\n !options.entityName.trim() ||\n /[;\\r\\n\\0]/u.test(options.entityName))\n )\n invalidConfiguration();\n const entityName = options.entityName?.trim();\n if (!entityPath && !entityName) invalidConfiguration();\n if (entityPath && entityName && entityPath !== entityName)\n invalidConfiguration();\n if (\n options.maxBatchSizeBytes !== undefined &&\n (!Number.isSafeInteger(options.maxBatchSizeBytes) ||\n options.maxBatchSizeBytes <= 0)\n ) {\n throw new Error(\n \"Eventstream maxBatchSizeBytes must be a positive safe integer.\",\n );\n }\n return entityPath ? undefined : entityName;\n}\n\n/** Sends JSON events to Fabric's Custom endpoint SOURCE using AMQP over TLS. */\nexport class EventstreamExporter implements SpanExporter {\n private readonly producer: EventHubProducerClient;\n private readonly maxBatchSizeBytes: number | undefined;\n private readonly active = new Map<\n AbortController,\n { operation: Promise<void>; expire: () => void }\n >();\n private readonly exportTimeout: number;\n private readonly shutdownTimeout: number;\n private readonly maxConcurrentExports: number;\n private closing = false;\n private shutdownPromise: Promise<void> | undefined;\n private producerClosePromise: Promise<void> | undefined;\n\n constructor(options: EventstreamExporterOptions) {\n const entityName = validateConnection(options);\n this.maxBatchSizeBytes = options.maxBatchSizeBytes;\n this.exportTimeout = positiveInteger(\n options.exportTimeoutMs ?? 30000,\n \"exportTimeoutMs\",\n 3600000,\n );\n this.shutdownTimeout = positiveInteger(\n options.shutdownTimeoutMs ?? 30000,\n \"shutdownTimeoutMs\",\n 3600000,\n );\n this.maxConcurrentExports = positiveInteger(\n options.maxConcurrentExports ?? 4,\n \"maxConcurrentExports\",\n 1024,\n );\n try {\n this.producer = entityName\n ? new EventHubProducerClient(options.connectionString, entityName)\n : new EventHubProducerClient(options.connectionString);\n } catch {\n throw new Error(\"Unable to initialize Eventstream transport.\");\n }\n }\n\n export(\n spans: ReadableSpan[],\n callback: Parameters<SpanExporter[\"export\"]>[1],\n signal?: AbortSignal,\n ): void {\n if (this.closing) {\n queueMicrotask(() =>\n callback({\n code: 1,\n error: categorizedError(\n \"shutdown\",\n \"Eventstream exporter is shut down.\",\n ),\n }),\n );\n return;\n }\n if (spans.length === 0) {\n queueMicrotask(() => callback({ code: 0 }));\n return;\n }\n if (this.active.size >= this.maxConcurrentExports) {\n queueMicrotask(() =>\n callback({\n code: 1,\n error: categorizedError(\n \"capacity\",\n \"Eventstream export concurrency limit reached.\",\n ),\n }),\n );\n return;\n }\n const controller = new AbortController();\n const progress = { exportedSpans: 0 };\n let settled = false;\n const finish = (failed: boolean, error?: unknown) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n signal?.removeEventListener(\"abort\", expire);\n const droppedSpans = spans.length - progress.exportedSpans;\n // This optional result extension preserves ordinary SpanExporter consumers.\n const result = {\n code: failed || droppedSpans > 0 ? 1 : 0,\n exportedSpans: progress.exportedSpans,\n droppedSpans,\n ...(failed || droppedSpans > 0\n ? {\n error: categorizedError(\n classifyError(error, failed ? \"unknown\" : \"oversized\"),\n \"Eventstream export failed; events may have been partially delivered.\",\n ),\n }\n : {}),\n };\n callback(result);\n };\n const expire = () => {\n controller.abort();\n finish(\n true,\n categorizedError(\"timeout\", \"Eventstream export deadline expired.\"),\n );\n };\n const deadline = setTimeout(expire, this.exportTimeout);\n signal?.addEventListener(\"abort\", expire, { once: true });\n if (signal?.aborted) {\n expire();\n return;\n }\n const operation = this.send(spans, controller.signal, progress);\n this.active.set(controller, { operation, expire });\n const complete = (failed: boolean, error?: unknown) => {\n this.active.delete(controller);\n finish(failed, error);\n };\n // Keep the slot until I/O actually settles, even if an SDK ignores abort.\n void operation.then(\n () => complete(false),\n (error: unknown) => complete(true, error),\n );\n }\n\n private async send(\n spans: readonly ReadableSpan[],\n signal: AbortSignal,\n progress: { exportedSpans: number },\n ): Promise<void> {\n const options = {\n abortSignal: signal,\n ...(this.maxBatchSizeBytes === undefined\n ? {}\n : { maxSizeInBytes: this.maxBatchSizeBytes }),\n };\n let batch = await this.producer.createBatch(options);\n signal.throwIfAborted();\n const sendBatch = async () => {\n const count = batch.count;\n if (count === 0) return;\n signal.throwIfAborted();\n await this.producer.sendBatch(batch, { abortSignal: signal });\n progress.exportedSpans += count;\n signal.throwIfAborted();\n };\n for (const span of spans) {\n signal.throwIfAborted();\n const event = {\n body: serializeSpan(span),\n contentType: \"application/json\",\n };\n if (batch.tryAdd(event)) continue;\n // A fresh empty batch is authoritative for oversized messages.\n if (batch.count === 0) continue;\n await sendBatch();\n batch = await this.producer.createBatch(options);\n signal.throwIfAborted();\n if (!batch.tryAdd(event)) {\n continue;\n }\n }\n await sendBatch();\n }\n\n shutdown(signal?: AbortSignal): Promise<void> {\n if (!this.shutdownPromise) {\n this.closing = true;\n this.shutdownPromise = this.close(signal);\n }\n return this.shutdownPromise;\n }\n\n private async close(signal?: AbortSignal): Promise<void> {\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let expire: (() => void) | undefined;\n try {\n await Promise.race([\n (async () => {\n await Promise.allSettled(\n [...this.active.values()].map(({ operation }) => operation),\n );\n await this.closeProducer();\n })(),\n new Promise<never>((_resolve, reject) => {\n expire = () => {\n for (const { expire } of this.active.values()) expire();\n void this.closeProducer().catch(() => {});\n reject(categorizedError(\"timeout\", \"Eventstream shutdown failed.\"));\n };\n signal?.addEventListener(\"abort\", expire, { once: true });\n if (signal?.aborted) expire();\n else deadline = setTimeout(expire, this.shutdownTimeout);\n }),\n ]);\n } catch (error) {\n throw categorizedError(\n classifyError(error, \"shutdown\"),\n \"Eventstream shutdown failed.\",\n );\n } finally {\n clearTimeout(deadline);\n if (expire) signal?.removeEventListener(\"abort\", expire);\n this.active.clear();\n }\n }\n\n private closeProducer(): Promise<void> {\n this.producerClosePromise ??= Promise.resolve().then(() =>\n this.producer.close(),\n );\n return this.producerClosePromise;\n }\n}\n","import type { ReadableSpan } from \"@opentelemetry/sdk-trace\";\n\ntype HrTime = ReadableSpan[\"startTime\"];\n\nfunction isoTime(time: HrTime): string {\n return new Date(\n time[0] * 1_000 + Math.floor(time[1] / 1_000_000),\n ).toISOString();\n}\n\nfunction stringAttribute(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\n/** JSON-compatible, framework-neutral Eventstream schema. Times are UTC ISO 8601. */\nexport function serializeSpan(span: ReadableSpan) {\n const context = span.spanContext();\n const resourceAttributes = { ...span.resource.attributes };\n const startTime = isoTime(span.startTime);\n const endTime = isoTime(span.endTime);\n return {\n schemaVersion: \"1.0\" as const,\n timestamp: endTime,\n traceId: context.traceId,\n spanId: context.spanId,\n parentSpanId: span.parentSpanContext?.spanId ?? null,\n spanName: span.name,\n spanKind: span.kind,\n startTime,\n endTime,\n durationMs: span.duration[0] * 1_000 + span.duration[1] / 1_000_000,\n status: span.status.code,\n statusMessage: span.status.message ?? null,\n serviceName: stringAttribute(resourceAttributes[\"service.name\"]),\n serviceVersion: stringAttribute(resourceAttributes[\"service.version\"]),\n environment: stringAttribute(\n resourceAttributes[\"deployment.environment.name\"] ??\n resourceAttributes[\"deployment.environment\"],\n ),\n resourceAttributes,\n spanAttributes: { ...span.attributes },\n events: span.events.map((event) => ({\n name: event.name,\n timestamp: isoTime(event.time),\n attributes: { ...event.attributes },\n droppedAttributesCount: event.droppedAttributesCount ?? 0,\n })),\n links: span.links.map((link) => ({\n traceId: link.context.traceId,\n spanId: link.context.spanId,\n traceFlags: link.context.traceFlags,\n traceState: link.context.traceState?.serialize() ?? null,\n attributes: { ...link.attributes },\n droppedAttributesCount: link.droppedAttributesCount ?? 0,\n })),\n };\n}\n\nexport type SerializedSpan = ReturnType<typeof serializeSpan>;\n","import {\n createEngine,\n type CoreOptions,\n type Observability,\n} from \"./engine.js\";\nimport { EventstreamExporter } from \"./exporters/eventstream.js\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\n\nexport { createEngine, redactSecrets } from \"./engine.js\";\nexport type {\n CoreOptions,\n Diagnostics,\n DiagnosticCategory,\n DiagnosticEvent,\n Observability,\n Redactor,\n} from \"./engine.js\";\nexport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\nexport { EventstreamExporter, serializeSpan } from \"./exporters/eventstream.js\";\nexport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\n\nexport interface EventhouseObservabilityOptions extends Omit<\n CoreOptions,\n \"exporter\"\n> {\n connectionString?: string;\n entityName?: string;\n transport?: \"eventstream\" | \"otlp\";\n exporter?: SpanExporter;\n endpoint?: string;\n headers?: Record<string, string>;\n maxBatchSizeBytes?: number;\n}\n\nfunction envNumber(name: string): number | undefined {\n const raw = process.env[name];\n if (raw === undefined) return undefined;\n if (raw.trim() === \"\" || !Number.isFinite(Number(raw))) {\n throw new Error(`${name} must be a finite number`);\n }\n return Number(raw);\n}\n\nfunction envHeaders(): Record<string, string> | undefined {\n const raw =\n process.env.OTEL_EXPORTER_OTLP_TRACES_HEADERS ??\n process.env.OTEL_EXPORTER_OTLP_HEADERS;\n if (!raw) return undefined;\n const result: Record<string, string> = {};\n for (const entry of raw.split(\",\")) {\n const equals = entry.indexOf(\"=\");\n if (equals < 1)\n throw new Error(\"Invalid OTLP header environment configuration\");\n try {\n result[entry.slice(0, equals).trim()] = decodeURIComponent(\n entry.slice(equals + 1).trim(),\n );\n } catch {\n throw new Error(\"Invalid OTLP header environment configuration\");\n }\n }\n return result;\n}\n\nexport function createObservability(\n options: EventhouseObservabilityOptions = {},\n): Observability {\n const connectionString =\n options.connectionString ??\n process.env.FABRIC_EVENTSTREAM_CONNECTION_STRING;\n const selection =\n options.transport ?? (connectionString ? \"eventstream\" : \"otlp\");\n let exporter: SpanExporter;\n if (options.exporter) {\n exporter = options.exporter;\n } else if (selection === \"eventstream\") {\n if (!connectionString)\n throw new Error(\"Fabric Eventstream connectionString is required\");\n const entityName =\n options.entityName ?? process.env.FABRIC_EVENTSTREAM_ENTITY_NAME;\n exporter = new EventstreamExporter({\n connectionString,\n ...(entityName ? { entityName } : {}),\n ...(options.maxBatchSizeBytes\n ? { maxBatchSizeBytes: options.maxBatchSizeBytes }\n : {}),\n ...(options.exportTimeoutMs !== undefined\n ? { exportTimeoutMs: options.exportTimeoutMs }\n : {}),\n ...(options.shutdownTimeoutMs !== undefined\n ? { shutdownTimeoutMs: options.shutdownTimeoutMs }\n : {}),\n ...(options.maxConcurrentExports !== undefined\n ? { maxConcurrentExports: options.maxConcurrentExports }\n : {}),\n });\n } else if (selection === \"otlp\") {\n const base = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;\n const endpoint =\n options.endpoint ??\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ??\n (base ? `${base.replace(/\\/$/, \"\")}/v1/traces` : undefined);\n if (!endpoint)\n throw new Error(\n \"Supply a Fabric connection string or an explicit OTLP traces endpoint\",\n );\n const headers = options.headers ?? envHeaders();\n try {\n const url = new URL(endpoint);\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.username ||\n url.password\n )\n throw new Error();\n } catch {\n throw new Error(\"Invalid OTLP endpoint configuration.\");\n }\n for (const [name, value] of Object.entries(headers ?? {})) {\n if (\n !/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(name) ||\n /[\\r\\n\\0]/u.test(value)\n ) {\n throw new Error(\"Invalid OTLP headers configuration.\");\n }\n }\n exporter = new OTLPTraceExporter({\n url: endpoint,\n ...(headers ? { headers } : {}),\n });\n } else {\n throw new Error(\"Unsupported telemetry transport\");\n }\n const serviceName = options.serviceName ?? process.env.OTEL_SERVICE_NAME;\n const serviceVersion =\n options.serviceVersion ?? process.env.OTEL_SERVICE_VERSION;\n const environment = options.environment ?? process.env.DEPLOYMENT_ENVIRONMENT;\n const samplingRatio =\n options.samplingRatio ?? envNumber(\"EVENTHOUSE_SAMPLING_RATIO\");\n const batchSize = options.batchSize ?? envNumber(\"EVENTHOUSE_BATCH_SIZE\");\n const flushIntervalMs =\n options.flushIntervalMs ?? envNumber(\"EVENTHOUSE_FLUSH_INTERVAL_MS\");\n return createEngine({\n ...options,\n exporter,\n ...(serviceName ? { serviceName } : {}),\n ...(serviceVersion ? { serviceVersion } : {}),\n ...(environment ? { environment } : {}),\n ...(samplingRatio !== undefined ? { samplingRatio } : {}),\n ...(batchSize !== undefined ? { batchSize } : {}),\n ...(flushIntervalMs !== undefined ? { flushIntervalMs } : {}),\n });\n}\n"],"mappings":";AAAA,SAAS,yBAAyB;AAClC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AACP,SAAS,8BAA8B;;;ACIvC,IAAM,WAA+C;AAAA,EACnD,gBACE;AAAA,EACF,SAAS;AAAA,EACT,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,WACE;AAAA,EACF,UACE;AAAA,EACF,UAAU;AAAA,EACV,SAAS;AACX;AAEA,IAAM,QAAQ,oBAAI,IAAyC;AAAA,EACzD,CAAC,KAAK,gBAAgB;AAAA,EACtB,CAAC,KAAK,gBAAgB;AAAA,EACtB,CAAC,KAAK,YAAY;AAAA,EAClB,CAAC,sBAAsB,gBAAgB;AAAA,EACvC,CAAC,qBAAqB,gBAAgB;AAAA,EACtC,CAAC,uBAAuB,gBAAgB;AAAA,EACxC,CAAC,wBAAwB,gBAAgB;AAAA,EACzC,CAAC,4BAA4B,gBAAgB;AAAA,EAC7C,CAAC,aAAa,SAAS;AAAA,EACvB,CAAC,aAAa,SAAS;AAAA,EACvB,CAAC,gBAAgB,SAAS;AAAA,EAC1B,CAAC,cAAc,SAAS;AAAA,EACxB,CAAC,6BAA6B,SAAS;AAAA,EACvC,CAAC,2BAA2B,SAAS;AAAA,EACrC,CAAC,+BAA+B,SAAS;AAAA,EACzC,CAAC,uBAAuB,SAAS;AAAA,EACjC,CAAC,aAAa,SAAS;AAAA,EACvB,CAAC,gBAAgB,SAAS;AAAA,EAC1B,CAAC,yBAAyB,SAAS;AAAA,EACnC,CAAC,cAAc,SAAS;AAAA,EACxB,CAAC,mBAAmB,YAAY;AAAA,EAChC,CAAC,oBAAoB,YAAY;AAAA,EACjC,CAAC,gCAAgC,YAAY;AAC/C,CAAC;AACD,WAAW,YAAY,OAAO,KAAK,QAAQ;AACzC,QAAM,IAAI,cAAc,QAAQ,IAAI,QAAQ;AAEvC,SAAS,cACd,OACA,WAA+B,WACX;AACpB,MAAI;AACF,aACM,QAAQ,GACZ,QAAQ,KAAK,SAAS,OAAO,UAAU,UACvC,SACA;AACA,YAAM,UAAU;AAMhB,iBAAW,SAAS,CAAC,QAAQ,MAAM,QAAQ,MAAM,QAAQ,UAAU,GAAG;AACpE,cAAM,MACJ,OAAO,UAAU,WACb,QACA,OAAO,UAAU,YAAY,MAAM,UAAU,MAC3C,MAAM,YAAY,IAClB;AACR,cAAM,WAAW,QAAQ,SAAY,SAAY,MAAM,IAAI,GAAG;AAC9D,YAAI,SAAU,QAAO;AAAA,MACvB;AACA,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEO,SAAS,gBACd,WACA,UACiB;AACjB,SAAO,OAAO,OAAO,EAAE,WAAW,UAAU,SAAS,SAAS,QAAQ,EAAE,CAAC;AAC3E;AAEO,SAAS,iBACd,UACA,SACA;AACA,SAAO,OAAO,OAAO,IAAI,MAAM,OAAO,GAAG,EAAE,MAAM,cAAc,QAAQ,GAAG,CAAC;AAC7E;;;ADrFA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AA6DP,SAAS,QACP,OACA,MACA,KACA,KACQ;AACR,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,OAAO,QAAQ,KAAK;AACzD,UAAM,IAAI,MAAM,GAAG,IAAI,oBAAoB,GAAG,QAAQ,GAAG,EAAE;AAAA,EAC7D;AACA,SAAO;AACT;AAEA,IAAM,YACJ;AACF,IAAM,aACJ;AAEK,SAAS,cAAc,OAAuB;AACnD,SAAO,MACJ,QAAQ,kCAAkC,8BAA8B,EACxE,QAAQ,sDAAsD,YAAY,EAC1E,QAAQ,qCAAqC,mBAAmB,EAChE,QAAQ,uCAAuC,cAAc;AAClE;AAEA,SAAS,cAAc,SAAsB;AAC3C,QAAM,aAAa,CACjB,KACA,UAC+B;AAC/B,QACE,UAAU,KAAK,GAAG,KACjB,CAAC,QAAQ,kBAAkB,WAAW,KAAK,GAAG;AAE/C,aAAO;AACT,UAAM,QAAQ,CAAC,SACb,OAAO,SAAS,WAAW,cAAc,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI;AAClE,QAAI,SAAyB,MAAM,QAAQ,KAAK,IAC3C,MAAM,MAAM,GAAG,EAAE,EAAE,IAAI,KAAK,IAC5B,MAAM,KAAkC;AAC7C,QAAI,QAAQ,QAAQ;AAClB,UAAI;AACF,cAAM,WAAW,QAAQ,OAAO,KAAK,MAAM;AAC3C,YAAI,aAAa,OAAW,QAAO;AACnC,iBAAS,MAAM,QAAQ,QAAQ,IAC1B,SAAS,MAAM,GAAG,EAAE,EAAE,IAAI,KAAK,IAC/B,MAAM,QAAqC;AAAA,MAClD,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,QAAM,kBAAkB,CAAC,eAAuC;AAC9D,UAAM,SAAqB,CAAC;AAC5B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,EAAE,MAAM,GAAG,EAAE,GAAG;AAClE,UAAI,UAAU,QAAW;AACvB,cAAM,UAAU,WAAW,KAAK,KAAK;AACrC,YAAI,YAAY;AACd,iBAAO,cAAc,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,IAAI;AAAA,MAC/C;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,SAAO,CAAC,UAAsC;AAAA,IAC5C,aAAa,MAAM,KAAK,YAAY;AAAA,IACpC,GAAI,KAAK,oBACL,EAAE,mBAAmB,KAAK,kBAAkB,IAC5C,CAAC;AAAA,IACL,MAAM,KAAK;AAAA,IACX,WAAW,KAAK;AAAA,IAChB,SAAS,KAAK;AAAA,IACd,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,sBAAsB,KAAK;AAAA,IAC3B,wBAAwB,KAAK;AAAA,IAC7B,oBAAoB,KAAK;AAAA,IACzB,mBAAmB,KAAK;AAAA,IACxB,MAAM,cAAc,KAAK,IAAI,EAAE,MAAM,GAAG,GAAG;AAAA,IAC3C,YAAY,gBAAgB,KAAK,UAAU;AAAA,IAC3C,UAAU,uBAAuB,gBAAgB,KAAK,SAAS,UAAU,CAAC;AAAA,IAC1E,QAAQ;AAAA,MACN,MAAM,KAAK,OAAO;AAAA,MAClB,GAAI,QAAQ,kBAAkB,KAAK,OAAO,UACtC,EAAE,SAAS,cAAc,KAAK,OAAO,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,IAC7D,CAAC;AAAA,IACP;AAAA,IACA,QAAQ,KAAK,OAAO,IAAI,CAAC,WAAW;AAAA,MAClC,GAAG;AAAA,MACH,MAAM,cAAc,MAAM,IAAI,EAAE,MAAM,GAAG,GAAG;AAAA,MAC5C,GAAI,MAAM,aACN,EAAE,YAAY,gBAAgB,MAAM,UAAU,EAAE,IAChD,CAAC;AAAA,IACP,EAAE;AAAA,IACF,OAAO,KAAK,MAAM,IAAI,CAAC,UAAU;AAAA,MAC/B,GAAG;AAAA,MACH,GAAI,KAAK,aACL,EAAE,YAAY,gBAAgB,KAAK,UAAU,EAAE,IAC/C,CAAC;AAAA,IACP,EAAE;AAAA,EACJ;AACF;AAEA,IAAM,wBAAN,MAAqD;AAAA,EAsBnD,YACmB,UACA,cACjB,WACA,UACA,SACiB,sBACA,iBACA,UACA,cACA,OACjB;AAViB;AACA;AAIA;AACA;AACA;AACA;AACA;AAEjB,SAAK,YAAY,IAAI,mBAAmB;AAAA,MACtC,UAAU;AAAA,QACR,QAAQ,CAAC,OAAO,aAAa;AAC3B,cAAI;AACJ,gBAAM,UAAU,IAAI,QAAc,CAAC,YAAY;AAC7C,uBAAW;AAAA,UACb,CAAC;AACD,eAAK,SAAS,IAAI,OAAO;AACzB,cAAI,UAAU;AACd,cAAI,SAAS;AACb,cAAI;AACJ,cAAI;AACJ,gBAAM,UAAU,MAAM;AACpB,gBAAI,CAAC,OAAQ;AACb,qBAAS;AACT,iBAAK,SAAS,cAAc,MAAM;AAAA,UACpC;AACA,gBAAM,aAAa,IAAI,gBAAgB;AACvC,gBAAM,SAAS,MAAM;AACnB,uBAAW,MAAM;AACjB,mBAAO,OAAO,QAAW,SAAS;AAAA,UACpC;AACA,gBAAM,SAAS,CACb,SACA,QAKA,aACG;AACH,gBAAI,QAAS;AACb,sBAAU;AACV,yBAAa,QAAQ;AACrB,iBAAK,UAAU,OAAO,MAAM;AAC5B,iBAAK,QAAQ,OAAO,OAAO;AAC3B,oBAAQ;AACR,kBAAM,WAAW,QAAQ;AACzB,kBAAM,UAAU,QAAQ;AACxB,kBAAM,YACJ,OAAO,UAAU,QAAQ,KACzB,OAAO,UAAU,OAAO,KACxB,YAAa,KACb,WAAY,KACZ,WAAY,YAAa,MAAM;AACjC,iBAAK,SAAS,kBAAkB,YAC5B,WACA,UACE,MAAM,SACN;AACN,iBAAK,SAAS,iBAAiB,YAC3B,UACA,UACE,IACA,MAAM;AACZ,gBAAI,CAAC,SAAS;AACZ,mBAAK,SAAS;AACd,mBAAK,OAAO,UAAU,QAAQ,OAAO,QAAQ;AAAA,YAC/C;AACA,iBAAK,SAAS,OAAO,OAAO;AAC5B,qBAAS;AAET,qBAAS,EAAE,MAAM,EAAE,CAAC;AACpB,iBAAK,WAAW;AAAA,UAClB;AACA,eAAK,UAAU,IAAI,MAAM;AAEzB,oBAAU,MAAM;AACd,gBAAI,QAAS;AACb,gBAAI,KAAK,UAAU;AACjB,qBAAO,OAAO,QAAW,UAAU;AACnC;AAAA,YACF;AACA,gBAAI,KAAK,qBAAqB,KAAK,sBAAsB;AACvD,mBAAK,QAAQ,IAAI,OAAO;AACxB,2BAAa,WAAW,QAAQ,OAAO;AACvC;AAAA,YACF;AACA,iBAAK,QAAQ,OAAO,OAAO;AAC3B,oBAAQ;AACR,iBAAK;AACL,gBAAI,WAAW;AACf,kBAAM,UAAU,MAAM;AACpB,kBAAI,SAAU;AACd,yBAAW;AACX,mBAAK;AACL,mBAAK,WAAW;AAAA,YAClB;AACA,gBAAI;AAEF,oBAAMA,YAAW,KAAK;AAOtB,oBAAM,SAASA,UAAS;AAAA,gBACtB;AAAA,gBACA,CAACC,YAAW;AACV,0BAAQ;AACR;AAAA,oBACEA,QAAO,SAAS;AAAA,oBAChBA;AAAA,kBAIF;AAAA,gBACF;AAAA,gBACA,WAAW;AAAA,cACb;AAEA,mBAAK,QAAQ,QAAQ,MAAM,EAAE,MAAM,CAAC,UAAmB;AACrD,wBAAQ;AACR,uBAAO,OAAO,EAAE,MAAM,CAAC;AAAA,cACzB,CAAC;AAAA,YACH,SAAS,OAAO;AACd,sBAAQ;AACR,qBAAO,OAAO,EAAE,MAAM,CAAC;AAAA,YACzB;AACA,gBAAI,CAAC,QAAS,cAAa,WAAW,QAAQ,OAAO;AAAA,UACvD;AACA,yBAAe,OAAO;AAAA,QACxB;AAAA,QACA,UAAU,YAAY;AACpB,gBAAM,KAAK,eAAe;AAC1B,gBAAM,KAAK,iBAAiB;AAAA,QAC9B;AAAA,MACF;AAAA,MACA,oBAAoB;AAAA,MACpB;AAAA,MACA,sBAAsB;AAAA;AAAA,MAEtB,qBAAqB,UAAU;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAlJmB;AAAA,EACA;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EA/BF;AAAA,EACA,WAAW,oBAAI,IAAmB;AAAA,EAC3C;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACS,YAAY,oBAAI,IAAgB;AAAA,EAChC,UAAU,oBAAI,IAAgB;AAAA,EAC9B,qBAAqB,IAAI,gBAAgB;AAAA,EAClD,oBAAoB;AAAA,EACpB,WAAW;AAAA,EACV,WAAwB;AAAA,IAC/B,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AAAA,EAuJA,UAAgB;AAAA,EAAC;AAAA,EAEjB,MAAM,MAA0B;AAC9B,SAAK,SAAS;AACd,QAAI,KAAK,UAAU,KAAK,SAAS,cAAc,KAAK,cAAc;AAChE,WAAK,SAAS;AACd;AAAA,IACF;AACA,QAAI;AACF,YAAM,YAAY,KAAK,SAAS,IAAI;AACpC,WAAK,SAAS;AACd,WAAK,UAAU,MAAM,SAAS;AAAA,IAChC,QAAQ;AACN,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,aAA4B;AAC1B,QAAI,KAAK,gBAAiB,QAAO,KAAK;AACtC,SAAK,iBAAiB,QAAQ,QAAQ,EAAE,KAAK,YAAY;AACvD,UAAI;AACF,WAAG;AACD,gBAAM,KAAK,UAAU,WAAW;AAChC,gBAAM,KAAK,eAAe;AAAA,QAC5B,SAAS,KAAK,SAAS,aAAa;AAAA,MACtC,SAAS,OAAO;AACd,aAAK,SAAS;AACd,aAAK,OAAO,SAAS,KAAK;AAAA,MAC5B,UAAE;AACA,aAAK,eAAe;AAAA,MACtB;AAAA,IACF,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,iBAAgC;AAC5C,WAAO,KAAK,SAAS,OAAO,EAAG,OAAM,QAAQ,IAAI,KAAK,QAAQ;AAAA,EAChE;AAAA,EAEQ,aAAmB;AACzB,QAAI,KAAK,qBAAqB,KAAK,qBAAsB;AACzD,UAAM,SAAS,KAAK,QAAQ,OAAO,EAAE,KAAK,EAAE;AAC5C,QAAI,CAAC,OAAQ;AACb,SAAK,QAAQ,OAAO,MAAM;AAC1B,mBAAe,MAAM;AACnB,aAAO;AACP,WAAK,WAAW;AAAA,IAClB,CAAC;AAAA,EACH;AAAA,EAEA,WAA0B;AACxB,SAAK,qBAAqB,YAAY;AACpC,WAAK,SAAS;AACd,UAAI;AACJ,UAAI;AACF,cAAM,QAAQ,KAAK;AAAA,UACjB,KAAK,UAAU,SAAS;AAAA,UACxB,IAAI,QAAc,CAAC,YAAY;AAC7B,uBAAW,WAAW,MAAM;AAC1B,mBAAK,SAAS;AACd,mBAAK,OAAO,YAAY,QAAW,SAAS;AAC5C,mBAAK,mBAAmB,MAAM;AAC9B,sBAAQ;AAAA,YACV,GAAG,KAAK,eAAe;AAAA,UACzB,CAAC;AAAA,QACH,CAAC;AAAA,MACH,SAAS,OAAO;AACd,aAAK,SAAS;AACd,aAAK,OAAO,YAAY,OAAO,UAAU;AAAA,MAC3C,UAAE;AACA,qBAAa,QAAQ;AACrB,aAAK,WAAW;AAChB,mBAAW,UAAU,KAAK,UAAW,QAAO;AAC5C,aAAK,SAAS,iBAAiB,KAAK,SAAS;AAC7C,aAAK,SAAS,aAAa;AAE3B,aAAK,KAAK,iBAAiB;AAAA,MAC7B;AAAA,IACF,GAAG;AACH,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,mBAAkC;AACxC,SAAK,4BAA4B,QAAQ,QAAQ,EAC9C,KAAK,MAAM;AACV,YAAM,WAAW,KAAK;AAGtB,aAAO,SAAS,SAAS,KAAK,mBAAmB,MAAM;AAAA,IACzD,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,UAAI,CAAC,KAAK,YAAY,CAAC,KAAK,mBAAmB,OAAO,SAAS;AAC7D,aAAK,SAAS;AACd,aAAK,OAAO,YAAY,OAAO,UAAU;AAAA,MAC3C;AAAA,IACF,CAAC;AACH,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAqB;AACnB,QAAI;AACF,YAAM,WAAW,KAAK;AAGtB,aAAO,SAAS,iBAAiB,EAAE,iBAAiB;AAAA,IACtD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,OACN,WACA,OACA,UACM;AACN,UAAM,QAAQ,gBAAgB,WAAW,cAAc,OAAO,QAAQ,CAAC;AACvE,SAAK,SAAS,YAAY;AAC1B,QAAI;AACF,WAAK,QAAQ,QAAQ,KAAK,eAAe,KAAK,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACjE,QAAQ;AAAA,IAAC;AACT,QAAI,KAAK,OAAO;AACd,UAAI;AACF,gBAAQ;AAAA,UACN,sBAAsB,MAAM,SAAS,KAAK,MAAM,QAAQ,KAAK,MAAM,OAAO;AAAA,QAC5E;AAAA,MACF,QAAQ;AAAA,MAAC;AAAA,IACX;AAAA,EACF;AACF;AAEO,SAAS,aAAa,SAAqC;AAChE,QAAM,QAAQ,QAAQ,QAAQ,iBAAiB,GAAG,iBAAiB,GAAG,CAAC;AACvE,QAAM,WAAW;AAAA,IACf,QAAQ,gBAAgB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,YAAY,QAAQ,QAAQ,aAAa,KAAK,aAAa,GAAG,QAAQ;AAC5E,QAAM,WAAW;AAAA,IACf,QAAQ,mBAAmB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,UAAU;AAAA,IACd,QAAQ,mBAAmB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,uBAAuB;AAAA,IAC3B,QAAQ,wBAAwB;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,kBAAkB;AAAA,IACtB,QAAQ,qBAAqB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,iBAAiB;AAAA,IACrB,QAAQ,kBAAkB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ;AAAA,IACzC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,GAAG;AACF,QAAI,CAAC,OAAO,UAAU,KAAK,EAAG,OAAM,IAAI,MAAM,GAAG,IAAI,qBAAqB;AAAA,EAC5E;AACA,QAAM,YAAY,IAAI;AAAA,IACpB,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,OAAO;AAAA,IACrB,QAAQ;AAAA,IACR,QAAQ,SAAS;AAAA,EACnB;AACA,QAAM,WAAW,IAAI,eAAe;AAAA,IAClC,UAAU,uBAAuB;AAAA,MAC/B,GAAG,QAAQ;AAAA,MACX,gBAAgB,QAAQ,eAAe;AAAA,MACvC,GAAI,QAAQ,iBACR,EAAE,mBAAmB,QAAQ,eAAe,IAC5C,CAAC;AAAA,MACL,GAAI,QAAQ,cACR,EAAE,+BAA+B,QAAQ,YAAY,IACrD,CAAC;AAAA,IACP,CAAC;AAAA,IACD,SAAS,IAAI,mBAAmB;AAAA,MAC9B,MAAM,IAAI,yBAAyB,KAAK;AAAA,IAC1C,CAAC;AAAA,IACD,gBAAgB,CAAC,SAAS;AAAA,IAC1B,YAAY;AAAA,MACV,qBAAqB;AAAA,MACrB,2BAA2B;AAAA,MAC3B,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,6BAA6B;AAAA,MAC7B,4BAA4B;AAAA,IAC9B;AAAA,EACF,CAAC;AACD,QAAM,SAAS,SAAS;AAAA,IACtB;AAAA,IACA;AAAA,EACF;AACA,QAAM,eAAe,IAAI,kBAA2B;AACpD,QAAM,SAAS,oBAAI,IAAU;AAC7B,MAAI,SAAS;AACb,MAAI;AACJ,QAAM,SAAwB;AAAA,IAC5B,gBAAgB,QAAQ,kBAAkB;AAAA,IAC1C;AAAA,IACA,UAAU,MAAM,cAAc,CAAC,GAAG;AAChC,UAAI,UAAU,OAAO,QAAQ,gBAAgB;AAC3C,kBAAU,SAAS;AACnB,eAAO,MAAM,gBAAgB,oBAAoB;AAAA,MACnD;AACA,YAAM,EAAE,QAAQ,GAAG,YAAY,IAAI;AACnC,YAAM,UAAU,aAAa,SAAS,KAAK,QAAQ,OAAO;AAC1D,YAAM,gBAAgB,SAClB,iBAAiB,SACf,MAAM,QAAQ,SAAS,MAAM,IAC7B,SACF;AACJ,YAAM,OAAO,OAAO,UAAU,MAAM,aAAa,aAAa;AAC9D,UAAI,KAAK,YAAY,GAAG;AACtB,eAAO,IAAI,IAAI;AACf,cAAM,MAAM,KAAK,IAAI,KAAK,IAAI;AAC9B,aAAK,MAAM,CAAC,SAAS;AACnB,iBAAO,OAAO,IAAI;AAClB,cAAI,IAAI;AAAA,QACV;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,SAAS,MAAM,UAAU;AACvB,UAAI,OAAQ,QAAO,SAAS;AAC5B,YAAM,SACJ,aAAa,SAAS,KAAK,QAAQ,OAAO,KAAK;AACjD,YAAM,UAAU,MAAM,QAAQ,QAAQ,IAAI;AAC1C,aAAO,aAAa,IAAI,SAAS,MAAM,QAAQ,KAAK,SAAS,QAAQ,CAAC;AAAA,IACxE;AAAA,IACA,OAAO,MAAM,UAAU,WAAW;AAAA,IAClC,WAAW;AACT,2BAAqB,YAAY;AAC/B,iBAAS;AACT,mBAAW,QAAQ,QAAQ;AACzB,eAAK,aAAa,4BAA4B,IAAI;AAClD,eAAK,IAAI;AAAA,QACX;AACA,YAAI;AACF,gBAAM,SAAS,SAAS;AAAA,QAC1B,UAAE;AACA,uBAAa,QAAQ;AAAA,QACvB;AAAA,MACF,GAAG;AACH,aAAO;AAAA,IACT;AAAA,IACA,iBAAiB;AACf,aAAO;AAAA,QACL,GAAG,UAAU;AAAA,QACb,eAAe,UAAU,WAAW;AAAA,QACpC,aAAa,OAAO;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;AEpoBA,SAAS,8BAA8B;;;ACIvC,SAAS,QAAQ,MAAsB;AACrC,SAAO,IAAI;AAAA,IACT,KAAK,CAAC,IAAI,MAAQ,KAAK,MAAM,KAAK,CAAC,IAAI,GAAS;AAAA,EAClD,EAAE,YAAY;AAChB;AAEA,SAAS,gBAAgB,OAA+B;AACtD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAGO,SAAS,cAAc,MAAoB;AAChD,QAAMC,WAAU,KAAK,YAAY;AACjC,QAAM,qBAAqB,EAAE,GAAG,KAAK,SAAS,WAAW;AACzD,QAAM,YAAY,QAAQ,KAAK,SAAS;AACxC,QAAM,UAAU,QAAQ,KAAK,OAAO;AACpC,SAAO;AAAA,IACL,eAAe;AAAA,IACf,WAAW;AAAA,IACX,SAASA,SAAQ;AAAA,IACjB,QAAQA,SAAQ;AAAA,IAChB,cAAc,KAAK,mBAAmB,UAAU;AAAA,IAChD,UAAU,KAAK;AAAA,IACf,UAAU,KAAK;AAAA,IACf;AAAA,IACA;AAAA,IACA,YAAY,KAAK,SAAS,CAAC,IAAI,MAAQ,KAAK,SAAS,CAAC,IAAI;AAAA,IAC1D,QAAQ,KAAK,OAAO;AAAA,IACpB,eAAe,KAAK,OAAO,WAAW;AAAA,IACtC,aAAa,gBAAgB,mBAAmB,cAAc,CAAC;AAAA,IAC/D,gBAAgB,gBAAgB,mBAAmB,iBAAiB,CAAC;AAAA,IACrE,aAAa;AAAA,MACX,mBAAmB,6BAA6B,KAC9C,mBAAmB,wBAAwB;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,gBAAgB,EAAE,GAAG,KAAK,WAAW;AAAA,IACrC,QAAQ,KAAK,OAAO,IAAI,CAAC,WAAW;AAAA,MAClC,MAAM,MAAM;AAAA,MACZ,WAAW,QAAQ,MAAM,IAAI;AAAA,MAC7B,YAAY,EAAE,GAAG,MAAM,WAAW;AAAA,MAClC,wBAAwB,MAAM,0BAA0B;AAAA,IAC1D,EAAE;AAAA,IACF,OAAO,KAAK,MAAM,IAAI,CAAC,UAAU;AAAA,MAC/B,SAAS,KAAK,QAAQ;AAAA,MACtB,QAAQ,KAAK,QAAQ;AAAA,MACrB,YAAY,KAAK,QAAQ;AAAA,MACzB,YAAY,KAAK,QAAQ,YAAY,UAAU,KAAK;AAAA,MACpD,YAAY,EAAE,GAAG,KAAK,WAAW;AAAA,MACjC,wBAAwB,KAAK,0BAA0B;AAAA,IACzD,EAAE;AAAA,EACJ;AACF;;;ADpCA,SAAS,gBAAgB,OAAe,MAAc,KAAqB;AACzE,MAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,KAAK,QAAQ;AACvD,UAAM,IAAI;AAAA,MACR,eAAe,IAAI,qCAAqC,GAAG;AAAA,IAC7D;AACF,SAAO;AACT;AAEA,SAAS,uBAA8B;AACrC,QAAM,IAAI,MAAM,+CAA+C;AACjE;AAEA,SAAS,mBACP,SACoB;AACpB,MACE,OAAO,QAAQ,qBAAqB,YACpC,CAAC,QAAQ,iBAAiB,KAAK,GAC/B;AACA,yBAAqB;AAAA,EACvB;AACA,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,QAAQ,QAAQ,iBAAiB,KAAK,EAAE,MAAM,GAAG,GAAG;AAC7D,QAAI,CAAC,KAAK,KAAK,EAAG;AAClB,UAAM,YAAY,KAAK,QAAQ,GAAG;AAClC,QAAI,aAAa,EAAG,sBAAqB;AACzC,UAAM,OAAO,KAAK,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY;AACzD,UAAM,QAAQ,KAAK,MAAM,YAAY,CAAC,EAAE,KAAK;AAC7C,QAAI,OAAO,IAAI,IAAI,KAAK,CAAC,SAAS,YAAY,KAAK,KAAK;AACtD,2BAAqB;AACvB,QACE,CAAC;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,SAAS,IAAI,GACf;AACA,2BAAqB;AAAA,IACvB;AACA,WAAO,IAAI,MAAM,KAAK;AAAA,EACxB;AACA,MAAI,CAAC,OAAO,IAAI,qBAAqB,KAAK,CAAC,OAAO,IAAI,iBAAiB,GAAG;AACxE,yBAAqB;AAAA,EACvB;AACA,MAAI;AACF,UAAM,WAAW,IAAI,IAAI,OAAO,IAAI,UAAU,KAAK,EAAE;AACrD,QACE,SAAS,aAAa,SACtB,CAAC,SAAS,YACV,SAAS,YACT,SAAS,YACT,SAAS,UACT,SAAS,QACR,SAAS,aAAa,OAAO,SAAS,aAAa;AAEpD,2BAAqB;AAAA,EACzB,QAAQ;AACN,yBAAqB;AAAA,EACvB;AACA,QAAM,aAAa,OAAO,IAAI,YAAY;AAC1C,MACE,QAAQ,eAAe,WACtB,OAAO,QAAQ,eAAe,YAC7B,CAAC,QAAQ,WAAW,KAAK,KACzB,aAAa,KAAK,QAAQ,UAAU;AAEtC,yBAAqB;AACvB,QAAM,aAAa,QAAQ,YAAY,KAAK;AAC5C,MAAI,CAAC,cAAc,CAAC,WAAY,sBAAqB;AACrD,MAAI,cAAc,cAAc,eAAe;AAC7C,yBAAqB;AACvB,MACE,QAAQ,sBAAsB,WAC7B,CAAC,OAAO,cAAc,QAAQ,iBAAiB,KAC9C,QAAQ,qBAAqB,IAC/B;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,aAAa,SAAY;AAClC;AAGO,IAAM,sBAAN,MAAkD;AAAA,EACtC;AAAA,EACA;AAAA,EACA,SAAS,oBAAI,IAG5B;AAAA,EACe;AAAA,EACA;AAAA,EACA;AAAA,EACT,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EAER,YAAY,SAAqC;AAC/C,UAAM,aAAa,mBAAmB,OAAO;AAC7C,SAAK,oBAAoB,QAAQ;AACjC,SAAK,gBAAgB;AAAA,MACnB,QAAQ,mBAAmB;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AACA,SAAK,kBAAkB;AAAA,MACrB,QAAQ,qBAAqB;AAAA,MAC7B;AAAA,MACA;AAAA,IACF;AACA,SAAK,uBAAuB;AAAA,MAC1B,QAAQ,wBAAwB;AAAA,MAChC;AAAA,MACA;AAAA,IACF;AACA,QAAI;AACF,WAAK,WAAW,aACZ,IAAI,uBAAuB,QAAQ,kBAAkB,UAAU,IAC/D,IAAI,uBAAuB,QAAQ,gBAAgB;AAAA,IACzD,QAAQ;AACN,YAAM,IAAI,MAAM,6CAA6C;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,OACE,OACA,UACA,QACM;AACN,QAAI,KAAK,SAAS;AAChB;AAAA,QAAe,MACb,SAAS;AAAA,UACP,MAAM;AAAA,UACN,OAAO;AAAA,YACL;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AACA;AAAA,IACF;AACA,QAAI,MAAM,WAAW,GAAG;AACtB,qBAAe,MAAM,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;AAC1C;AAAA,IACF;AACA,QAAI,KAAK,OAAO,QAAQ,KAAK,sBAAsB;AACjD;AAAA,QAAe,MACb,SAAS;AAAA,UACP,MAAM;AAAA,UACN,OAAO;AAAA,YACL;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AACA;AAAA,IACF;AACA,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,WAAW,EAAE,eAAe,EAAE;AACpC,QAAI,UAAU;AACd,UAAM,SAAS,CAAC,QAAiB,UAAoB;AACnD,UAAI,QAAS;AACb,gBAAU;AACV,mBAAa,QAAQ;AACrB,cAAQ,oBAAoB,SAAS,MAAM;AAC3C,YAAM,eAAe,MAAM,SAAS,SAAS;AAE7C,YAAM,SAAS;AAAA,QACb,MAAM,UAAU,eAAe,IAAI,IAAI;AAAA,QACvC,eAAe,SAAS;AAAA,QACxB;AAAA,QACA,GAAI,UAAU,eAAe,IACzB;AAAA,UACE,OAAO;AAAA,YACL,cAAc,OAAO,SAAS,YAAY,WAAW;AAAA,YACrD;AAAA,UACF;AAAA,QACF,IACA,CAAC;AAAA,MACP;AACA,eAAS,MAAM;AAAA,IACjB;AACA,UAAM,SAAS,MAAM;AACnB,iBAAW,MAAM;AACjB;AAAA,QACE;AAAA,QACA,iBAAiB,WAAW,sCAAsC;AAAA,MACpE;AAAA,IACF;AACA,UAAM,WAAW,WAAW,QAAQ,KAAK,aAAa;AACtD,YAAQ,iBAAiB,SAAS,QAAQ,EAAE,MAAM,KAAK,CAAC;AACxD,QAAI,QAAQ,SAAS;AACnB,aAAO;AACP;AAAA,IACF;AACA,UAAM,YAAY,KAAK,KAAK,OAAO,WAAW,QAAQ,QAAQ;AAC9D,SAAK,OAAO,IAAI,YAAY,EAAE,WAAW,OAAO,CAAC;AACjD,UAAM,WAAW,CAAC,QAAiB,UAAoB;AACrD,WAAK,OAAO,OAAO,UAAU;AAC7B,aAAO,QAAQ,KAAK;AAAA,IACtB;AAEA,SAAK,UAAU;AAAA,MACb,MAAM,SAAS,KAAK;AAAA,MACpB,CAAC,UAAmB,SAAS,MAAM,KAAK;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,MAAc,KACZ,OACA,QACA,UACe;AACf,UAAM,UAAU;AAAA,MACd,aAAa;AAAA,MACb,GAAI,KAAK,sBAAsB,SAC3B,CAAC,IACD,EAAE,gBAAgB,KAAK,kBAAkB;AAAA,IAC/C;AACA,QAAI,QAAQ,MAAM,KAAK,SAAS,YAAY,OAAO;AACnD,WAAO,eAAe;AACtB,UAAM,YAAY,YAAY;AAC5B,YAAM,QAAQ,MAAM;AACpB,UAAI,UAAU,EAAG;AACjB,aAAO,eAAe;AACtB,YAAM,KAAK,SAAS,UAAU,OAAO,EAAE,aAAa,OAAO,CAAC;AAC5D,eAAS,iBAAiB;AAC1B,aAAO,eAAe;AAAA,IACxB;AACA,eAAW,QAAQ,OAAO;AACxB,aAAO,eAAe;AACtB,YAAM,QAAQ;AAAA,QACZ,MAAM,cAAc,IAAI;AAAA,QACxB,aAAa;AAAA,MACf;AACA,UAAI,MAAM,OAAO,KAAK,EAAG;AAEzB,UAAI,MAAM,UAAU,EAAG;AACvB,YAAM,UAAU;AAChB,cAAQ,MAAM,KAAK,SAAS,YAAY,OAAO;AAC/C,aAAO,eAAe;AACtB,UAAI,CAAC,MAAM,OAAO,KAAK,GAAG;AACxB;AAAA,MACF;AAAA,IACF;AACA,UAAM,UAAU;AAAA,EAClB;AAAA,EAEA,SAAS,QAAqC;AAC5C,QAAI,CAAC,KAAK,iBAAiB;AACzB,WAAK,UAAU;AACf,WAAK,kBAAkB,KAAK,MAAM,MAAM;AAAA,IAC1C;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAc,MAAM,QAAqC;AACvD,QAAI;AACJ,QAAI;AACJ,QAAI;AACF,YAAM,QAAQ,KAAK;AAAA,SAChB,YAAY;AACX,gBAAM,QAAQ;AAAA,YACZ,CAAC,GAAG,KAAK,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,UAAU,MAAM,SAAS;AAAA,UAC5D;AACA,gBAAM,KAAK,cAAc;AAAA,QAC3B,GAAG;AAAA,QACH,IAAI,QAAe,CAAC,UAAU,WAAW;AACvC,mBAAS,MAAM;AACb,uBAAW,EAAE,QAAAC,QAAO,KAAK,KAAK,OAAO,OAAO,EAAG,CAAAA,QAAO;AACtD,iBAAK,KAAK,cAAc,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AACxC,mBAAO,iBAAiB,WAAW,8BAA8B,CAAC;AAAA,UACpE;AACA,kBAAQ,iBAAiB,SAAS,QAAQ,EAAE,MAAM,KAAK,CAAC;AACxD,cAAI,QAAQ,QAAS,QAAO;AAAA,cACvB,YAAW,WAAW,QAAQ,KAAK,eAAe;AAAA,QACzD,CAAC;AAAA,MACH,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM;AAAA,QACJ,cAAc,OAAO,UAAU;AAAA,QAC/B;AAAA,MACF;AAAA,IACF,UAAE;AACA,mBAAa,QAAQ;AACrB,UAAI,OAAQ,SAAQ,oBAAoB,SAAS,MAAM;AACvD,WAAK,OAAO,MAAM;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,gBAA+B;AACrC,SAAK,yBAAyB,QAAQ,QAAQ,EAAE;AAAA,MAAK,MACnD,KAAK,SAAS,MAAM;AAAA,IACtB;AACA,WAAO,KAAK;AAAA,EACd;AACF;;;AExTA,SAAS,yBAAyB;AAclC,SAAS,qBAAAC,0BAAyB;AAelC,SAAS,UAAU,MAAkC;AACnD,QAAM,MAAM,QAAQ,IAAI,IAAI;AAC5B,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI,IAAI,KAAK,MAAM,MAAM,CAAC,OAAO,SAAS,OAAO,GAAG,CAAC,GAAG;AACtD,UAAM,IAAI,MAAM,GAAG,IAAI,0BAA0B;AAAA,EACnD;AACA,SAAO,OAAO,GAAG;AACnB;AAEA,SAAS,aAAiD;AACxD,QAAM,MACJ,QAAQ,IAAI,qCACZ,QAAQ,IAAI;AACd,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,SAAiC,CAAC;AACxC,aAAW,SAAS,IAAI,MAAM,GAAG,GAAG;AAClC,UAAM,SAAS,MAAM,QAAQ,GAAG;AAChC,QAAI,SAAS;AACX,YAAM,IAAI,MAAM,+CAA+C;AACjE,QAAI;AACF,aAAO,MAAM,MAAM,GAAG,MAAM,EAAE,KAAK,CAAC,IAAI;AAAA,QACtC,MAAM,MAAM,SAAS,CAAC,EAAE,KAAK;AAAA,MAC/B;AAAA,IACF,QAAQ;AACN,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,oBACd,UAA0C,CAAC,GAC5B;AACf,QAAM,mBACJ,QAAQ,oBACR,QAAQ,IAAI;AACd,QAAM,YACJ,QAAQ,cAAc,mBAAmB,gBAAgB;AAC3D,MAAI;AACJ,MAAI,QAAQ,UAAU;AACpB,eAAW,QAAQ;AAAA,EACrB,WAAW,cAAc,eAAe;AACtC,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,iDAAiD;AACnE,UAAM,aACJ,QAAQ,cAAc,QAAQ,IAAI;AACpC,eAAW,IAAI,oBAAoB;AAAA,MACjC;AAAA,MACA,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,MACnC,GAAI,QAAQ,oBACR,EAAE,mBAAmB,QAAQ,kBAAkB,IAC/C,CAAC;AAAA,MACL,GAAI,QAAQ,oBAAoB,SAC5B,EAAE,iBAAiB,QAAQ,gBAAgB,IAC3C,CAAC;AAAA,MACL,GAAI,QAAQ,sBAAsB,SAC9B,EAAE,mBAAmB,QAAQ,kBAAkB,IAC/C,CAAC;AAAA,MACL,GAAI,QAAQ,yBAAyB,SACjC,EAAE,sBAAsB,QAAQ,qBAAqB,IACrD,CAAC;AAAA,IACP,CAAC;AAAA,EACH,WAAW,cAAc,QAAQ;AAC/B,UAAM,OAAO,QAAQ,IAAI;AACzB,UAAM,WACJ,QAAQ,YACR,QAAQ,IAAI,uCACX,OAAO,GAAG,KAAK,QAAQ,OAAO,EAAE,CAAC,eAAe;AACnD,QAAI,CAAC;AACH,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AACF,UAAM,UAAU,QAAQ,WAAW,WAAW;AAC9C,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,QAAQ;AAC5B,UACE,CAAC,CAAC,SAAS,QAAQ,EAAE,SAAS,IAAI,QAAQ,KAC1C,IAAI,YACJ,IAAI;AAEJ,cAAM,IAAI,MAAM;AAAA,IACpB,QAAQ;AACN,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,WAAW,CAAC,CAAC,GAAG;AACzD,UACE,CAAC,iCAAiC,KAAK,IAAI,KAC3C,YAAY,KAAK,KAAK,GACtB;AACA,cAAM,IAAI,MAAM,qCAAqC;AAAA,MACvD;AAAA,IACF;AACA,eAAW,IAAI,kBAAkB;AAAA,MAC/B,KAAK;AAAA,MACL,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC/B,CAAC;AAAA,EACH,OAAO;AACL,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACA,QAAM,cAAc,QAAQ,eAAe,QAAQ,IAAI;AACvD,QAAM,iBACJ,QAAQ,kBAAkB,QAAQ,IAAI;AACxC,QAAM,cAAc,QAAQ,eAAe,QAAQ,IAAI;AACvD,QAAM,gBACJ,QAAQ,iBAAiB,UAAU,2BAA2B;AAChE,QAAM,YAAY,QAAQ,aAAa,UAAU,uBAAuB;AACxE,QAAM,kBACJ,QAAQ,mBAAmB,UAAU,8BAA8B;AACrE,SAAO,aAAa;AAAA,IAClB,GAAG;AAAA,IACH;AAAA,IACA,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,IACrC,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;AAAA,IAC3C,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,IACrC,GAAI,kBAAkB,SAAY,EAAE,cAAc,IAAI,CAAC;AAAA,IACvD,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IAC/C,GAAI,oBAAoB,SAAY,EAAE,gBAAgB,IAAI,CAAC;AAAA,EAC7D,CAAC;AACH;","names":["exporter","result","context","expire","OTLPTraceExporter"]}
1
+ {"version":3,"sources":["../src/engine.ts","../src/diagnostics.ts","../src/exporters/eventstream.ts","../src/exporters/serialize.ts","../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport {\n context,\n trace,\n ROOT_CONTEXT,\n INVALID_SPAN_CONTEXT,\n type Attributes,\n type AttributeValue,\n type Context,\n type Span,\n type SpanOptions,\n} from \"@opentelemetry/api\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport {\n classifyError,\n diagnosticEvent,\n type DiagnosticCategory,\n type DiagnosticEvent,\n} from \"./diagnostics.js\";\nimport {\n TracerProvider,\n ParentBasedSampler,\n TraceIdRatioBasedSampler,\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanExporter,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace\";\n\nexport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\nexport type { DiagnosticCategory, DiagnosticEvent } from \"./diagnostics.js\";\n\nexport interface Diagnostics {\n eventsGenerated: number;\n eventsExported: number;\n eventsRetried: number;\n eventsDropped: number;\n exportFailures: number;\n /** Admitted spans awaiting export; excludes batches already in flight. */\n queueDepth: number;\n activeSpans: number;\n /** Latest sanitized failure only; never includes the original error or configuration. */\n lastError?: DiagnosticEvent;\n}\n\nexport type Redactor = (\n key: string,\n value: AttributeValue,\n) => AttributeValue | undefined;\n\nexport interface CoreOptions {\n exporter: SpanExporter;\n serviceName?: string;\n serviceVersion?: string;\n environment?: string;\n resourceAttributes?: Attributes;\n captureContent?: boolean;\n redact?: Redactor;\n /** Receives sanitized failure categories. Callback exceptions are contained. */\n onDiagnostic?: (event: DiagnosticEvent) => void;\n /** Prints only sanitized failure categories and fixed troubleshooting hints. */\n debug?: boolean;\n samplingRatio?: number;\n batchSize?: number;\n flushIntervalMs?: number;\n /** Export callback deadline in milliseconds. Defaults to 30000. */\n exportTimeoutMs?: number;\n /** Underlying exports, including timed-out calls still pending. Defaults to 4. */\n maxConcurrentExports?: number;\n /** Overall shutdown deadline in milliseconds, including transport cleanup. Defaults to 30000. */\n shutdownTimeoutMs?: number;\n maxQueueSize?: number;\n maxActiveSpans?: number;\n}\n\nexport interface Observability {\n readonly captureContent: boolean;\n readonly maxActiveSpans: number;\n startSpan(\n name: string,\n options?: SpanOptions & { parent?: Span | Context },\n ): Span;\n withSpan<T>(span: Span, callback: () => T): T;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n getDiagnostics(): Readonly<Diagnostics>;\n}\n\nfunction bounded(\n value: number,\n name: string,\n min: number,\n max: number,\n): number {\n if (!Number.isFinite(value) || value < min || value > max) {\n throw new Error(`${name} must be between ${min} and ${max}`);\n }\n return value;\n}\n\nconst secretKey =\n /(?:password|secret|authorization|connection.?string|api[_.-]?key|sharedaccess|access[_.-]?token)/i;\nconst contentKey =\n /(?:prompt|completion|response\\.content|input\\.messages|output\\.messages|tool\\.(?:arguments|result|output))/i;\n\nexport function redactSecrets(value: string): string {\n return value\n .replace(/(?:Endpoint=sb:\\/\\/)[^\\s\"']+/gi, \"[REDACTED_CONNECTION_STRING]\")\n .replace(/SharedAccess(?:Key|Signature)(?:Name)?=[^;\\s\"']+/gi, \"[REDACTED]\")\n .replace(/\\bBearer\\s+[A-Za-z0-9._~+/-]+=*/gi, \"Bearer [REDACTED]\")\n .replace(/([?&](?:sig|token|key)=)[^&\\s\"']+/gi, \"$1[REDACTED]\");\n}\n\nfunction makeSanitizer(options: CoreOptions) {\n const cleanValue = (\n key: string,\n value: AttributeValue,\n ): AttributeValue | undefined => {\n if (\n secretKey.test(key) ||\n (!options.captureContent && contentKey.test(key))\n )\n return undefined;\n const clean = (item: string | number | boolean | null | undefined) =>\n typeof item === \"string\" ? redactSecrets(item).slice(0, 4096) : item;\n let result: AttributeValue = Array.isArray(value)\n ? (value.slice(0, 64).map(clean) as AttributeValue)\n : (clean(value as string | number | boolean) as AttributeValue);\n if (options.redact) {\n try {\n const redacted = options.redact(key, result);\n if (redacted === undefined) return undefined;\n result = Array.isArray(redacted)\n ? (redacted.slice(0, 64).map(clean) as AttributeValue)\n : (clean(redacted as string | number | boolean) as AttributeValue);\n } catch {\n return undefined;\n }\n }\n return result;\n };\n const cleanAttributes = (attributes: Attributes): Attributes => {\n const result: Attributes = {};\n for (const [key, value] of Object.entries(attributes).slice(0, 64)) {\n if (value !== undefined) {\n const cleaned = cleanValue(key, value);\n if (cleaned !== undefined)\n result[redactSecrets(key).slice(0, 256)] = cleaned;\n }\n }\n return result;\n };\n return (span: ReadableSpan): ReadableSpan => ({\n spanContext: () => span.spanContext(),\n ...(span.parentSpanContext\n ? { parentSpanContext: span.parentSpanContext }\n : {}),\n kind: span.kind,\n startTime: span.startTime,\n endTime: span.endTime,\n duration: span.duration,\n ended: span.ended,\n instrumentationScope: span.instrumentationScope,\n droppedAttributesCount: span.droppedAttributesCount,\n droppedEventsCount: span.droppedEventsCount,\n droppedLinksCount: span.droppedLinksCount,\n name: redactSecrets(span.name).slice(0, 512),\n attributes: cleanAttributes(span.attributes),\n resource: resourceFromAttributes(cleanAttributes(span.resource.attributes)),\n status: {\n code: span.status.code,\n ...(options.captureContent && span.status.message\n ? { message: redactSecrets(span.status.message).slice(0, 4096) }\n : {}),\n },\n events: span.events.map((event) => ({\n ...event,\n name: redactSecrets(event.name).slice(0, 512),\n ...(event.attributes\n ? { attributes: cleanAttributes(event.attributes) }\n : {}),\n })),\n links: span.links.map((link) => ({\n ...link,\n ...(link.attributes\n ? { attributes: cleanAttributes(link.attributes) }\n : {}),\n })),\n });\n}\n\nclass ManagedBatchProcessor implements SpanProcessor {\n private readonly processor: BatchSpanProcessor;\n private readonly inFlight = new Set<Promise<void>>();\n private flushPromise: Promise<void> | undefined;\n private closed = false;\n private shutdownPromise: Promise<void> | undefined;\n private exporterShutdownPromise: Promise<void> | undefined;\n private readonly finishers = new Set<() => void>();\n private readonly waiters = new Set<() => void>();\n private readonly shutdownController = new AbortController();\n private underlyingExports = 0;\n private disposed = false;\n readonly counters: Diagnostics = {\n eventsGenerated: 0,\n eventsExported: 0,\n eventsRetried: 0,\n eventsDropped: 0,\n exportFailures: 0,\n queueDepth: 0,\n activeSpans: 0,\n };\n\n constructor(\n private readonly exporter: SpanExporter,\n private readonly maxQueueSize: number,\n batchSize: number,\n interval: number,\n timeout: number,\n private readonly maxConcurrentExports: number,\n private readonly shutdownTimeout: number,\n private readonly sanitize: (span: ReadableSpan) => ReadableSpan,\n private readonly onDiagnostic: CoreOptions[\"onDiagnostic\"],\n private readonly debug: boolean,\n ) {\n this.processor = new BatchSpanProcessor({\n exporter: {\n export: (spans, callback) => {\n let complete!: () => void;\n const pending = new Promise<void>((resolve) => {\n complete = resolve;\n });\n this.inFlight.add(pending);\n let settled = false;\n let queued = true;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let attempt!: () => void;\n const dequeue = () => {\n if (!queued) return;\n queued = false;\n this.counters.queueDepth -= spans.length;\n };\n const controller = new AbortController();\n const expire = () => {\n controller.abort();\n finish(false, undefined, \"timeout\");\n };\n const finish = (\n success: boolean,\n result?: {\n exportedSpans?: number;\n droppedSpans?: number;\n error?: unknown;\n },\n category?: DiagnosticCategory,\n ) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n this.finishers.delete(expire);\n this.waiters.delete(attempt);\n dequeue();\n const exported = result?.exportedSpans;\n const dropped = result?.droppedSpans;\n const hasCounts =\n Number.isInteger(exported) &&\n Number.isInteger(dropped) &&\n exported! >= 0 &&\n dropped! >= 0 &&\n exported! + dropped! === spans.length;\n this.counters.eventsExported += hasCounts\n ? exported!\n : success\n ? spans.length\n : 0;\n this.counters.eventsDropped += hasCounts\n ? dropped!\n : success\n ? 0\n : spans.length;\n if (!success) {\n this.counters.exportFailures++;\n this.report(\"export\", result?.error, category);\n }\n this.inFlight.delete(pending);\n complete();\n // Failures are accounted for here, never forwarded to OTel's global logger.\n callback({ code: 0 });\n this.wakeWaiter();\n };\n this.finishers.add(expire);\n // BSP can start an export directly in onEnd when the batch fills.\n attempt = () => {\n if (settled) return;\n if (this.disposed) {\n finish(false, undefined, \"shutdown\");\n return;\n }\n if (this.underlyingExports >= this.maxConcurrentExports) {\n this.waiters.add(attempt);\n deadline ??= setTimeout(expire, timeout);\n return;\n }\n this.waiters.delete(attempt);\n dequeue();\n this.underlyingExports++;\n let released = false;\n const release = () => {\n if (released) return;\n released = true;\n this.underlyingExports--;\n this.wakeWaiter();\n };\n try {\n // Standard exporters ignore the optional signal; Eventstream honors it.\n const exporter = this.exporter as SpanExporter & {\n export(\n spans: ReadableSpan[],\n callback: Parameters<SpanExporter[\"export\"]>[1],\n signal?: AbortSignal,\n ): void;\n };\n const result = exporter.export(\n spans,\n (result) => {\n release();\n finish(\n result.code === 0,\n result as typeof result & {\n exportedSpans?: number;\n droppedSpans?: number;\n },\n );\n },\n controller.signal,\n );\n // Also contain exporters incorrectly returning a rejected promise.\n void Promise.resolve(result).catch((error: unknown) => {\n release();\n finish(false, { error });\n });\n } catch (error) {\n release();\n finish(false, { error });\n }\n if (!settled) deadline ??= setTimeout(expire, timeout);\n };\n queueMicrotask(attempt);\n },\n shutdown: async () => {\n await this.waitForExports();\n await this.shutdownExporter();\n },\n },\n maxExportBatchSize: batchSize,\n maxQueueSize,\n scheduledDelayMillis: interval,\n // The callback deadline settles batches before BSP's fallback timeout.\n exportTimeoutMillis: timeout + 1000,\n });\n }\n\n onStart(): void {}\n\n onEnd(span: ReadableSpan): void {\n this.counters.eventsGenerated++;\n if (this.closed || this.counters.queueDepth >= this.maxQueueSize) {\n this.counters.eventsDropped++;\n return;\n }\n try {\n const sanitized = this.sanitize(span);\n this.counters.queueDepth++;\n this.processor.onEnd(sanitized);\n } catch {\n this.counters.eventsDropped++;\n }\n }\n\n forceFlush(): Promise<void> {\n if (this.shutdownPromise) return this.shutdownPromise;\n this.flushPromise ??= Promise.resolve().then(async () => {\n try {\n do {\n await this.processor.forceFlush();\n await this.waitForExports();\n } while (this.counters.queueDepth > 0);\n } catch (error) {\n this.counters.exportFailures++;\n this.report(\"flush\", error);\n } finally {\n this.flushPromise = undefined;\n }\n });\n return this.flushPromise;\n }\n\n private async waitForExports(): Promise<void> {\n while (this.inFlight.size > 0) await Promise.all(this.inFlight);\n }\n\n private wakeWaiter(): void {\n if (this.underlyingExports >= this.maxConcurrentExports) return;\n const waiter = this.waiters.values().next().value;\n if (!waiter) return;\n this.waiters.delete(waiter);\n queueMicrotask(() => {\n waiter();\n this.wakeWaiter();\n });\n }\n\n shutdown(): Promise<void> {\n this.shutdownPromise ??= (async () => {\n this.closed = true;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n this.processor.shutdown(),\n new Promise<void>((resolve) => {\n deadline = setTimeout(() => {\n this.counters.exportFailures++;\n this.report(\"shutdown\", undefined, \"timeout\");\n this.shutdownController.abort();\n resolve();\n }, this.shutdownTimeout);\n }),\n ]);\n } catch (error) {\n this.counters.exportFailures++;\n this.report(\"shutdown\", error, \"shutdown\");\n } finally {\n clearTimeout(deadline);\n this.disposed = true;\n for (const finish of this.finishers) finish();\n this.counters.eventsDropped += this.counters.queueDepth;\n this.counters.queueDepth = 0;\n // Even when draining times out, initiate cleanup exactly once.\n void this.shutdownExporter();\n }\n })();\n return this.shutdownPromise;\n }\n\n private shutdownExporter(): Promise<void> {\n this.exporterShutdownPromise ??= Promise.resolve()\n .then(() => {\n const exporter = this.exporter as SpanExporter & {\n shutdown(signal?: AbortSignal): Promise<void>;\n };\n return exporter.shutdown(this.shutdownController.signal);\n })\n .catch((error: unknown) => {\n if (!this.disposed && !this.shutdownController.signal.aborted) {\n this.counters.exportFailures++;\n this.report(\"shutdown\", error, \"shutdown\");\n }\n });\n return this.exporterShutdownPromise;\n }\n\n getRetries(): number {\n try {\n const exporter = this.exporter as SpanExporter & {\n getDiagnostics?(): { eventsRetried: number };\n };\n return exporter.getDiagnostics?.().eventsRetried ?? 0;\n } catch {\n return 0;\n }\n }\n\n private report(\n operation: DiagnosticEvent[\"operation\"],\n error: unknown,\n fallback?: DiagnosticCategory,\n ): void {\n const event = diagnosticEvent(operation, classifyError(error, fallback));\n this.counters.lastError = event;\n try {\n void Promise.resolve(this.onDiagnostic?.(event)).catch(() => {});\n } catch {}\n if (this.debug) {\n try {\n console.warn(\n `[ai-observability] ${event.operation}: ${event.category}. ${event.message}`,\n );\n } catch {}\n }\n }\n}\n\nexport function createEngine(options: CoreOptions): Observability {\n const ratio = bounded(options.samplingRatio ?? 1, \"samplingRatio\", 0, 1);\n const maxQueue = bounded(\n options.maxQueueSize ?? 2048,\n \"maxQueueSize\",\n 1,\n 100000,\n );\n const batchSize = bounded(options.batchSize ?? 256, \"batchSize\", 1, maxQueue);\n const interval = bounded(\n options.flushIntervalMs ?? 5000,\n \"flushIntervalMs\",\n 1,\n 3600000,\n );\n const timeout = bounded(\n options.exportTimeoutMs ?? 30000,\n \"exportTimeoutMs\",\n 1,\n 3600000,\n );\n const maxConcurrentExports = bounded(\n options.maxConcurrentExports ?? 4,\n \"maxConcurrentExports\",\n 1,\n 1024,\n );\n const shutdownTimeout = bounded(\n options.shutdownTimeoutMs ?? 30000,\n \"shutdownTimeoutMs\",\n 1,\n 3600000,\n );\n const maxActiveSpans = bounded(\n options.maxActiveSpans ?? 4096,\n \"maxActiveSpans\",\n 1,\n 100000,\n );\n for (const [name, value] of Object.entries({\n maxQueue,\n batchSize,\n interval,\n timeout,\n maxConcurrentExports,\n shutdownTimeout,\n maxActiveSpans,\n })) {\n if (!Number.isInteger(value)) throw new Error(`${name} must be an integer`);\n }\n const processor = new ManagedBatchProcessor(\n options.exporter,\n maxQueue,\n batchSize,\n interval,\n timeout,\n maxConcurrentExports,\n shutdownTimeout,\n makeSanitizer(options),\n options.onDiagnostic,\n options.debug ?? false,\n );\n const provider = new TracerProvider({\n resource: resourceFromAttributes({\n ...options.resourceAttributes,\n \"service.name\": options.serviceName ?? \"ai-application\",\n ...(options.serviceVersion\n ? { \"service.version\": options.serviceVersion }\n : {}),\n ...(options.environment\n ? { \"deployment.environment.name\": options.environment }\n : {}),\n }),\n sampler: new ParentBasedSampler({\n root: new TraceIdRatioBasedSampler(ratio),\n }),\n spanProcessors: [processor],\n spanLimits: {\n attributeCountLimit: 64,\n attributeValueLengthLimit: 4096,\n eventCountLimit: 64,\n linkCountLimit: 32,\n attributePerEventCountLimit: 32,\n attributePerLinkCountLimit: 32,\n },\n });\n const tracer = provider.getTracer(\n \"@saguiitay/eventhouse-ai-observability\",\n \"0.1.2\",\n );\n const localContext = new AsyncLocalStorage<Context>();\n const active = new Set<Span>();\n let closed = false;\n let shutdownPromise: Promise<void> | undefined;\n const engine: Observability = {\n captureContent: options.captureContent ?? false,\n maxActiveSpans,\n startSpan(name, spanOptions = {}) {\n if (closed || active.size >= maxActiveSpans) {\n processor.counters.eventsDropped++;\n return trace.wrapSpanContext(INVALID_SPAN_CONTEXT);\n }\n const { parent, ...otelOptions } = spanOptions;\n const ambient = localContext.getStore() ?? context.active();\n const parentContext = parent\n ? \"spanContext\" in parent\n ? trace.setSpan(ambient, parent)\n : parent\n : ambient;\n const span = tracer.startSpan(name, otelOptions, parentContext);\n if (span.isRecording()) {\n active.add(span);\n const end = span.end.bind(span);\n span.end = (time) => {\n active.delete(span);\n end(time);\n };\n }\n return span;\n },\n withSpan(span, callback) {\n if (closed) return callback();\n const parent =\n localContext.getStore() ?? context.active() ?? ROOT_CONTEXT;\n const current = trace.setSpan(parent, span);\n return localContext.run(current, () => context.with(current, callback));\n },\n flush: () => processor.forceFlush(),\n shutdown() {\n shutdownPromise ??= (async () => {\n closed = true;\n for (const span of active) {\n span.setAttribute(\"observability.incomplete\", true);\n span.end();\n }\n try {\n await provider.shutdown();\n } finally {\n localContext.disable();\n }\n })();\n return shutdownPromise;\n },\n getDiagnostics() {\n return {\n ...processor.counters,\n eventsRetried: processor.getRetries(),\n activeSpans: active.size,\n };\n },\n };\n return engine;\n}\n","export type DiagnosticCategory =\n | \"authentication\"\n | \"network\"\n | \"timeout\"\n | \"throttling\"\n | \"oversized\"\n | \"capacity\"\n | \"shutdown\"\n | \"unknown\";\n\nexport interface DiagnosticEvent {\n readonly operation: \"export\" | \"flush\" | \"shutdown\";\n readonly category: DiagnosticCategory;\n readonly message: string;\n}\n\nconst messages: Record<DiagnosticCategory, string> = {\n authentication:\n \"Check transport credentials and permissions; Eventstream requires producer Send access.\",\n network: \"Check endpoint availability, DNS, and required network egress.\",\n timeout: \"The operation exceeded its deadline; delivery may be uncertain.\",\n throttling: \"The service is throttling; check capacity and reduce load.\",\n oversized:\n \"Reduce span content or attributes to fit the service message limit.\",\n capacity:\n \"The local export bound was reached; check load and exporter health.\",\n shutdown: \"Exporter cleanup did not complete successfully.\",\n unknown: \"Check transport configuration and endpoint health.\",\n};\n\nconst codes = new Map<string | number, DiagnosticCategory>([\n [401, \"authentication\"],\n [403, \"authentication\"],\n [429, \"throttling\"],\n [\"unauthorizedaccess\", \"authentication\"],\n [\"unauthorizederror\", \"authentication\"],\n [\"authenticationerror\", \"authentication\"],\n [\"authenticationfailed\", \"authentication\"],\n [\"amqp:unauthorized-access\", \"authentication\"],\n [\"enotfound\", \"network\"],\n [\"eai_again\", \"network\"],\n [\"econnrefused\", \"network\"],\n [\"econnreset\", \"network\"],\n [\"servicecommunicationerror\", \"network\"],\n [\"serviceunavailableerror\", \"network\"],\n [\"messagingcommunicationerror\", \"network\"],\n [\"connectionlosterror\", \"network\"],\n [\"etimedout\", \"timeout\"],\n [\"timeouterror\", \"timeout\"],\n [\"operationtimeouterror\", \"timeout\"],\n [\"aborterror\", \"timeout\"],\n [\"serverbusyerror\", \"throttling\"],\n [\"servicebusyerror\", \"throttling\"],\n [\"amqp:resource-limit-exceeded\", \"throttling\"],\n]);\nfor (const category of Object.keys(messages) as DiagnosticCategory[])\n codes.set(`eventhouse_${category}`, category);\n\nexport function classifyError(\n error: unknown,\n fallback: DiagnosticCategory = \"unknown\",\n): DiagnosticCategory {\n try {\n for (\n let depth = 0;\n depth < 3 && error && typeof error === \"object\";\n depth++\n ) {\n const current = error as {\n code?: unknown;\n name?: unknown;\n statusCode?: unknown;\n cause?: unknown;\n };\n for (const value of [current.code, current.name, current.statusCode]) {\n const key =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\" && value.length <= 128\n ? value.toLowerCase()\n : undefined;\n const category = key === undefined ? undefined : codes.get(key);\n if (category) return category;\n }\n error = current.cause;\n }\n } catch {\n // Error objects and their getters belong to third-party exporters.\n }\n return fallback;\n}\n\nexport function diagnosticEvent(\n operation: DiagnosticEvent[\"operation\"],\n category: DiagnosticCategory,\n): DiagnosticEvent {\n return Object.freeze({ operation, category, message: messages[category] });\n}\n\nexport function categorizedError(\n category: DiagnosticCategory,\n message: string,\n) {\n return Object.assign(new Error(message), { code: `EVENTHOUSE_${category}` });\n}\n","import { EventHubProducerClient } from \"@azure/event-hubs\";\nimport type { ReadableSpan, SpanExporter } from \"@opentelemetry/sdk-trace\";\nimport { serializeSpan } from \"./serialize.js\";\nimport { categorizedError, classifyError } from \"../diagnostics.js\";\n\nexport { serializeSpan } from \"./serialize.js\";\nexport type { SerializedSpan } from \"./serialize.js\";\n\nexport interface EventstreamExporterOptions {\n connectionString: string;\n entityName?: string;\n maxBatchSizeBytes?: number;\n /** Total deadline for one export, including SDK retries. Defaults to 30000. */\n exportTimeoutMs?: number;\n /** Overall drain/close deadline. Defaults to 30000. */\n shutdownTimeoutMs?: number;\n /** Maximum underlying operations, including aborted operations still pending. Defaults to 4. */\n maxConcurrentExports?: number;\n}\n\nfunction positiveInteger(value: number, name: string, max: number): number {\n if (!Number.isSafeInteger(value) || value < 1 || value > max)\n throw new Error(\n `Eventstream ${name} must be an integer between 1 and ${max}.`,\n );\n return value;\n}\n\nfunction invalidConfiguration(): never {\n throw new Error(\"Invalid Eventstream connection configuration.\");\n}\n\nfunction validateConnection(\n options: EventstreamExporterOptions,\n): string | undefined {\n if (\n typeof options.connectionString !== \"string\" ||\n !options.connectionString.trim()\n ) {\n invalidConfiguration();\n }\n const fields = new Map<string, string>();\n for (const part of options.connectionString.trim().split(\";\")) {\n if (!part.trim()) continue;\n const separator = part.indexOf(\"=\");\n if (separator <= 0) invalidConfiguration();\n const name = part.slice(0, separator).trim().toLowerCase();\n const value = part.slice(separator + 1).trim();\n if (fields.has(name) || !value || /[\\r\\n\\0]/u.test(value))\n invalidConfiguration();\n if (\n ![\n \"endpoint\",\n \"sharedaccesskeyname\",\n \"sharedaccesskey\",\n \"entitypath\",\n ].includes(name)\n ) {\n invalidConfiguration();\n }\n fields.set(name, value);\n }\n if (!fields.has(\"sharedaccesskeyname\") || !fields.has(\"sharedaccesskey\")) {\n invalidConfiguration();\n }\n try {\n const endpoint = new URL(fields.get(\"endpoint\") ?? \"\");\n if (\n endpoint.protocol !== \"sb:\" ||\n !endpoint.hostname ||\n endpoint.username ||\n endpoint.password ||\n endpoint.search ||\n endpoint.hash ||\n (endpoint.pathname !== \"/\" && endpoint.pathname !== \"\")\n )\n invalidConfiguration();\n } catch {\n invalidConfiguration();\n }\n const entityPath = fields.get(\"entitypath\");\n if (\n options.entityName !== undefined &&\n (typeof options.entityName !== \"string\" ||\n !options.entityName.trim() ||\n /[;\\r\\n\\0]/u.test(options.entityName))\n )\n invalidConfiguration();\n const entityName = options.entityName?.trim();\n if (!entityPath && !entityName) invalidConfiguration();\n if (entityPath && entityName && entityPath !== entityName)\n invalidConfiguration();\n if (\n options.maxBatchSizeBytes !== undefined &&\n (!Number.isSafeInteger(options.maxBatchSizeBytes) ||\n options.maxBatchSizeBytes <= 0)\n ) {\n throw new Error(\n \"Eventstream maxBatchSizeBytes must be a positive safe integer.\",\n );\n }\n return entityPath ? undefined : entityName;\n}\n\n/** Sends JSON events to Fabric's Custom endpoint SOURCE using AMQP over TLS. */\nexport class EventstreamExporter implements SpanExporter {\n private readonly producer: EventHubProducerClient;\n private readonly maxBatchSizeBytes: number | undefined;\n private readonly active = new Map<\n AbortController,\n { operation: Promise<void>; expire: () => void }\n >();\n private readonly exportTimeout: number;\n private readonly shutdownTimeout: number;\n private readonly maxConcurrentExports: number;\n private closing = false;\n private shutdownPromise: Promise<void> | undefined;\n private producerClosePromise: Promise<void> | undefined;\n\n constructor(options: EventstreamExporterOptions) {\n const entityName = validateConnection(options);\n this.maxBatchSizeBytes = options.maxBatchSizeBytes;\n this.exportTimeout = positiveInteger(\n options.exportTimeoutMs ?? 30000,\n \"exportTimeoutMs\",\n 3600000,\n );\n this.shutdownTimeout = positiveInteger(\n options.shutdownTimeoutMs ?? 30000,\n \"shutdownTimeoutMs\",\n 3600000,\n );\n this.maxConcurrentExports = positiveInteger(\n options.maxConcurrentExports ?? 4,\n \"maxConcurrentExports\",\n 1024,\n );\n try {\n this.producer = entityName\n ? new EventHubProducerClient(options.connectionString, entityName)\n : new EventHubProducerClient(options.connectionString);\n } catch {\n throw new Error(\"Unable to initialize Eventstream transport.\");\n }\n }\n\n export(\n spans: ReadableSpan[],\n callback: Parameters<SpanExporter[\"export\"]>[1],\n signal?: AbortSignal,\n ): void {\n if (this.closing) {\n queueMicrotask(() =>\n callback({\n code: 1,\n error: categorizedError(\n \"shutdown\",\n \"Eventstream exporter is shut down.\",\n ),\n }),\n );\n return;\n }\n if (spans.length === 0) {\n queueMicrotask(() => callback({ code: 0 }));\n return;\n }\n if (this.active.size >= this.maxConcurrentExports) {\n queueMicrotask(() =>\n callback({\n code: 1,\n error: categorizedError(\n \"capacity\",\n \"Eventstream export concurrency limit reached.\",\n ),\n }),\n );\n return;\n }\n const controller = new AbortController();\n const progress = { exportedSpans: 0 };\n let settled = false;\n const finish = (failed: boolean, error?: unknown) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n signal?.removeEventListener(\"abort\", expire);\n const droppedSpans = spans.length - progress.exportedSpans;\n // This optional result extension preserves ordinary SpanExporter consumers.\n const result = {\n code: failed || droppedSpans > 0 ? 1 : 0,\n exportedSpans: progress.exportedSpans,\n droppedSpans,\n ...(failed || droppedSpans > 0\n ? {\n error: categorizedError(\n classifyError(error, failed ? \"unknown\" : \"oversized\"),\n \"Eventstream export failed; events may have been partially delivered.\",\n ),\n }\n : {}),\n };\n callback(result);\n };\n const expire = () => {\n controller.abort();\n finish(\n true,\n categorizedError(\"timeout\", \"Eventstream export deadline expired.\"),\n );\n };\n const deadline = setTimeout(expire, this.exportTimeout);\n signal?.addEventListener(\"abort\", expire, { once: true });\n if (signal?.aborted) {\n expire();\n return;\n }\n const operation = this.send(spans, controller.signal, progress);\n this.active.set(controller, { operation, expire });\n const complete = (failed: boolean, error?: unknown) => {\n this.active.delete(controller);\n finish(failed, error);\n };\n // Keep the slot until I/O actually settles, even if an SDK ignores abort.\n void operation.then(\n () => complete(false),\n (error: unknown) => complete(true, error),\n );\n }\n\n private async send(\n spans: readonly ReadableSpan[],\n signal: AbortSignal,\n progress: { exportedSpans: number },\n ): Promise<void> {\n const options = {\n abortSignal: signal,\n ...(this.maxBatchSizeBytes === undefined\n ? {}\n : { maxSizeInBytes: this.maxBatchSizeBytes }),\n };\n let batch = await this.producer.createBatch(options);\n signal.throwIfAborted();\n const sendBatch = async () => {\n const count = batch.count;\n if (count === 0) return;\n signal.throwIfAborted();\n await this.producer.sendBatch(batch, { abortSignal: signal });\n progress.exportedSpans += count;\n signal.throwIfAborted();\n };\n for (const span of spans) {\n signal.throwIfAborted();\n const event = {\n body: serializeSpan(span),\n contentType: \"application/json\",\n };\n if (batch.tryAdd(event)) continue;\n // A fresh empty batch is authoritative for oversized messages.\n if (batch.count === 0) continue;\n await sendBatch();\n batch = await this.producer.createBatch(options);\n signal.throwIfAborted();\n if (!batch.tryAdd(event)) {\n continue;\n }\n }\n await sendBatch();\n }\n\n shutdown(signal?: AbortSignal): Promise<void> {\n if (!this.shutdownPromise) {\n this.closing = true;\n this.shutdownPromise = this.close(signal);\n }\n return this.shutdownPromise;\n }\n\n private async close(signal?: AbortSignal): Promise<void> {\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let expire: (() => void) | undefined;\n try {\n await Promise.race([\n (async () => {\n await Promise.allSettled(\n [...this.active.values()].map(({ operation }) => operation),\n );\n await this.closeProducer();\n })(),\n new Promise<never>((_resolve, reject) => {\n expire = () => {\n for (const { expire } of this.active.values()) expire();\n void this.closeProducer().catch(() => {});\n reject(categorizedError(\"timeout\", \"Eventstream shutdown failed.\"));\n };\n signal?.addEventListener(\"abort\", expire, { once: true });\n if (signal?.aborted) expire();\n else deadline = setTimeout(expire, this.shutdownTimeout);\n }),\n ]);\n } catch (error) {\n throw categorizedError(\n classifyError(error, \"shutdown\"),\n \"Eventstream shutdown failed.\",\n );\n } finally {\n clearTimeout(deadline);\n if (expire) signal?.removeEventListener(\"abort\", expire);\n this.active.clear();\n }\n }\n\n private closeProducer(): Promise<void> {\n this.producerClosePromise ??= Promise.resolve().then(() =>\n this.producer.close(),\n );\n return this.producerClosePromise;\n }\n}\n","import type { ReadableSpan } from \"@opentelemetry/sdk-trace\";\n\ntype HrTime = ReadableSpan[\"startTime\"];\n\nfunction isoTime(time: HrTime): string {\n return new Date(\n time[0] * 1_000 + Math.floor(time[1] / 1_000_000),\n ).toISOString();\n}\n\nfunction stringAttribute(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\n/** JSON-compatible, framework-neutral Eventstream schema. Times are UTC ISO 8601. */\nexport function serializeSpan(span: ReadableSpan) {\n const context = span.spanContext();\n const resourceAttributes = { ...span.resource.attributes };\n const startTime = isoTime(span.startTime);\n const endTime = isoTime(span.endTime);\n return {\n schemaVersion: \"1.0\" as const,\n timestamp: endTime,\n traceId: context.traceId,\n spanId: context.spanId,\n parentSpanId: span.parentSpanContext?.spanId ?? null,\n spanName: span.name,\n spanKind: span.kind,\n startTime,\n endTime,\n durationMs: span.duration[0] * 1_000 + span.duration[1] / 1_000_000,\n status: span.status.code,\n statusMessage: span.status.message ?? null,\n serviceName: stringAttribute(resourceAttributes[\"service.name\"]),\n serviceVersion: stringAttribute(resourceAttributes[\"service.version\"]),\n environment: stringAttribute(\n resourceAttributes[\"deployment.environment.name\"] ??\n resourceAttributes[\"deployment.environment\"],\n ),\n resourceAttributes,\n spanAttributes: { ...span.attributes },\n events: span.events.map((event) => ({\n name: event.name,\n timestamp: isoTime(event.time),\n attributes: { ...event.attributes },\n droppedAttributesCount: event.droppedAttributesCount ?? 0,\n })),\n links: span.links.map((link) => ({\n traceId: link.context.traceId,\n spanId: link.context.spanId,\n traceFlags: link.context.traceFlags,\n traceState: link.context.traceState?.serialize() ?? null,\n attributes: { ...link.attributes },\n droppedAttributesCount: link.droppedAttributesCount ?? 0,\n })),\n };\n}\n\nexport type SerializedSpan = ReturnType<typeof serializeSpan>;\n","import {\n createEngine,\n type CoreOptions,\n type Observability,\n} from \"./engine.js\";\nimport { EventstreamExporter } from \"./exporters/eventstream.js\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\n\nexport { createEngine, redactSecrets } from \"./engine.js\";\nexport type {\n CoreOptions,\n Diagnostics,\n DiagnosticCategory,\n DiagnosticEvent,\n Observability,\n Redactor,\n} from \"./engine.js\";\nexport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\nexport { EventstreamExporter, serializeSpan } from \"./exporters/eventstream.js\";\nexport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\n\nexport interface EventhouseObservabilityOptions extends Omit<\n CoreOptions,\n \"exporter\"\n> {\n connectionString?: string;\n entityName?: string;\n transport?: \"eventstream\" | \"otlp\";\n exporter?: SpanExporter;\n endpoint?: string;\n headers?: Record<string, string>;\n maxBatchSizeBytes?: number;\n}\n\nfunction envNumber(name: string): number | undefined {\n const raw = process.env[name];\n if (raw === undefined) return undefined;\n if (raw.trim() === \"\" || !Number.isFinite(Number(raw))) {\n throw new Error(`${name} must be a finite number`);\n }\n return Number(raw);\n}\n\nfunction envHeaders(): Record<string, string> | undefined {\n const raw =\n process.env.OTEL_EXPORTER_OTLP_TRACES_HEADERS ??\n process.env.OTEL_EXPORTER_OTLP_HEADERS;\n if (!raw) return undefined;\n const result: Record<string, string> = {};\n for (const entry of raw.split(\",\")) {\n const equals = entry.indexOf(\"=\");\n if (equals < 1)\n throw new Error(\"Invalid OTLP header environment configuration\");\n try {\n result[entry.slice(0, equals).trim()] = decodeURIComponent(\n entry.slice(equals + 1).trim(),\n );\n } catch {\n throw new Error(\"Invalid OTLP header environment configuration\");\n }\n }\n return result;\n}\n\nexport function createObservability(\n options: EventhouseObservabilityOptions = {},\n): Observability {\n const connectionString =\n options.connectionString ??\n process.env.FABRIC_EVENTSTREAM_CONNECTION_STRING;\n const selection =\n options.transport ?? (connectionString ? \"eventstream\" : \"otlp\");\n let exporter: SpanExporter;\n if (options.exporter) {\n exporter = options.exporter;\n } else if (selection === \"eventstream\") {\n if (!connectionString)\n throw new Error(\"Fabric Eventstream connectionString is required\");\n const entityName =\n options.entityName ?? process.env.FABRIC_EVENTSTREAM_ENTITY_NAME;\n exporter = new EventstreamExporter({\n connectionString,\n ...(entityName ? { entityName } : {}),\n ...(options.maxBatchSizeBytes\n ? { maxBatchSizeBytes: options.maxBatchSizeBytes }\n : {}),\n ...(options.exportTimeoutMs !== undefined\n ? { exportTimeoutMs: options.exportTimeoutMs }\n : {}),\n ...(options.shutdownTimeoutMs !== undefined\n ? { shutdownTimeoutMs: options.shutdownTimeoutMs }\n : {}),\n ...(options.maxConcurrentExports !== undefined\n ? { maxConcurrentExports: options.maxConcurrentExports }\n : {}),\n });\n } else if (selection === \"otlp\") {\n const base = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;\n const endpoint =\n options.endpoint ??\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ??\n (base ? `${base.replace(/\\/$/, \"\")}/v1/traces` : undefined);\n if (!endpoint)\n throw new Error(\n \"Supply a Fabric connection string or an explicit OTLP traces endpoint\",\n );\n const headers = options.headers ?? envHeaders();\n try {\n const url = new URL(endpoint);\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.username ||\n url.password\n )\n throw new Error();\n } catch {\n throw new Error(\"Invalid OTLP endpoint configuration.\");\n }\n for (const [name, value] of Object.entries(headers ?? {})) {\n if (\n !/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(name) ||\n /[\\r\\n\\0]/u.test(value)\n ) {\n throw new Error(\"Invalid OTLP headers configuration.\");\n }\n }\n exporter = new OTLPTraceExporter({\n url: endpoint,\n ...(headers ? { headers } : {}),\n });\n } else {\n throw new Error(\"Unsupported telemetry transport\");\n }\n const serviceName = options.serviceName ?? process.env.OTEL_SERVICE_NAME;\n const serviceVersion =\n options.serviceVersion ?? process.env.OTEL_SERVICE_VERSION;\n const environment = options.environment ?? process.env.DEPLOYMENT_ENVIRONMENT;\n const samplingRatio =\n options.samplingRatio ?? envNumber(\"EVENTHOUSE_SAMPLING_RATIO\");\n const batchSize = options.batchSize ?? envNumber(\"EVENTHOUSE_BATCH_SIZE\");\n const flushIntervalMs =\n options.flushIntervalMs ?? envNumber(\"EVENTHOUSE_FLUSH_INTERVAL_MS\");\n return createEngine({\n ...options,\n exporter,\n ...(serviceName ? { serviceName } : {}),\n ...(serviceVersion ? { serviceVersion } : {}),\n ...(environment ? { environment } : {}),\n ...(samplingRatio !== undefined ? { samplingRatio } : {}),\n ...(batchSize !== undefined ? { batchSize } : {}),\n ...(flushIntervalMs !== undefined ? { flushIntervalMs } : {}),\n });\n}\n"],"mappings":"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","names":["exporter","result","context","expire","OTLPTraceExporter"]}
package/dist/copilot.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createObservability
3
- } from "./chunk-XFSF25OP.js";
3
+ } from "./chunk-XQFUPGYU.js";
4
4
 
5
5
  // src/adapters/copilot.ts
6
6
  import {
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  createObservability,
6
6
  redactSecrets,
7
7
  serializeSpan
8
- } from "./chunk-XFSF25OP.js";
8
+ } from "./chunk-XQFUPGYU.js";
9
9
  export {
10
10
  EventstreamExporter,
11
11
  OTLPTraceExporter,
@@ -3,7 +3,7 @@
3
3
  ## Delivered
4
4
 
5
5
  A single TypeScript ESM npm package, `@saguiitay/eventhouse-ai-observability`
6
- (personal project; 0.1.0 published to GitHub Packages, 0.1.1 prepared in this
6
+ (personal project; 0.1.1 published to GitHub Packages, 0.1.2 prepared in this
7
7
  checkout), with root and `/copilot` exports and ordinary internal modules in `src`.
8
8
  The former private workspace packages, OTLP wrapper, custom batching queue, and
9
9
  declaration-rewriting build step have been removed. OpenTelemetry's
@@ -94,7 +94,7 @@ Pattern redaction is defense in depth, not a general PII/secret detector. Conten
94
94
 
95
95
  ## Required external validation
96
96
 
97
- Run CI on Node 22.15+ and 24 for each release. After publishing 0.1.1, reinstall
97
+ Run CI on Node 22.15+ and 24 for each release. After publishing 0.1.2, reinstall
98
98
  the basic example's pinned dependency and repeat live ingestion/dashboard checks.
99
99
  Run the opt-in parent-child validation and the remaining examples, and validate
100
100
  automated provisioning/updates and interactive KQL performance before claiming
@@ -5,14 +5,25 @@ Use Node.js 22.15+ (validated with 24.22.3), the root package dependencies, and
5
5
  authenticated Copilot CLI. Model calls consume your Copilot quota.
6
6
 
7
7
  The **basic** example consumes published
8
- `@saguiitay/eventhouse-ai-observability@0.1.1` from GitHub Packages once that release
9
- is published. Version 0.1.0 was successfully installed and used against a live
8
+ `@saguiitay/eventhouse-ai-observability@0.1.2` once that release is published.
9
+ Version 0.1.0 was successfully installed and used against a live
10
10
  Fabric deployment on 2026-11-12. The example has its own
11
11
  dependency manifest and disables the root TypeScript source aliases, so it
12
12
  cannot silently use the checkout's runtime. The tools and multi-agent examples
13
13
  continue to use the locally built package.
14
14
 
15
- Install the basic example's dependency once. GitHub Packages requires a classic
15
+ Install the basic example's dependency once. To use npmjs through the approved
16
+ Microsoft mirror, override the example's existing GitHub scope mapping:
17
+
18
+ ```powershell
19
+ Push-Location .\examples\copilot-basic
20
+ npm install --package-lock=false --@saguiitay:registry=https://packagefeedproxy.microsoft.io/npm/
21
+ Pop-Location
22
+ ```
23
+
24
+ Mirror availability can lag publication. Alternatively, after the pinned version
25
+ has also been published to GitHub Packages, use the existing scope mapping.
26
+ GitHub Packages requires a classic
16
27
  personal access token with `read:packages`, even for public
17
28
  packages. All other dependencies use the Microsoft proxy, not npmjs.org:
18
29
 
@@ -3,6 +3,6 @@
3
3
  "private": true,
4
4
  "type": "module",
5
5
  "dependencies": {
6
- "@saguiitay/eventhouse-ai-observability": "0.1.1"
6
+ "@saguiitay/eventhouse-ai-observability": "0.1.2"
7
7
  }
8
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saguiitay/eventhouse-ai-observability",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "OpenTelemetry AI agent observability for Microsoft Fabric Eventstream and Eventhouse",
5
5
  "repository": {
6
6
  "type": "git",