@tangle-network/sdk-telemetry 0.60.50-develop.20261013200919.56fef80 → 0.60.50-develop.20261013210018.8ab576e
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/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/stage-span.d.mts +3 -1
- package/dist/stage-span.d.mts.map +1 -1
- package/dist/stage-span.mjs +3 -1
- package/dist/stage-span.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as parseServerTiming, t as ServerTimingEntry } from "./server-timing-BA7iR17B.mjs";
|
|
2
|
-
import { LifecycleOp, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, RecordOptions, SpanComponent, SpanRecorder, SpanStatus, StageSpan, StageSpanInput, isAdoptablePtid, mintPtid, monotonicNs, readOrMintPtid, spanDurationMs } from "./stage-span.mjs";
|
|
2
|
+
import { LifecycleOp, ORCHESTRATOR_HOP_ID_HEADER, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, RecordOptions, SpanComponent, SpanRecorder, SpanStatus, StageSpan, StageSpanInput, isAdoptablePtid, mintPtid, monotonicNs, readOrMintPtid, spanDurationMs } from "./stage-span.mjs";
|
|
3
3
|
import { AgentEvent, ErrorEvent as AgentErrorEvent, FilePart, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, GenAiUsage, MessagePartUpdatedEvent, MessagePartUpdatedEvent as MessagePartUpdatedEvent$1, ParsedSSEEvent, Part, ReasoningPart, ResultEvent, SSEChunkParser, SSEEventData, SSEEventData as SSEEventData$1, SSEParserOptions, StatusEvent, Storage, StreamTokenUsage, StreamUsageAccumulator, StreamUsageExtractor, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, TextPart, TokenUsageCounts, ToolPart, ToolState, addTokenUsage, consumeSSEStream, createStreamUsageExtractor, createUsageCallback, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, isFilePart, isReasoningPart, isTextPart, isToolPart, parseSSEData as parseSSEData$1, parseSSEStream, readTokenCostUsd, readTokenUsage, tokenCount, tokenUsageSource } from "@tangle-network/agent-core";
|
|
4
4
|
|
|
5
5
|
//#region src/types.d.ts
|
|
@@ -966,5 +966,5 @@ declare function createUsageInterceptor(tracker: UsageTracker): {
|
|
|
966
966
|
};
|
|
967
967
|
declare function createUsageTracker(config: UsageTrackerConfig, provider?: UsageProvider, storage?: Storage): UsageTracker;
|
|
968
968
|
//#endregion
|
|
969
|
-
export { AdapterRegistry, type AgentErrorEvent, type AgentEvent, type AgentMetric, type ApiMetric, type BuildResultEvent, ConsoleTelemetrySink, type CreditBalance, type CreditProvider, CreditTracker, type CreditTrackerConfig, type CreditTransaction, type CustomEvent, type Diagnostic, type DiagnosticEvent, type DiagnosticSeverity, type DiagnosticSummary, type EnrichmentContext, type EnvironmentEvent, type EnvironmentType, type ErrorEvent, type ExecutionTrace, type FileChangeEvent, type FilePart, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, type GenAiUsage, HttpTelemetrySink, type InitOtelProviderResult, LangfuseSink, type LangfuseSinkConfig, type LifecycleOp, MemoryCreditProvider, type MessagePartUpdatedEvent, type MessagePartUpdatedEventWithTimestamp, type MessageUpdatedEvent, type MetadataBlob, type MetadataBlobAdapter, type MetadataBlobFormat, MultiTelemetrySink, type OtelSinkConfig, OtelTelemetrySink, type Outcome, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, type ParsedSSEEvent, type Part, type PerformanceMetric, type ProductType, type ReasoningPart, type RecordOptions, type ResultEvent, SSEChunkParser, type SSEEventData, type SSEParserOptions, type ServerTimingEntry, type Signal, type SignalEvent, type SpanComponent, SpanRecorder, type SpanStatus, type StageSpan, type StageSpanInput, type StatusEvent, type StreamTokenUsage, type StreamUsageAccumulator, StreamUsageExtractor, type SubscriptionTier, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, type TelemetryConfig, type TelemetryEvent, type TelemetryEventType, type TelemetrySink, TelemetryTracker, type TestResultEvent, TestTelemetrySink, type TextPart, type TokenUsageCounts, type ToolPart, type ToolState, TraceCollector, type TraceCollectorConfig, type TraceContext, type TraceEvent, type TraceEventType, type TraceScope, type UsageProvider, type UsageRecord, type UsageSummary, UsageTracker, type UsageTrackerConfig, addTokenUsage, consumeSSEStream, createConsoleSink, createCreditTracker, createEmptyContext, createHttpSink, createJsonAdapter, createLangfuseSinkFromEnv, createOtelSink, createOtelSinkFromEnv, createStreamUsageExtractor, createTelemetryTracker, createTestSink, createTraceCollector, createUsageCallback, createUsageInterceptor, createUsageTracker, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, getDefaultRegistry, initOtelProvider, initializeDefaultAdapters, isAdoptablePtid, isBuildResultEvent, isCompletionEvent, isCustomEvent, isDiagnosticEvent, isEnvironmentEvent, isErrorEvent, isFileChangeEvent, isFilePart, isMessagePartUpdatedEvent, isMessageUpdatedEvent, isReasoningPart, isTestResultEvent, isTextPart, isToolPart, jsonAdapter, mintPtid, monotonicNs, parseMetadataBlob, parseSSEData, parseSSEStream, parseServerTiming, readOrMintPtid, readTokenCostUsd, readTokenUsage, resetDefaultRegistry, shutdownOtelProvider, spanDurationMs, sseToSignal, sseToTraceEvent, tokenCount, tokenUsageSource };
|
|
969
|
+
export { AdapterRegistry, type AgentErrorEvent, type AgentEvent, type AgentMetric, type ApiMetric, type BuildResultEvent, ConsoleTelemetrySink, type CreditBalance, type CreditProvider, CreditTracker, type CreditTrackerConfig, type CreditTransaction, type CustomEvent, type Diagnostic, type DiagnosticEvent, type DiagnosticSeverity, type DiagnosticSummary, type EnrichmentContext, type EnvironmentEvent, type EnvironmentType, type ErrorEvent, type ExecutionTrace, type FileChangeEvent, type FilePart, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, type GenAiUsage, HttpTelemetrySink, type InitOtelProviderResult, LangfuseSink, type LangfuseSinkConfig, type LifecycleOp, MemoryCreditProvider, type MessagePartUpdatedEvent, type MessagePartUpdatedEventWithTimestamp, type MessageUpdatedEvent, type MetadataBlob, type MetadataBlobAdapter, type MetadataBlobFormat, MultiTelemetrySink, ORCHESTRATOR_HOP_ID_HEADER, type OtelSinkConfig, OtelTelemetrySink, type Outcome, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, type ParsedSSEEvent, type Part, type PerformanceMetric, type ProductType, type ReasoningPart, type RecordOptions, type ResultEvent, SSEChunkParser, type SSEEventData, type SSEParserOptions, type ServerTimingEntry, type Signal, type SignalEvent, type SpanComponent, SpanRecorder, type SpanStatus, type StageSpan, type StageSpanInput, type StatusEvent, type StreamTokenUsage, type StreamUsageAccumulator, StreamUsageExtractor, type SubscriptionTier, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, type TelemetryConfig, type TelemetryEvent, type TelemetryEventType, type TelemetrySink, TelemetryTracker, type TestResultEvent, TestTelemetrySink, type TextPart, type TokenUsageCounts, type ToolPart, type ToolState, TraceCollector, type TraceCollectorConfig, type TraceContext, type TraceEvent, type TraceEventType, type TraceScope, type UsageProvider, type UsageRecord, type UsageSummary, UsageTracker, type UsageTrackerConfig, addTokenUsage, consumeSSEStream, createConsoleSink, createCreditTracker, createEmptyContext, createHttpSink, createJsonAdapter, createLangfuseSinkFromEnv, createOtelSink, createOtelSinkFromEnv, createStreamUsageExtractor, createTelemetryTracker, createTestSink, createTraceCollector, createUsageCallback, createUsageInterceptor, createUsageTracker, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, getDefaultRegistry, initOtelProvider, initializeDefaultAdapters, isAdoptablePtid, isBuildResultEvent, isCompletionEvent, isCustomEvent, isDiagnosticEvent, isEnvironmentEvent, isErrorEvent, isFileChangeEvent, isFilePart, isMessagePartUpdatedEvent, isMessageUpdatedEvent, isReasoningPart, isTestResultEvent, isTextPart, isToolPart, jsonAdapter, mintPtid, monotonicNs, parseMetadataBlob, parseSSEData, parseSSEStream, parseServerTiming, readOrMintPtid, readTokenCostUsd, readTokenUsage, resetDefaultRegistry, shutdownOtelProvider, spanDurationMs, sseToSignal, sseToTraceEvent, tokenCount, tokenUsageSource };
|
|
970
970
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as parseServerTiming } from "./server-timing-CcTtoaLu.mjs";
|
|
2
|
-
import { PROVISION_TRACE_ID_HEADER, PTID_PREFIX, SpanRecorder, isAdoptablePtid, mintPtid, monotonicNs, readOrMintPtid, spanDurationMs } from "./stage-span.mjs";
|
|
2
|
+
import { ORCHESTRATOR_HOP_ID_HEADER, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, SpanRecorder, isAdoptablePtid, mintPtid, monotonicNs, readOrMintPtid, spanDurationMs } from "./stage-span.mjs";
|
|
3
3
|
import { GEN_AI_CONVERSATION_ID, GEN_AI_CONVERSATION_ID as GEN_AI_CONVERSATION_ID$1, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OPERATION_NAME as GEN_AI_OPERATION_NAME$1, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_REQUEST_MODEL as GEN_AI_REQUEST_MODEL$1, GEN_AI_RESPONSE_MODEL, GEN_AI_RESPONSE_MODEL as GEN_AI_RESPONSE_MODEL$1, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_INPUT_TOKENS as GEN_AI_USAGE_INPUT_TOKENS$1, GEN_AI_USAGE_OUTPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS as GEN_AI_USAGE_OUTPUT_TOKENS$1, SSEChunkParser, StreamUsageExtractor, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, addTokenUsage, consumeSSEStream, createStreamUsageExtractor, createUsageCallback, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, isFilePart, isReasoningPart, isTextPart, isToolPart, parseSSEData as parseSSEData$1, parseSSEStream, readTokenCostUsd, readTokenUsage, tokenCount, tokenUsageSource } from "@tangle-network/agent-core";
|
|
4
4
|
//#region src/credits.ts
|
|
5
5
|
const DEFAULT_CONFIG$2 = {
|
|
@@ -2178,6 +2178,6 @@ function createUsageTracker(config, provider, storage) {
|
|
|
2178
2178
|
return new UsageTracker(config, provider, storage);
|
|
2179
2179
|
}
|
|
2180
2180
|
//#endregion
|
|
2181
|
-
export { AdapterRegistry, ConsoleTelemetrySink, CreditTracker, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, HttpTelemetrySink, LangfuseSink, MemoryCreditProvider, MultiTelemetrySink, OtelTelemetrySink, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, SSEChunkParser, SpanRecorder, StreamUsageExtractor, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, TelemetryTracker, TestTelemetrySink, TraceCollector, UsageTracker, addTokenUsage, consumeSSEStream, createConsoleSink, createCreditTracker, createEmptyContext, createHttpSink, createJsonAdapter, createLangfuseSinkFromEnv, createOtelSink, createOtelSinkFromEnv, createStreamUsageExtractor, createTelemetryTracker, createTestSink, createTraceCollector, createUsageCallback, createUsageInterceptor, createUsageTracker, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, getDefaultRegistry, initOtelProvider, initializeDefaultAdapters, isAdoptablePtid, isBuildResultEvent, isCompletionEvent, isCustomEvent, isDiagnosticEvent, isEnvironmentEvent, isErrorEvent, isFileChangeEvent, isFilePart, isMessagePartUpdatedEvent, isMessageUpdatedEvent, isReasoningPart, isTestResultEvent, isTextPart, isToolPart, jsonAdapter, mintPtid, monotonicNs, parseMetadataBlob, parseSSEData, parseSSEStream, parseServerTiming, readOrMintPtid, readTokenCostUsd, readTokenUsage, resetDefaultRegistry, shutdownOtelProvider, spanDurationMs, sseToSignal, sseToTraceEvent, tokenCount, tokenUsageSource };
|
|
2181
|
+
export { AdapterRegistry, ConsoleTelemetrySink, CreditTracker, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, HttpTelemetrySink, LangfuseSink, MemoryCreditProvider, MultiTelemetrySink, ORCHESTRATOR_HOP_ID_HEADER, OtelTelemetrySink, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, SSEChunkParser, SpanRecorder, StreamUsageExtractor, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, TelemetryTracker, TestTelemetrySink, TraceCollector, UsageTracker, addTokenUsage, consumeSSEStream, createConsoleSink, createCreditTracker, createEmptyContext, createHttpSink, createJsonAdapter, createLangfuseSinkFromEnv, createOtelSink, createOtelSinkFromEnv, createStreamUsageExtractor, createTelemetryTracker, createTestSink, createTraceCollector, createUsageCallback, createUsageInterceptor, createUsageTracker, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, getDefaultRegistry, initOtelProvider, initializeDefaultAdapters, isAdoptablePtid, isBuildResultEvent, isCompletionEvent, isCustomEvent, isDiagnosticEvent, isEnvironmentEvent, isErrorEvent, isFileChangeEvent, isFilePart, isMessagePartUpdatedEvent, isMessageUpdatedEvent, isReasoningPart, isTestResultEvent, isTextPart, isToolPart, jsonAdapter, mintPtid, monotonicNs, parseMetadataBlob, parseSSEData, parseSSEStream, parseServerTiming, readOrMintPtid, readTokenCostUsd, readTokenUsage, resetDefaultRegistry, shutdownOtelProvider, spanDurationMs, sseToSignal, sseToTraceEvent, tokenCount, tokenUsageSource };
|
|
2182
2182
|
|
|
2183
2183
|
//# sourceMappingURL=index.mjs.map
|
package/dist/stage-span.d.mts
CHANGED
|
@@ -19,6 +19,8 @@ import { n as parseServerTiming, t as ServerTimingEntry } from "./server-timing-
|
|
|
19
19
|
*/
|
|
20
20
|
/** Request header that carries the one correlation id across every hop. */
|
|
21
21
|
declare const PROVISION_TRACE_ID_HEADER = "x-tangle-trace-id";
|
|
22
|
+
/** Response header for one Orchestrator HTTP hop within a logical trace. */
|
|
23
|
+
declare const ORCHESTRATOR_HOP_ID_HEADER = "x-orchestrator-hop-id";
|
|
22
24
|
/** Correlation id prefix minted at the edge (`ptid_<uuid>`). */
|
|
23
25
|
declare const PTID_PREFIX = "ptid_";
|
|
24
26
|
type LifecycleOp = "create" | "branch" | "resume" | "suspend" | "snapshot" | "restore" | "exec" | "delete" | "turn";
|
|
@@ -125,5 +127,5 @@ declare class SpanRecorder {
|
|
|
125
127
|
}): string;
|
|
126
128
|
}
|
|
127
129
|
//#endregion
|
|
128
|
-
export { LifecycleOp, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, RecordOptions, type ServerTimingEntry, SpanComponent, SpanRecorder, SpanStatus, StageSpan, StageSpanInput, isAdoptablePtid, mintPtid, monotonicNs, parseServerTiming, readOrMintPtid, spanDurationMs };
|
|
130
|
+
export { LifecycleOp, ORCHESTRATOR_HOP_ID_HEADER, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, RecordOptions, type ServerTimingEntry, SpanComponent, SpanRecorder, SpanStatus, StageSpan, StageSpanInput, isAdoptablePtid, mintPtid, monotonicNs, parseServerTiming, readOrMintPtid, spanDurationMs };
|
|
129
131
|
//# sourceMappingURL=stage-span.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage-span.d.mts","names":[],"sources":["../src/stage-span.ts"],"mappings":";;;;;;AAkBA;;;;;AAGA;;;;;
|
|
1
|
+
{"version":3,"file":"stage-span.d.mts","names":[],"sources":["../src/stage-span.ts"],"mappings":";;;;;;AAkBA;;;;;AAGA;;;;;AAGA;;;;cANa,yBAAA;AAQb;AAAA,cALa,0BAAA;;cAGA,WAAA;AAAA,KAED,WAAA;AAAA,KAWA,aAAA;AAAA,KAUA,UAAA;;;;AAAZ;;;;UASiB,SAAA;EACf,IAAA;EACA,EAAA,EAAI,WAAA;EACJ,KAAA;EACA,SAAA,EAAW,aAAA;EACX,OAAA;EACA,KAAA;EACA,MAAA,EAAQ,UAAA;EACR,WAAA;EACA,KAAA,GAAQ,MAAA;AAAA;;iBAIM,WAAA,CAAA;;iBAKA,cAAA,CACd,IAAA,EAAM,IAAA,CAAK,SAAA;AAAA,iBAaG,eAAA,CACd,KAAA,8BACC,KAAA;;iBAKa,QAAA,CAAA;;;;;;;iBAUA,cAAA,CAAe,WAAA;AApC/B;AAAA,KAyCY,cAAA,GAAiB,IAAA,CAAK,SAAA;;UAGjB,aAAA;EACf,MAAA,GAAS,UAAA;EACT,WAAA;EACA,KAAA,GAAQ,MAAA;AAAA;;;;;AA5BV;;;cA+Ca,YAAA;EAAA,SACF,IAAA;EAAA,SACA,EAAA,EAAI,WAAA;EAAA,iBACI,KAAA;cAEL,IAAA,UAAc,EAAA,EAAI,WAAA;EA7CR;EAmDtB,IAAA,CAAK,KAAA,EAAO,cAAA,GAAiB,SAAA;EAzCf;;;;EAmDR,KAAA,GAAA,CACJ,KAAA,UACA,SAAA,EAAW,aAAA,EACX,EAAA,QAAU,OAAA,CAAQ,CAAA,GAClB,IAAA,GAAO,aAAA,GACN,OAAA,CAAQ,CAAA;EAnDD;;;;;EA6EV,MAAA,CACE,KAAA,UACA,SAAA,EAAW,aAAA,EACX,UAAA,UACA,IAAA,GAAO,aAAA,GACN,SAAA;EA/EyB;EA+F5B,IAAA,CAAA,YAAiB,SAAA;EA5FH;EAiGd,QAAA,CAAA,GAAY,SAAA;EAnGH;;;;;;AAqBX;EAyFE,SAAA,CAAU,KAAA;IACR,KAAA;IACA,SAAA;IACA,QAAA;IACA,MAAA,EAAQ,KAAA;MAAQ,KAAA;MAAe,GAAA;IAAA;EAAA;EApExB;EAqFT,MAAA,CAAA;EApFG;;;;;;;;EAuGH,cAAA,CAAe,IAAA;IAAS,KAAA;IAAgB,WAAA;EAAA;AAAA"}
|
package/dist/stage-span.mjs
CHANGED
|
@@ -18,6 +18,8 @@ import { t as parseServerTiming } from "./server-timing-CcTtoaLu.mjs";
|
|
|
18
18
|
*/
|
|
19
19
|
/** Request header that carries the one correlation id across every hop. */
|
|
20
20
|
const PROVISION_TRACE_ID_HEADER = "x-tangle-trace-id";
|
|
21
|
+
/** Response header for one Orchestrator HTTP hop within a logical trace. */
|
|
22
|
+
const ORCHESTRATOR_HOP_ID_HEADER = "x-orchestrator-hop-id";
|
|
21
23
|
/** Correlation id prefix minted at the edge (`ptid_<uuid>`). */
|
|
22
24
|
const PTID_PREFIX = "ptid_";
|
|
23
25
|
/** Monotonic clock → nanoseconds. Portable across Node and Workers. */
|
|
@@ -186,6 +188,6 @@ var SpanRecorder = class {
|
|
|
186
188
|
}
|
|
187
189
|
};
|
|
188
190
|
//#endregion
|
|
189
|
-
export { PROVISION_TRACE_ID_HEADER, PTID_PREFIX, SpanRecorder, isAdoptablePtid, mintPtid, monotonicNs, parseServerTiming, readOrMintPtid, spanDurationMs };
|
|
191
|
+
export { ORCHESTRATOR_HOP_ID_HEADER, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, SpanRecorder, isAdoptablePtid, mintPtid, monotonicNs, parseServerTiming, readOrMintPtid, spanDurationMs };
|
|
190
192
|
|
|
191
193
|
//# sourceMappingURL=stage-span.mjs.map
|
package/dist/stage-span.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage-span.mjs","names":[],"sources":["../src/stage-span.ts"],"sourcesContent":["/**\n * One span shape for every lifecycle-op stage across every hop.\n *\n * The problem this solves: each service used to time its own stages with an\n * isolated `Date.now()` map (worker `stageMs`, orchestrator `startupDiagnostics`,\n * host `StartupBootstrapRecorder`, sidecar Prometheus) joined by disjoint ids,\n * so no single query reconstructs one operation end-to-end. `StageSpan` is the\n * shared record; `SpanRecorder` collects them under one correlation id (`ptid`)\n * and renders the same `Server-Timing` slice everywhere. Existing recorders\n * emit through this rather than hand-rolling a parallel timer.\n *\n * Runtime-portability: this module imports nothing Node-only (no `process`, no\n * `@repo/shared`, no otel) so it is safe to bundle into the Cloudflare Worker\n * via the `@tangle-network/sdk-telemetry/stage-span` subpath. The monotonic\n * clock is `performance.now()`, which is a global in both Node 18+ and Workers.\n */\n\n/** Request header that carries the one correlation id across every hop. */\nexport const PROVISION_TRACE_ID_HEADER = \"x-tangle-trace-id\";\n\n/** Correlation id prefix minted at the edge (`ptid_<uuid>`). */\nexport const PTID_PREFIX = \"ptid_\";\n\nexport type LifecycleOp =\n | \"create\"\n | \"branch\"\n | \"resume\"\n | \"suspend\"\n | \"snapshot\"\n | \"restore\"\n | \"exec\"\n | \"delete\"\n | \"turn\";\n\nexport type SpanComponent =\n | \"client\"\n | \"cf-worker\"\n | \"sandbox-api\"\n | \"orchestrator\"\n | \"host-agent\"\n | \"sidecar\"\n | \"storage\"\n | \"container\";\n\nexport type SpanStatus = \"completed\" | \"skipped\" | \"error\";\n\n/**\n * One timed stage of one lifecycle op, keyed by (ptid, op, stage, component).\n * `startNs`/`endNs` are monotonic-clock nanoseconds (see {@link monotonicNs});\n * only their difference is meaningful — they are NOT wall-clock timestamps.\n * `parentStage` builds a tree: a span with `parentStage` set is a child that\n * rolls up under its parent and does NOT count toward the top-level residual.\n */\nexport interface StageSpan {\n ptid: string;\n op: LifecycleOp;\n stage: string;\n component: SpanComponent;\n startNs: bigint;\n endNs: bigint;\n status: SpanStatus;\n parentStage?: string;\n attrs?: Record<string, string | number>;\n}\n\n/** Monotonic clock → nanoseconds. Portable across Node and Workers. */\nexport function monotonicNs(): bigint {\n return BigInt(Math.round(performance.now() * 1_000_000));\n}\n\n/** Duration of a span in fractional milliseconds. */\nexport function spanDurationMs(\n span: Pick<StageSpan, \"startNs\" | \"endNs\">,\n): number {\n return Number(span.endNs - span.startNs) / 1_000_000;\n}\n\n/**\n * A supplied trace id is adopted only when it matches the token charset a\n * `Server-Timing`/header value accepts unquoted, so a client-origin id can be\n * threaded but a malformed/oversized one can never poison downstream headers\n * or logs. Everything else is minted fresh.\n */\nconst PTID_ACCEPT = /^[\\w-]{8,200}$/;\n\nexport function isAdoptablePtid(\n value: string | null | undefined,\n): value is string {\n return typeof value === \"string\" && PTID_ACCEPT.test(value);\n}\n\n/** Mint a fresh edge-origin correlation id. */\nexport function mintPtid(): string {\n return `${PTID_PREFIX}${crypto.randomUUID()}`;\n}\n\n/**\n * Adopt an inbound `x-tangle-trace-id` when present and well-formed (so the\n * SDK can supply a true client-origin root), otherwise mint one. This is the\n * single decision every hop runs — the edge mints, every downstream hop adopts\n * the forwarded value, so the id is born once and identical everywhere.\n */\nexport function readOrMintPtid(headerValue: string | null | undefined): string {\n return isAdoptablePtid(headerValue) ? headerValue : mintPtid();\n}\n\n/** Input to {@link SpanRecorder.span} — ptid/op are fixed by the recorder. */\nexport type StageSpanInput = Omit<StageSpan, \"ptid\" | \"op\">;\n\n/** Options carried when recording a stage from a known duration. */\nexport interface RecordOptions {\n status?: SpanStatus;\n parentStage?: string;\n attrs?: Record<string, string | number>;\n}\n\nexport type { ServerTimingEntry } from \"./server-timing.js\";\nexport { parseServerTiming } from \"./server-timing.js\";\n\nconst TOKEN = /[^\\w-]/g;\n\nfunction sanitizeDesc(value: string): string {\n return value.replace(TOKEN, \"\");\n}\n\n/**\n * Collects {@link StageSpan}s for ONE op under ONE `ptid` and renders them to a\n * `Server-Timing` slice / a durable span array / a residual reconciliation.\n * There is exactly one recorder per op; existing per-service timers become thin\n * adapters that call {@link record} or {@link stage} instead of keeping their\n * own map.\n */\nexport class SpanRecorder {\n readonly ptid: string;\n readonly op: LifecycleOp;\n private readonly spans: StageSpan[] = [];\n\n constructor(ptid: string, op: LifecycleOp) {\n this.ptid = ptid;\n this.op = op;\n }\n\n /** Push a fully-formed span (start/end already measured). Returns it. */\n span(input: StageSpanInput): StageSpan {\n const span: StageSpan = { ptid: this.ptid, op: this.op, ...input };\n this.spans.push(span);\n return span;\n }\n\n /**\n * Time an async fn on the monotonic clock and record the span. A throw is\n * recorded as `status:\"error\"` and re-thrown — the timing is never lost.\n */\n async stage<T>(\n stage: string,\n component: SpanComponent,\n fn: () => Promise<T>,\n opts?: RecordOptions,\n ): Promise<T> {\n const startNs = monotonicNs();\n let status: SpanStatus = opts?.status ?? \"completed\";\n try {\n return await fn();\n } catch (err) {\n status = \"error\";\n throw err;\n } finally {\n this.span({\n stage,\n component,\n startNs,\n endNs: monotonicNs(),\n status,\n parentStage: opts?.parentStage,\n attrs: opts?.attrs,\n });\n }\n }\n\n /**\n * Adapter for a stage already timed elsewhere (an existing `Date.now()` map,\n * a fold-back duration from a downstream hop): synthesize a span of the given\n * millisecond duration ending now. Only the duration is load-bearing.\n */\n record(\n stage: string,\n component: SpanComponent,\n durationMs: number,\n opts?: RecordOptions,\n ): StageSpan {\n const endNs = monotonicNs();\n const startNs =\n endNs - BigInt(Math.round(Math.max(0, durationMs) * 1_000_000));\n return this.span({\n stage,\n component,\n startNs,\n endNs,\n status: opts?.status ?? \"completed\",\n parentStage: opts?.parentStage,\n attrs: opts?.attrs,\n });\n }\n\n /** All spans in record order (durable store payload — the full tree). */\n list(): readonly StageSpan[] {\n return this.spans;\n }\n\n /** Top-level spans (no `parentStage`) — the ones the residual accounts for. */\n topLevel(): StageSpan[] {\n return this.spans.filter((s) => s.parentStage === undefined);\n }\n\n /**\n * Residual accounting: `sum(topLevelLeaves) + residual === total`, computed on\n * the SAME rounded integers the header emits so the identity is exact. When\n * `total` is omitted it is the wall span (max end − min start) across all\n * spans. `residual` is the unaccounted gap — negative when stages overlap\n * (parallelized work), the honest signal the CI dark-gap gate reads.\n */\n reconcile(total?: number): {\n total: number;\n leavesSum: number;\n residual: number;\n leaves: Array<{ stage: string; dur: number }>;\n } {\n const leaves = this.topLevel().map((s) => ({\n stage: s.stage,\n dur: Math.round(spanDurationMs(s)),\n }));\n const leavesSum = leaves.reduce((acc, l) => acc + l.dur, 0);\n const totalRounded = Math.round(total ?? this.wallMs());\n return {\n total: totalRounded,\n leavesSum,\n residual: totalRounded - leavesSum,\n leaves,\n };\n }\n\n /** Wall duration across all recorded spans, in ms. */\n wallMs(): number {\n if (this.spans.length === 0) return 0;\n let min = this.spans[0].startNs;\n let max = this.spans[0].endNs;\n for (const s of this.spans) {\n if (s.startNs < min) min = s.startNs;\n if (s.endNs > max) max = s.endNs;\n }\n return Number(max - min) / 1_000_000;\n }\n\n /**\n * Render the `Server-Timing` slice for this op: one `stage;dur=` per\n * top-level span, then `<op>_unaccounted;dur=<residual>`, then\n * `total;dur=<total>`. By construction the non-total entries sum to `total`,\n * so a browser Network tab and the durable store agree. Skipped spans carry\n * `desc=\"skipped\"`; string attrs surface as `desc`. Nested children are\n * omitted from the header (they live in {@link list}) to keep the sum exact.\n */\n toServerTiming(opts?: { total?: number; includePtid?: boolean }): string {\n const { total, leaves, residual } = this.reconcile(opts?.total);\n const byStage = new Map(this.topLevel().map((s) => [s.stage, s]));\n const entries: string[] = [];\n if (opts?.includePtid) {\n entries.push(`ptid;desc=\"${sanitizeDesc(this.ptid)}\"`);\n }\n for (const leaf of leaves) {\n const span = byStage.get(leaf.stage);\n const desc =\n span?.status === \"skipped\"\n ? \"skipped\"\n : typeof span?.attrs?.desc === \"string\"\n ? sanitizeDesc(span.attrs.desc)\n : undefined;\n entries.push(\n desc\n ? `${leaf.stage};dur=${leaf.dur};desc=\"${desc}\"`\n : `${leaf.stage};dur=${leaf.dur}`,\n );\n }\n entries.push(`${this.op}_unaccounted;dur=${residual}`);\n entries.push(`total;dur=${total}`);\n return entries.join(\", \");\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stage-span.mjs","names":[],"sources":["../src/stage-span.ts"],"sourcesContent":["/**\n * One span shape for every lifecycle-op stage across every hop.\n *\n * The problem this solves: each service used to time its own stages with an\n * isolated `Date.now()` map (worker `stageMs`, orchestrator `startupDiagnostics`,\n * host `StartupBootstrapRecorder`, sidecar Prometheus) joined by disjoint ids,\n * so no single query reconstructs one operation end-to-end. `StageSpan` is the\n * shared record; `SpanRecorder` collects them under one correlation id (`ptid`)\n * and renders the same `Server-Timing` slice everywhere. Existing recorders\n * emit through this rather than hand-rolling a parallel timer.\n *\n * Runtime-portability: this module imports nothing Node-only (no `process`, no\n * `@repo/shared`, no otel) so it is safe to bundle into the Cloudflare Worker\n * via the `@tangle-network/sdk-telemetry/stage-span` subpath. The monotonic\n * clock is `performance.now()`, which is a global in both Node 18+ and Workers.\n */\n\n/** Request header that carries the one correlation id across every hop. */\nexport const PROVISION_TRACE_ID_HEADER = \"x-tangle-trace-id\";\n\n/** Response header for one Orchestrator HTTP hop within a logical trace. */\nexport const ORCHESTRATOR_HOP_ID_HEADER = \"x-orchestrator-hop-id\";\n\n/** Correlation id prefix minted at the edge (`ptid_<uuid>`). */\nexport const PTID_PREFIX = \"ptid_\";\n\nexport type LifecycleOp =\n | \"create\"\n | \"branch\"\n | \"resume\"\n | \"suspend\"\n | \"snapshot\"\n | \"restore\"\n | \"exec\"\n | \"delete\"\n | \"turn\";\n\nexport type SpanComponent =\n | \"client\"\n | \"cf-worker\"\n | \"sandbox-api\"\n | \"orchestrator\"\n | \"host-agent\"\n | \"sidecar\"\n | \"storage\"\n | \"container\";\n\nexport type SpanStatus = \"completed\" | \"skipped\" | \"error\";\n\n/**\n * One timed stage of one lifecycle op, keyed by (ptid, op, stage, component).\n * `startNs`/`endNs` are monotonic-clock nanoseconds (see {@link monotonicNs});\n * only their difference is meaningful — they are NOT wall-clock timestamps.\n * `parentStage` builds a tree: a span with `parentStage` set is a child that\n * rolls up under its parent and does NOT count toward the top-level residual.\n */\nexport interface StageSpan {\n ptid: string;\n op: LifecycleOp;\n stage: string;\n component: SpanComponent;\n startNs: bigint;\n endNs: bigint;\n status: SpanStatus;\n parentStage?: string;\n attrs?: Record<string, string | number>;\n}\n\n/** Monotonic clock → nanoseconds. Portable across Node and Workers. */\nexport function monotonicNs(): bigint {\n return BigInt(Math.round(performance.now() * 1_000_000));\n}\n\n/** Duration of a span in fractional milliseconds. */\nexport function spanDurationMs(\n span: Pick<StageSpan, \"startNs\" | \"endNs\">,\n): number {\n return Number(span.endNs - span.startNs) / 1_000_000;\n}\n\n/**\n * A supplied trace id is adopted only when it matches the token charset a\n * `Server-Timing`/header value accepts unquoted, so a client-origin id can be\n * threaded but a malformed/oversized one can never poison downstream headers\n * or logs. Everything else is minted fresh.\n */\nconst PTID_ACCEPT = /^[\\w-]{8,200}$/;\n\nexport function isAdoptablePtid(\n value: string | null | undefined,\n): value is string {\n return typeof value === \"string\" && PTID_ACCEPT.test(value);\n}\n\n/** Mint a fresh edge-origin correlation id. */\nexport function mintPtid(): string {\n return `${PTID_PREFIX}${crypto.randomUUID()}`;\n}\n\n/**\n * Adopt an inbound `x-tangle-trace-id` when present and well-formed (so the\n * SDK can supply a true client-origin root), otherwise mint one. This is the\n * single decision every hop runs — the edge mints, every downstream hop adopts\n * the forwarded value, so the id is born once and identical everywhere.\n */\nexport function readOrMintPtid(headerValue: string | null | undefined): string {\n return isAdoptablePtid(headerValue) ? headerValue : mintPtid();\n}\n\n/** Input to {@link SpanRecorder.span} — ptid/op are fixed by the recorder. */\nexport type StageSpanInput = Omit<StageSpan, \"ptid\" | \"op\">;\n\n/** Options carried when recording a stage from a known duration. */\nexport interface RecordOptions {\n status?: SpanStatus;\n parentStage?: string;\n attrs?: Record<string, string | number>;\n}\n\nexport type { ServerTimingEntry } from \"./server-timing.js\";\nexport { parseServerTiming } from \"./server-timing.js\";\n\nconst TOKEN = /[^\\w-]/g;\n\nfunction sanitizeDesc(value: string): string {\n return value.replace(TOKEN, \"\");\n}\n\n/**\n * Collects {@link StageSpan}s for ONE op under ONE `ptid` and renders them to a\n * `Server-Timing` slice / a durable span array / a residual reconciliation.\n * There is exactly one recorder per op; existing per-service timers become thin\n * adapters that call {@link record} or {@link stage} instead of keeping their\n * own map.\n */\nexport class SpanRecorder {\n readonly ptid: string;\n readonly op: LifecycleOp;\n private readonly spans: StageSpan[] = [];\n\n constructor(ptid: string, op: LifecycleOp) {\n this.ptid = ptid;\n this.op = op;\n }\n\n /** Push a fully-formed span (start/end already measured). Returns it. */\n span(input: StageSpanInput): StageSpan {\n const span: StageSpan = { ptid: this.ptid, op: this.op, ...input };\n this.spans.push(span);\n return span;\n }\n\n /**\n * Time an async fn on the monotonic clock and record the span. A throw is\n * recorded as `status:\"error\"` and re-thrown — the timing is never lost.\n */\n async stage<T>(\n stage: string,\n component: SpanComponent,\n fn: () => Promise<T>,\n opts?: RecordOptions,\n ): Promise<T> {\n const startNs = monotonicNs();\n let status: SpanStatus = opts?.status ?? \"completed\";\n try {\n return await fn();\n } catch (err) {\n status = \"error\";\n throw err;\n } finally {\n this.span({\n stage,\n component,\n startNs,\n endNs: monotonicNs(),\n status,\n parentStage: opts?.parentStage,\n attrs: opts?.attrs,\n });\n }\n }\n\n /**\n * Adapter for a stage already timed elsewhere (an existing `Date.now()` map,\n * a fold-back duration from a downstream hop): synthesize a span of the given\n * millisecond duration ending now. Only the duration is load-bearing.\n */\n record(\n stage: string,\n component: SpanComponent,\n durationMs: number,\n opts?: RecordOptions,\n ): StageSpan {\n const endNs = monotonicNs();\n const startNs =\n endNs - BigInt(Math.round(Math.max(0, durationMs) * 1_000_000));\n return this.span({\n stage,\n component,\n startNs,\n endNs,\n status: opts?.status ?? \"completed\",\n parentStage: opts?.parentStage,\n attrs: opts?.attrs,\n });\n }\n\n /** All spans in record order (durable store payload — the full tree). */\n list(): readonly StageSpan[] {\n return this.spans;\n }\n\n /** Top-level spans (no `parentStage`) — the ones the residual accounts for. */\n topLevel(): StageSpan[] {\n return this.spans.filter((s) => s.parentStage === undefined);\n }\n\n /**\n * Residual accounting: `sum(topLevelLeaves) + residual === total`, computed on\n * the SAME rounded integers the header emits so the identity is exact. When\n * `total` is omitted it is the wall span (max end − min start) across all\n * spans. `residual` is the unaccounted gap — negative when stages overlap\n * (parallelized work), the honest signal the CI dark-gap gate reads.\n */\n reconcile(total?: number): {\n total: number;\n leavesSum: number;\n residual: number;\n leaves: Array<{ stage: string; dur: number }>;\n } {\n const leaves = this.topLevel().map((s) => ({\n stage: s.stage,\n dur: Math.round(spanDurationMs(s)),\n }));\n const leavesSum = leaves.reduce((acc, l) => acc + l.dur, 0);\n const totalRounded = Math.round(total ?? this.wallMs());\n return {\n total: totalRounded,\n leavesSum,\n residual: totalRounded - leavesSum,\n leaves,\n };\n }\n\n /** Wall duration across all recorded spans, in ms. */\n wallMs(): number {\n if (this.spans.length === 0) return 0;\n let min = this.spans[0].startNs;\n let max = this.spans[0].endNs;\n for (const s of this.spans) {\n if (s.startNs < min) min = s.startNs;\n if (s.endNs > max) max = s.endNs;\n }\n return Number(max - min) / 1_000_000;\n }\n\n /**\n * Render the `Server-Timing` slice for this op: one `stage;dur=` per\n * top-level span, then `<op>_unaccounted;dur=<residual>`, then\n * `total;dur=<total>`. By construction the non-total entries sum to `total`,\n * so a browser Network tab and the durable store agree. Skipped spans carry\n * `desc=\"skipped\"`; string attrs surface as `desc`. Nested children are\n * omitted from the header (they live in {@link list}) to keep the sum exact.\n */\n toServerTiming(opts?: { total?: number; includePtid?: boolean }): string {\n const { total, leaves, residual } = this.reconcile(opts?.total);\n const byStage = new Map(this.topLevel().map((s) => [s.stage, s]));\n const entries: string[] = [];\n if (opts?.includePtid) {\n entries.push(`ptid;desc=\"${sanitizeDesc(this.ptid)}\"`);\n }\n for (const leaf of leaves) {\n const span = byStage.get(leaf.stage);\n const desc =\n span?.status === \"skipped\"\n ? \"skipped\"\n : typeof span?.attrs?.desc === \"string\"\n ? sanitizeDesc(span.attrs.desc)\n : undefined;\n entries.push(\n desc\n ? `${leaf.stage};dur=${leaf.dur};desc=\"${desc}\"`\n : `${leaf.stage};dur=${leaf.dur}`,\n );\n }\n entries.push(`${this.op}_unaccounted;dur=${residual}`);\n entries.push(`total;dur=${total}`);\n return entries.join(\", \");\n }\n}\n"],"mappings":"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"}
|