@tangle-network/sdk-telemetry 0.2.16 → 0.2.18

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 CHANGED
@@ -1,4 +1,4 @@
1
- import { n as parseServerTiming, t as ServerTimingEntry } from "./server-timing-C9RFa_A_.mjs";
1
+ import { f as parseServerTiming, l as ServerTimingEntry } from "./server-timing-Cj-NB41a.mjs";
2
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
 
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as parseServerTiming } from "./server-timing-DakHMNHj.mjs";
1
+ import { c as parseServerTiming } from "./server-timing-BsEa33zu.mjs";
2
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
@@ -0,0 +1,280 @@
1
+ //#region src/create-wall.ts
2
+ /** Exclusive create-request wall phases; nested service spans are a separate view. */
3
+ const CREATE_WALL_PHASES = [
4
+ "middleware",
5
+ "identity",
6
+ "preflight",
7
+ "tenantCoordination",
8
+ "configuration",
9
+ "leaseSelection",
10
+ "credentialJournal",
11
+ "quotaReservation",
12
+ "orchestrator",
13
+ "provisionResponse",
14
+ "responseBody",
15
+ "credentialAllocation",
16
+ "postCreate",
17
+ "response"
18
+ ];
19
+ const REQUIRED_PHASES = CREATE_WALL_PHASES.filter((phase) => phase !== "middleware" && phase !== "leaseSelection" && phase !== "tenantCoordination");
20
+ /** The original other-Worker + post-create budget, including auth/middleware. */
21
+ function createBookkeepingPostWall(phases) {
22
+ return CREATE_WALL_PHASES.reduce((sum, phase) => sum + (phase === "preflight" || phase === "orchestrator" ? 0 : phases[phase]), 0);
23
+ }
24
+ /**
25
+ * One cursor owned by the sequential request path. Parallel operations keep
26
+ * their own spans and never transition this cursor from their callbacks.
27
+ * Invalid clocks or missing caller hooks withhold a complete measurement.
28
+ */
29
+ function createWallTiming(startedAt) {
30
+ const phases = Object.fromEntries(CREATE_WALL_PHASES.map((phase) => [phase, 0]));
31
+ const visited = new Set(["identity"]);
32
+ let current = "identity";
33
+ let cursor = startedAt;
34
+ let valid = Number.isFinite(startedAt);
35
+ let finished = false;
36
+ return {
37
+ phase(name, at) {
38
+ if (finished || !Number.isFinite(at) || at < cursor) {
39
+ valid = false;
40
+ return;
41
+ }
42
+ phases[current] += at - cursor;
43
+ cursor = at;
44
+ current = name;
45
+ visited.add(name);
46
+ },
47
+ finish(receivedAt, respondedAt) {
48
+ if (finished || !valid || !Number.isFinite(receivedAt) || !Number.isFinite(respondedAt) || receivedAt > startedAt || respondedAt < cursor || REQUIRED_PHASES.some((phase) => !visited.has(phase))) {
49
+ finished = true;
50
+ return null;
51
+ }
52
+ finished = true;
53
+ phases[current] += respondedAt - cursor;
54
+ phases.middleware = startedAt - receivedAt;
55
+ const totalMs = respondedAt - receivedAt;
56
+ if (Object.values(phases).reduce((sum, ms) => sum + ms, 0) !== totalMs) return null;
57
+ return {
58
+ phases: { ...phases },
59
+ totalMs,
60
+ bookkeepingPostCreateMs: createBookkeepingPostWall(phases)
61
+ };
62
+ }
63
+ };
64
+ }
65
+ /** Read the already-parsed header. Historical/incomplete/overlapping rows stay unknown. */
66
+ function readCreateWallTiming(stages) {
67
+ const totalMs = stages["createWall.total"];
68
+ if (!Number.isFinite(totalMs) || totalMs < 0 || totalMs !== stages.outerWall) return null;
69
+ const phases = {};
70
+ for (const phase of CREATE_WALL_PHASES) {
71
+ const value = stages[`createWall.${phase}`];
72
+ if (!Number.isFinite(value) || value < 0) return null;
73
+ phases[phase] = value;
74
+ }
75
+ if (Object.values(phases).reduce((sum, ms) => sum + ms, 0) !== totalMs) return null;
76
+ return {
77
+ phases,
78
+ totalMs,
79
+ bookkeepingPostCreateMs: createBookkeepingPostWall(phases)
80
+ };
81
+ }
82
+ //#endregion
83
+ //#region src/server-timing-parser.mjs
84
+ function splitHeader(value, separator) {
85
+ const parts = [];
86
+ let start = 0;
87
+ let quoted = false;
88
+ for (let i = 0; i < value.length; i++) if (quoted && value[i] === "\\") i++;
89
+ else if (value[i] === "\"") quoted = !quoted;
90
+ else if (!quoted && value[i] === separator) {
91
+ parts.push(value.slice(start, i));
92
+ start = i + 1;
93
+ }
94
+ parts.push(value.slice(start));
95
+ return parts;
96
+ }
97
+ /** Missing or malformed durations remain unmeasured, never zero. */
98
+ function parseServerTiming(header) {
99
+ if (!header) return [];
100
+ const entries = [];
101
+ for (const metric of splitHeader(header, ",")) {
102
+ const [rawName, ...params] = splitHeader(metric, ";");
103
+ const name = rawName.trim();
104
+ if (!/^[!#$%&'*+.^_`|~\w-]+$/.test(name)) continue;
105
+ const entry = { name };
106
+ const seen = /* @__PURE__ */ new Set();
107
+ for (const param of params) {
108
+ const eq = param.indexOf("=");
109
+ const key = (eq < 0 ? param : param.slice(0, eq)).trim().toLowerCase();
110
+ if (seen.has(key)) continue;
111
+ seen.add(key);
112
+ if (eq < 0) continue;
113
+ let value = param.slice(eq + 1).trim();
114
+ if (value.startsWith("\"")) {
115
+ if (!/^"(?:[^"\\]|\\[\s\S])*"$/.test(value)) continue;
116
+ value = value.slice(1, -1).replace(/\\([\s\S])/g, "$1");
117
+ }
118
+ if (key === "desc") entry.desc = value;
119
+ else if (key === "dur" && /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(value)) {
120
+ const duration = Number(value);
121
+ if (Number.isFinite(duration)) entry.dur = duration;
122
+ }
123
+ }
124
+ entries.push(entry);
125
+ }
126
+ return entries;
127
+ }
128
+ /** A stage ledger retains only duration-bearing entries; later metrics win. */
129
+ function parseServerTimingDurations(header) {
130
+ return Object.fromEntries(parseServerTiming(header).filter((entry) => entry.dur !== void 0).map(({ name, dur }) => [name, dur]));
131
+ }
132
+ /** Closed wire observations; these names carry no credential or authority values. */
133
+ const PLATFORM_VERDICT_REUSE_REASONS = Object.freeze([
134
+ "entry_changed",
135
+ "refusal_observed",
136
+ "current_compliance",
137
+ "negative_age",
138
+ "retention_elapsed",
139
+ "key_expired",
140
+ "feed_missing",
141
+ "feed_stale",
142
+ "feed_generation",
143
+ "dependencies_empty",
144
+ "dependency_revision",
145
+ "dependency_floor",
146
+ "grant_missing",
147
+ "grant_unreadable",
148
+ "grant_shape",
149
+ "grant_negative_age",
150
+ "grant_retention_elapsed",
151
+ "shared_refusal_observed",
152
+ "shared_refusal_unreadable",
153
+ "shared_read_unavailable",
154
+ "grant_invalid",
155
+ "grant_validation",
156
+ "verification_inflight",
157
+ "feed_contradiction",
158
+ "current_required",
159
+ "lkg_retention_elapsed"
160
+ ]);
161
+ /** Closed request-phase wire vocabulary, shared by producer and safe consumers. */
162
+ const HTTP_REQUEST_PHASE_NAMES = Object.freeze([
163
+ "external.provision",
164
+ "benchmarks.records.load",
165
+ "benchmarks.records.build",
166
+ "benchmarks.records.page",
167
+ "benchmarks.records.json",
168
+ "admission.host.list",
169
+ "admission.metadata",
170
+ "admission.json",
171
+ "observability.refresh.wait",
172
+ "fleet.sidecars",
173
+ "native-export.snapshot.wait",
174
+ "native-export.prepare.wait",
175
+ "native-export.collect.wait",
176
+ "scorecard.fleet.wait",
177
+ "scorecard.capacity.wait",
178
+ "scorecard.coverage.wait",
179
+ "scorecard.compose",
180
+ "scorecard.json",
181
+ "proxy.model_refresh",
182
+ "proxy.hub.lock_wait",
183
+ "proxy.hub.refresh",
184
+ "proxy.hub.state",
185
+ "proxy.hub.proof",
186
+ "proxy.hub.delivery",
187
+ "proxy.runtime_token",
188
+ "snapshot.delete.lock",
189
+ "snapshot.delete.credentials",
190
+ "snapshot.delete.list",
191
+ "snapshot.delete.generation"
192
+ ]);
193
+ function httpRequestPhaseFromTimingName(name) {
194
+ const prefix = name.startsWith("orch.phase.") ? "orch.phase." : "phase.";
195
+ if (!name.startsWith(prefix)) return void 0;
196
+ const phase = name.slice(prefix.length);
197
+ return HTTP_REQUEST_PHASE_NAMES.includes(phase) ? phase : void 0;
198
+ }
199
+ const PLATFORM_VERDICT_SCOPE_CLASSES = Object.freeze([
200
+ "key",
201
+ "identity",
202
+ "owner_user",
203
+ "owner_team",
204
+ "lineage",
205
+ "other"
206
+ ]);
207
+ const PLATFORM_VERDICT_EVIDENCE_ORDERS = Object.freeze([
208
+ "feed_before_observation",
209
+ "feed_at_observation",
210
+ "feed_after_observation",
211
+ "unknown"
212
+ ]);
213
+ /** Bounded, closed-schema origin phase projection for the two Worker ledgers.
214
+ * Duplicate observations remain separate; different origins/attempts cannot be summed.
215
+ */
216
+ const HTTP_PHASE_COVERAGE_FIELDS = Object.freeze([
217
+ "stored",
218
+ "emitted",
219
+ "omitted",
220
+ "invalid",
221
+ "collisions",
222
+ "headerDropped"
223
+ ]);
224
+ function createUpstreamHttpPhaseProjection() {
225
+ const entries = [];
226
+ let bytes = 0;
227
+ let dropped = 0;
228
+ let rejectedInputs = 0;
229
+ const fields = HTTP_PHASE_COVERAGE_FIELDS;
230
+ const byteLength = (value) => new TextEncoder().encode(value).length;
231
+ const keep = (entry) => {
232
+ const size = byteLength(entry) + 2;
233
+ if (entries.length >= 31 || bytes + size > 3900) {
234
+ dropped++;
235
+ return;
236
+ }
237
+ entries.push(entry);
238
+ bytes += size;
239
+ };
240
+ return {
241
+ absorb(header) {
242
+ if (header == null) return;
243
+ if (typeof header !== "string" || header.length > 4096 || byteLength(header) > 4096) {
244
+ rejectedInputs++;
245
+ return;
246
+ }
247
+ for (const entry of parseServerTiming(header)) if (entry.name === "phase.coverage") {
248
+ const counts = {};
249
+ const parts = (entry.desc ?? "").split(",");
250
+ if (parts.length !== fields.length) {
251
+ dropped++;
252
+ continue;
253
+ }
254
+ for (const part of parts) {
255
+ const [key, value, ...extra] = part.split("=");
256
+ if (extra.length || !fields.includes(key) || Object.hasOwn(counts, key) || !/^(?:0|[1-9]\d*)$/.test(value ?? "") || !Number.isSafeInteger(Number(value))) break;
257
+ counts[key] = Number(value);
258
+ }
259
+ if (Object.keys(counts).length !== fields.length) {
260
+ dropped++;
261
+ continue;
262
+ }
263
+ keep(`orch.phase.coverage;desc="${fields.map((key) => `${key}=${counts[key]}`).join(",")}"`);
264
+ } else if (entry.name.startsWith("phase.")) {
265
+ if (!httpRequestPhaseFromTimingName(entry.name) || !Number.isFinite(entry.dur) || entry.dur < 0 || !/^outcome=(?:completed|error)$/.test(entry.desc ?? "")) {
266
+ dropped++;
267
+ continue;
268
+ }
269
+ keep(`orch.${entry.name};dur=${Math.round(entry.dur)};desc="${entry.desc}"`);
270
+ }
271
+ },
272
+ entries() {
273
+ return [...entries, ...dropped || rejectedInputs ? [`orch.phase.forwarding;desc="dropped=${dropped},rejectedInputs=${rejectedInputs}"`] : []];
274
+ }
275
+ };
276
+ }
277
+ //#endregion
278
+ export { PLATFORM_VERDICT_SCOPE_CLASSES as a, parseServerTiming as c, createBookkeepingPostWall as d, createWallTiming as f, PLATFORM_VERDICT_REUSE_REASONS as i, parseServerTimingDurations as l, HTTP_REQUEST_PHASE_NAMES as n, createUpstreamHttpPhaseProjection as o, readCreateWallTiming as p, PLATFORM_VERDICT_EVIDENCE_ORDERS as r, httpRequestPhaseFromTimingName as s, HTTP_PHASE_COVERAGE_FIELDS as t, CREATE_WALL_PHASES as u };
279
+
280
+ //# sourceMappingURL=server-timing-BsEa33zu.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-timing-BsEa33zu.mjs","names":[],"sources":["../src/create-wall.ts","../src/server-timing-parser.mjs"],"sourcesContent":["/** Exclusive create-request wall phases; nested service spans are a separate view. */\nexport const CREATE_WALL_PHASES = [\n \"middleware\",\n \"identity\",\n \"preflight\",\n \"tenantCoordination\",\n \"configuration\",\n \"leaseSelection\",\n \"credentialJournal\",\n \"quotaReservation\",\n \"orchestrator\",\n \"provisionResponse\",\n \"responseBody\",\n \"credentialAllocation\",\n \"postCreate\",\n \"response\",\n] as const;\n\nexport type CreateWallPhase = (typeof CREATE_WALL_PHASES)[number];\nexport type CreateWallPhases = Record<CreateWallPhase, number>;\nexport interface CreateWallMeasurement {\n phases: CreateWallPhases;\n totalMs: number;\n /** Includes middleware/auth, preserving the original bookkeeping + post budget. */\n bookkeepingPostCreateMs: number;\n}\n\nconst REQUIRED_PHASES = CREATE_WALL_PHASES.filter(\n (phase) =>\n phase !== \"middleware\" &&\n phase !== \"leaseSelection\" &&\n phase !== \"tenantCoordination\",\n);\n\n/** The original other-Worker + post-create budget, including auth/middleware. */\nexport function createBookkeepingPostWall(phases: CreateWallPhases): number {\n return CREATE_WALL_PHASES.reduce(\n (sum, phase) =>\n sum +\n (phase === \"preflight\" || phase === \"orchestrator\" ? 0 : phases[phase]),\n 0,\n );\n}\n\n/**\n * One cursor owned by the sequential request path. Parallel operations keep\n * their own spans and never transition this cursor from their callbacks.\n * Invalid clocks or missing caller hooks withhold a complete measurement.\n */\nexport function createWallTiming(startedAt: number) {\n const phases = Object.fromEntries(\n CREATE_WALL_PHASES.map((phase) => [phase, 0]),\n ) as CreateWallPhases;\n const visited = new Set<CreateWallPhase>([\"identity\"]);\n let current: CreateWallPhase = \"identity\";\n let cursor = startedAt;\n let valid = Number.isFinite(startedAt);\n let finished = false;\n return {\n phase(name: CreateWallPhase, at: number): void {\n if (finished || !Number.isFinite(at) || at < cursor) {\n valid = false;\n return;\n }\n phases[current] += at - cursor;\n cursor = at;\n current = name;\n visited.add(name);\n },\n finish(\n receivedAt: number,\n respondedAt: number,\n ): CreateWallMeasurement | null {\n if (\n finished ||\n !valid ||\n !Number.isFinite(receivedAt) ||\n !Number.isFinite(respondedAt) ||\n receivedAt > startedAt ||\n respondedAt < cursor ||\n REQUIRED_PHASES.some((phase) => !visited.has(phase))\n ) {\n finished = true;\n return null;\n }\n finished = true;\n phases[current] += respondedAt - cursor;\n phases.middleware = startedAt - receivedAt;\n const totalMs = respondedAt - receivedAt;\n if (Object.values(phases).reduce((sum, ms) => sum + ms, 0) !== totalMs)\n return null;\n return {\n phases: { ...phases },\n totalMs,\n bookkeepingPostCreateMs: createBookkeepingPostWall(phases),\n };\n },\n };\n}\n\n/** Read the already-parsed header. Historical/incomplete/overlapping rows stay unknown. */\nexport function readCreateWallTiming(\n stages: Readonly<Record<string, number>>,\n): CreateWallMeasurement | null {\n const totalMs = stages[\"createWall.total\"];\n if (!Number.isFinite(totalMs) || totalMs < 0 || totalMs !== stages.outerWall)\n return null;\n const phases = {} as CreateWallPhases;\n for (const phase of CREATE_WALL_PHASES) {\n const value = stages[`createWall.${phase}`];\n if (!Number.isFinite(value) || value < 0) return null;\n phases[phase] = value;\n }\n if (Object.values(phases).reduce((sum, ms) => sum + ms, 0) !== totalMs)\n return null;\n return {\n phases,\n totalMs,\n bookkeepingPostCreateMs: createBookkeepingPostWall(phases),\n };\n}\n","// HTTP quoted strings can contain both separators and escaped quotes.\nfunction splitHeader(value, separator) {\n const parts = [];\n let start = 0;\n let quoted = false;\n for (let i = 0; i < value.length; i++) {\n if (quoted && value[i] === \"\\\\\") i++;\n else if (value[i] === '\"') quoted = !quoted;\n else if (!quoted && value[i] === separator) {\n parts.push(value.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(value.slice(start));\n return parts;\n}\n\n/** Missing or malformed durations remain unmeasured, never zero. */\nexport function parseServerTiming(header) {\n if (!header) return [];\n const entries = [];\n for (const metric of splitHeader(header, \",\")) {\n const [rawName, ...params] = splitHeader(metric, \";\");\n const name = rawName.trim();\n if (!/^[!#$%&'*+.^_`|~\\w-]+$/.test(name)) continue;\n const entry = { name };\n const seen = new Set();\n for (const param of params) {\n const eq = param.indexOf(\"=\");\n const key = (eq < 0 ? param : param.slice(0, eq)).trim().toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n if (eq < 0) continue;\n let value = param.slice(eq + 1).trim();\n if (value.startsWith('\"')) {\n if (!/^\"(?:[^\"\\\\]|\\\\[\\s\\S])*\"$/.test(value)) continue;\n value = value.slice(1, -1).replace(/\\\\([\\s\\S])/g, \"$1\");\n }\n if (key === \"desc\") entry.desc = value;\n else if (\n key === \"dur\" &&\n /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(value)\n ) {\n const duration = Number(value);\n if (Number.isFinite(duration)) entry.dur = duration;\n }\n }\n entries.push(entry);\n }\n return entries;\n}\n\n/** A stage ledger retains only duration-bearing entries; later metrics win. */\nexport function parseServerTimingDurations(header) {\n return Object.fromEntries(\n parseServerTiming(header)\n .filter((entry) => entry.dur !== undefined)\n .map(({ name, dur }) => [name, dur]),\n );\n}\n\n/** Closed wire observations; these names carry no credential or authority values. */\nexport const PLATFORM_VERDICT_REUSE_REASONS = Object.freeze([\n \"entry_changed\",\n \"refusal_observed\",\n \"current_compliance\",\n \"negative_age\",\n \"retention_elapsed\",\n \"key_expired\",\n \"feed_missing\",\n \"feed_stale\",\n \"feed_generation\",\n \"dependencies_empty\",\n \"dependency_revision\",\n \"dependency_floor\",\n \"grant_missing\",\n \"grant_unreadable\",\n \"grant_shape\",\n \"grant_negative_age\",\n \"grant_retention_elapsed\",\n \"shared_refusal_observed\",\n \"shared_refusal_unreadable\",\n \"shared_read_unavailable\",\n \"grant_invalid\",\n \"grant_validation\",\n \"verification_inflight\",\n \"feed_contradiction\",\n \"current_required\",\n \"lkg_retention_elapsed\",\n]);\n\n/** Closed request-phase wire vocabulary, shared by producer and safe consumers. */\nexport const HTTP_REQUEST_PHASE_NAMES = Object.freeze([\n \"external.provision\",\n \"benchmarks.records.load\",\n \"benchmarks.records.build\",\n \"benchmarks.records.page\",\n \"benchmarks.records.json\",\n \"admission.host.list\",\n \"admission.metadata\",\n \"admission.json\",\n \"observability.refresh.wait\",\n \"fleet.sidecars\",\n \"native-export.snapshot.wait\",\n \"native-export.prepare.wait\",\n \"native-export.collect.wait\",\n \"scorecard.fleet.wait\",\n \"scorecard.capacity.wait\",\n \"scorecard.coverage.wait\",\n \"scorecard.compose\",\n \"scorecard.json\",\n \"proxy.model_refresh\",\n \"proxy.hub.lock_wait\",\n \"proxy.hub.refresh\",\n \"proxy.hub.state\",\n \"proxy.hub.proof\",\n \"proxy.hub.delivery\",\n \"proxy.runtime_token\",\n \"snapshot.delete.lock\",\n \"snapshot.delete.credentials\",\n \"snapshot.delete.list\",\n \"snapshot.delete.generation\",\n]);\n\nexport function httpRequestPhaseFromTimingName(name) {\n const prefix = name.startsWith(\"orch.phase.\") ? \"orch.phase.\" : \"phase.\";\n if (!name.startsWith(prefix)) return undefined;\n const phase = name.slice(prefix.length);\n return HTTP_REQUEST_PHASE_NAMES.includes(phase) ? phase : undefined;\n}\n\nexport const PLATFORM_VERDICT_SCOPE_CLASSES = Object.freeze([\n \"key\",\n \"identity\",\n \"owner_user\",\n \"owner_team\",\n \"lineage\",\n \"other\",\n]);\nexport const PLATFORM_VERDICT_EVIDENCE_ORDERS = Object.freeze([\n \"feed_before_observation\",\n \"feed_at_observation\",\n \"feed_after_observation\",\n \"unknown\",\n]);\n\n/** Bounded, closed-schema origin phase projection for the two Worker ledgers.\n * Duplicate observations remain separate; different origins/attempts cannot be summed.\n */\nexport const HTTP_PHASE_COVERAGE_FIELDS = Object.freeze([\n \"stored\",\n \"emitted\",\n \"omitted\",\n \"invalid\",\n \"collisions\",\n \"headerDropped\",\n]);\n\nexport function createUpstreamHttpPhaseProjection() {\n const entries = [];\n let bytes = 0;\n let dropped = 0;\n let rejectedInputs = 0;\n const fields = HTTP_PHASE_COVERAGE_FIELDS;\n const byteLength = (value) => new TextEncoder().encode(value).length;\n const keep = (entry) => {\n // Reserve a bounded forwarding-coverage entry inside this component's 4 KiB.\n const size = byteLength(entry) + 2;\n if (entries.length >= 31 || bytes + size > 3900) {\n dropped++;\n return;\n }\n entries.push(entry);\n bytes += size;\n };\n return {\n absorb(header) {\n if (header == null) return;\n if (\n typeof header !== \"string\" ||\n header.length > 4096 ||\n byteLength(header) > 4096\n ) {\n rejectedInputs++;\n return;\n }\n for (const entry of parseServerTiming(header)) {\n // Only direct origin names enter this fold; never prefix orch. twice.\n if (entry.name === \"phase.coverage\") {\n const counts = {};\n const parts = (entry.desc ?? \"\").split(\",\");\n if (parts.length !== fields.length) {\n dropped++;\n continue;\n }\n for (const part of parts) {\n const [key, value, ...extra] = part.split(\"=\");\n if (\n extra.length ||\n !fields.includes(key) ||\n Object.hasOwn(counts, key) ||\n !/^(?:0|[1-9]\\d*)$/.test(value ?? \"\") ||\n !Number.isSafeInteger(Number(value))\n )\n break;\n counts[key] = Number(value);\n }\n if (Object.keys(counts).length !== fields.length) {\n dropped++;\n continue;\n }\n keep(\n `orch.phase.coverage;desc=\"${fields.map((key) => `${key}=${counts[key]}`).join(\",\")}\"`,\n );\n } else if (entry.name.startsWith(\"phase.\")) {\n if (\n !httpRequestPhaseFromTimingName(entry.name) ||\n !Number.isFinite(entry.dur) ||\n entry.dur < 0 ||\n !/^outcome=(?:completed|error)$/.test(entry.desc ?? \"\")\n ) {\n dropped++;\n continue;\n }\n keep(\n `orch.${entry.name};dur=${Math.round(entry.dur)};desc=\"${entry.desc}\"`,\n );\n }\n }\n },\n entries() {\n return [\n ...entries,\n ...(dropped || rejectedInputs\n ? [\n `orch.phase.forwarding;desc=\"dropped=${dropped},rejectedInputs=${rejectedInputs}\"`,\n ]\n : []),\n ];\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ //#region src/create-wall.d.ts
2
+ /** Exclusive create-request wall phases; nested service spans are a separate view. */
3
+ declare const CREATE_WALL_PHASES: readonly ["middleware", "identity", "preflight", "tenantCoordination", "configuration", "leaseSelection", "credentialJournal", "quotaReservation", "orchestrator", "provisionResponse", "responseBody", "credentialAllocation", "postCreate", "response"];
4
+ type CreateWallPhase = (typeof CREATE_WALL_PHASES)[number];
5
+ type CreateWallPhases = Record<CreateWallPhase, number>;
6
+ interface CreateWallMeasurement {
7
+ phases: CreateWallPhases;
8
+ totalMs: number;
9
+ /** Includes middleware/auth, preserving the original bookkeeping + post budget. */
10
+ bookkeepingPostCreateMs: number;
11
+ }
12
+ /** The original other-Worker + post-create budget, including auth/middleware. */
13
+ declare function createBookkeepingPostWall(phases: CreateWallPhases): number;
14
+ /**
15
+ * One cursor owned by the sequential request path. Parallel operations keep
16
+ * their own spans and never transition this cursor from their callbacks.
17
+ * Invalid clocks or missing caller hooks withhold a complete measurement.
18
+ */
19
+ declare function createWallTiming(startedAt: number): {
20
+ phase(name: CreateWallPhase, at: number): void;
21
+ finish(receivedAt: number, respondedAt: number): CreateWallMeasurement | null;
22
+ };
23
+ /** Read the already-parsed header. Historical/incomplete/overlapping rows stay unknown. */
24
+ declare function readCreateWallTiming(stages: Readonly<Record<string, number>>): CreateWallMeasurement | null;
25
+ //#endregion
26
+ //#region src/server-timing-parser.d.mts
27
+ interface ServerTimingEntry {
28
+ name: string;
29
+ dur?: number;
30
+ desc?: string;
31
+ }
32
+ declare function parseServerTiming(header: string | null | undefined): ServerTimingEntry[];
33
+ declare function parseServerTimingDurations(header: string | null | undefined): Record<string, number>;
34
+ declare const PLATFORM_VERDICT_REUSE_REASONS: readonly ["entry_changed", "refusal_observed", "current_compliance", "negative_age", "retention_elapsed", "key_expired", "feed_missing", "feed_stale", "feed_generation", "dependencies_empty", "dependency_revision", "dependency_floor", "grant_missing", "grant_unreadable", "grant_shape", "grant_negative_age", "grant_retention_elapsed", "shared_refusal_observed", "shared_refusal_unreadable", "shared_read_unavailable", "grant_invalid", "grant_validation", "verification_inflight", "feed_contradiction", "current_required", "lkg_retention_elapsed"];
35
+ type PlatformVerdictReuseRejection = (typeof PLATFORM_VERDICT_REUSE_REASONS)[number];
36
+ declare const HTTP_REQUEST_PHASE_NAMES: readonly ["external.provision", "benchmarks.records.load", "benchmarks.records.build", "benchmarks.records.page", "benchmarks.records.json", "admission.host.list", "admission.metadata", "admission.json", "observability.refresh.wait", "fleet.sidecars", "native-export.snapshot.wait", "native-export.prepare.wait", "native-export.collect.wait", "scorecard.fleet.wait", "scorecard.capacity.wait", "scorecard.coverage.wait", "scorecard.compose", "scorecard.json", "proxy.model_refresh", "proxy.hub.lock_wait", "proxy.hub.refresh", "proxy.hub.state", "proxy.hub.proof", "proxy.hub.delivery", "proxy.runtime_token", "snapshot.delete.lock", "snapshot.delete.credentials", "snapshot.delete.list", "snapshot.delete.generation"];
37
+ type HttpRequestPhaseName = (typeof HTTP_REQUEST_PHASE_NAMES)[number];
38
+ declare function httpRequestPhaseFromTimingName(name: string): HttpRequestPhaseName | undefined;
39
+ declare const PLATFORM_VERDICT_SCOPE_CLASSES: readonly ["key", "identity", "owner_user", "owner_team", "lineage", "other"];
40
+ declare const PLATFORM_VERDICT_EVIDENCE_ORDERS: readonly ["feed_before_observation", "feed_at_observation", "feed_after_observation", "unknown"];
41
+ type PlatformVerdictDependencyMismatch = {
42
+ scopeClass: (typeof PLATFORM_VERDICT_SCOPE_CLASSES)[number];
43
+ evidenceOrder: (typeof PLATFORM_VERDICT_EVIDENCE_ORDERS)[number];
44
+ };
45
+ declare function createUpstreamHttpPhaseProjection(): {
46
+ absorb(header: unknown): void;
47
+ entries(): string[];
48
+ };
49
+ declare const HTTP_PHASE_COVERAGE_FIELDS: readonly ["stored", "emitted", "omitted", "invalid", "collisions", "headerDropped"];
50
+ //#endregion
51
+ export { CreateWallPhases as _, PLATFORM_VERDICT_REUSE_REASONS as a, readCreateWallTiming as b, PlatformVerdictReuseRejection as c, httpRequestPhaseFromTimingName as d, parseServerTiming as f, CreateWallPhase as g, CreateWallMeasurement as h, PLATFORM_VERDICT_EVIDENCE_ORDERS as i, ServerTimingEntry as l, CREATE_WALL_PHASES as m, HTTP_REQUEST_PHASE_NAMES as n, PLATFORM_VERDICT_SCOPE_CLASSES as o, parseServerTimingDurations as p, HttpRequestPhaseName as r, PlatformVerdictDependencyMismatch as s, HTTP_PHASE_COVERAGE_FIELDS as t, createUpstreamHttpPhaseProjection as u, createBookkeepingPostWall as v, createWallTiming as y };
52
+ //# sourceMappingURL=server-timing-Cj-NB41a.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-timing-Cj-NB41a.d.mts","names":["ServerTimingEntry","name","dur","desc","parseServerTiming","header","parseServerTimingDurations","Record","PLATFORM_VERDICT_REUSE_REASONS","PlatformVerdictReuseRejection","HTTP_REQUEST_PHASE_NAMES","HttpRequestPhaseName","httpRequestPhaseFromTimingName","PLATFORM_VERDICT_SCOPE_CLASSES","PLATFORM_VERDICT_EVIDENCE_ORDERS","PlatformVerdictDependencyMismatch","scopeClass","evidenceOrder","createUpstreamHttpPhaseProjection","absorb","entries","HTTP_PHASE_COVERAGE_FIELDS"],"sources":["../src/create-wall.ts","../src/server-timing-parser.d.mts"],"mappings":";;cACa,kBAAA;AAAA,KAiBD,eAAA,WAA0B,kBAAA;AAAA,KAC1B,gBAAA,GAAmB,MAAA,CAAO,eAAA;AAAA,UACrB,qBAAA;EACf,MAAA,EAAQ,gBAAA;EACR,OAAA;EAJyB;EAMzB,uBAAA;AAAA;;iBAWc,yBAAA,CAA0B,MAAA,EAAQ,gBAAA;;;;;AAflD;iBA6BgB,gBAAA,CAAiB,SAAA;cAUjB,eAAA,EAAe,EAAA;6BAWP,WAAA,WAEjB,qBAAA;AAAA;;iBA6BS,oBAAA,CACd,MAAA,EAAQ,QAAA,CAAS,MAAA,oBAChB,qBAAA;;;UCvGcA,iBAAAA;EACfC,IAAAA;EACAC,GAAAA;EACAC,IAAAA;AAAAA;AAAAA,iBAGcC,iBAAAA,CACdC,MAAAA,8BACCL,iBAAAA;AAAAA,iBAEaM,0BAAAA,CACdD,MAAAA,8BACCE,MAAAA;AAAAA,cAEUC,8BAAAA;AAAAA,KA4BDC,6BAAAA,WACFD,8BAAAA;AAAAA,cAEGE,wBAAAA;AAAAA,KA+BDC,oBAAAA,WAA+BD,wBAAAA;AAAAA,iBAC3BE,8BAAAA,CACdX,IAAAA,WACCU,oBAAAA;AAAAA,cACUE,8BAAAA;AAAAA,cAQAC,gCAAAA;AAAAA,KAMDC,iCAAAA;EACVC,UAAAA,UAAoBH,8BAAAA;EACpBI,aAAAA,UAAuBH,gCAAAA;AAAAA;AAAAA,iBAGTI,iCAAAA,CAAAA;EACdC,MAAAA,CAAOd,MAAAA;EACPe,OAAAA;AAAAA;AAAAA,cAGWC,0BAAAA"}
@@ -1,2 +1,2 @@
1
- import { a as CreateWallMeasurement, c as createBookkeepingPostWall, i as CREATE_WALL_PHASES, l as createWallTiming, n as parseServerTiming, o as CreateWallPhase, r as parseServerTimingDurations, s as CreateWallPhases, t as ServerTimingEntry, u as readCreateWallTiming } from "./server-timing-C9RFa_A_.mjs";
2
- export { CREATE_WALL_PHASES, CreateWallMeasurement, CreateWallPhase, CreateWallPhases, ServerTimingEntry, createBookkeepingPostWall, createWallTiming, parseServerTiming, parseServerTimingDurations, readCreateWallTiming };
1
+ import { _ as CreateWallPhases, a as PLATFORM_VERDICT_REUSE_REASONS, b as readCreateWallTiming, c as PlatformVerdictReuseRejection, d as httpRequestPhaseFromTimingName, f as parseServerTiming, g as CreateWallPhase, h as CreateWallMeasurement, i as PLATFORM_VERDICT_EVIDENCE_ORDERS, l as ServerTimingEntry, m as CREATE_WALL_PHASES, n as HTTP_REQUEST_PHASE_NAMES, o as PLATFORM_VERDICT_SCOPE_CLASSES, p as parseServerTimingDurations, r as HttpRequestPhaseName, s as PlatformVerdictDependencyMismatch, t as HTTP_PHASE_COVERAGE_FIELDS, u as createUpstreamHttpPhaseProjection, v as createBookkeepingPostWall, y as createWallTiming } from "./server-timing-Cj-NB41a.mjs";
2
+ export { CREATE_WALL_PHASES, CreateWallMeasurement, CreateWallPhase, CreateWallPhases, HTTP_PHASE_COVERAGE_FIELDS, HTTP_REQUEST_PHASE_NAMES, HttpRequestPhaseName, PLATFORM_VERDICT_EVIDENCE_ORDERS, PLATFORM_VERDICT_REUSE_REASONS, PLATFORM_VERDICT_SCOPE_CLASSES, PlatformVerdictDependencyMismatch, PlatformVerdictReuseRejection, ServerTimingEntry, createBookkeepingPostWall, createUpstreamHttpPhaseProjection, createWallTiming, httpRequestPhaseFromTimingName, parseServerTiming, parseServerTimingDurations, readCreateWallTiming };
@@ -1,2 +1,2 @@
1
- import { a as createWallTiming, i as createBookkeepingPostWall, n as parseServerTimingDurations, o as readCreateWallTiming, r as CREATE_WALL_PHASES, t as parseServerTiming } from "./server-timing-DakHMNHj.mjs";
2
- export { CREATE_WALL_PHASES, createBookkeepingPostWall, createWallTiming, parseServerTiming, parseServerTimingDurations, readCreateWallTiming };
1
+ import { a as PLATFORM_VERDICT_SCOPE_CLASSES, c as parseServerTiming, d as createBookkeepingPostWall, f as createWallTiming, i as PLATFORM_VERDICT_REUSE_REASONS, l as parseServerTimingDurations, n as HTTP_REQUEST_PHASE_NAMES, o as createUpstreamHttpPhaseProjection, p as readCreateWallTiming, r as PLATFORM_VERDICT_EVIDENCE_ORDERS, s as httpRequestPhaseFromTimingName, t as HTTP_PHASE_COVERAGE_FIELDS, u as CREATE_WALL_PHASES } from "./server-timing-BsEa33zu.mjs";
2
+ export { CREATE_WALL_PHASES, HTTP_PHASE_COVERAGE_FIELDS, HTTP_REQUEST_PHASE_NAMES, PLATFORM_VERDICT_EVIDENCE_ORDERS, PLATFORM_VERDICT_REUSE_REASONS, PLATFORM_VERDICT_SCOPE_CLASSES, createBookkeepingPostWall, createUpstreamHttpPhaseProjection, createWallTiming, httpRequestPhaseFromTimingName, parseServerTiming, parseServerTimingDurations, readCreateWallTiming };
@@ -1,4 +1,4 @@
1
- import { n as parseServerTiming, t as ServerTimingEntry } from "./server-timing-C9RFa_A_.mjs";
1
+ import { f as parseServerTiming, l as ServerTimingEntry } from "./server-timing-Cj-NB41a.mjs";
2
2
 
3
3
  //#region src/stage-span.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as parseServerTiming } from "./server-timing-DakHMNHj.mjs";
1
+ import { c as parseServerTiming } from "./server-timing-BsEa33zu.mjs";
2
2
  //#region src/stage-span.ts
3
3
  /**
4
4
  * One span shape for every lifecycle-op stage across every hop.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sdk-telemetry",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -74,8 +74,8 @@
74
74
  }
75
75
  },
76
76
  "tangleRelease": {
77
- "sourceSha": "b66b40689425eb54bcb3c576be0ac54cf93770b1",
78
- "mergedAt": "2026-10-23T18:31:26-06:00"
77
+ "sourceSha": "291f2685b9e364bbb9a78ab060dd0377de6979af",
78
+ "mergedAt": "2026-10-24T04:26:14-06:00"
79
79
  },
80
80
  "scripts": {
81
81
  "build": "tsdown",
@@ -1,36 +0,0 @@
1
- //#region src/create-wall.d.ts
2
- /** Exclusive create-request wall phases; nested service spans are a separate view. */
3
- declare const CREATE_WALL_PHASES: readonly ["middleware", "identity", "preflight", "tenantCoordination", "configuration", "leaseSelection", "credentialJournal", "quotaReservation", "orchestrator", "provisionResponse", "responseBody", "credentialAllocation", "postCreate", "response"];
4
- type CreateWallPhase = (typeof CREATE_WALL_PHASES)[number];
5
- type CreateWallPhases = Record<CreateWallPhase, number>;
6
- interface CreateWallMeasurement {
7
- phases: CreateWallPhases;
8
- totalMs: number;
9
- /** Includes middleware/auth, preserving the original bookkeeping + post budget. */
10
- bookkeepingPostCreateMs: number;
11
- }
12
- /** The original other-Worker + post-create budget, including auth/middleware. */
13
- declare function createBookkeepingPostWall(phases: CreateWallPhases): number;
14
- /**
15
- * One cursor owned by the sequential request path. Parallel operations keep
16
- * their own spans and never transition this cursor from their callbacks.
17
- * Invalid clocks or missing caller hooks withhold a complete measurement.
18
- */
19
- declare function createWallTiming(startedAt: number): {
20
- phase(name: CreateWallPhase, at: number): void;
21
- finish(receivedAt: number, respondedAt: number): CreateWallMeasurement | null;
22
- };
23
- /** Read the already-parsed header. Historical/incomplete/overlapping rows stay unknown. */
24
- declare function readCreateWallTiming(stages: Readonly<Record<string, number>>): CreateWallMeasurement | null;
25
- //#endregion
26
- //#region src/server-timing-parser.d.mts
27
- interface ServerTimingEntry {
28
- name: string;
29
- dur?: number;
30
- desc?: string;
31
- }
32
- declare function parseServerTiming(header: string | null | undefined): ServerTimingEntry[];
33
- declare function parseServerTimingDurations(header: string | null | undefined): Record<string, number>;
34
- //#endregion
35
- export { CreateWallMeasurement as a, createBookkeepingPostWall as c, CREATE_WALL_PHASES as i, createWallTiming as l, parseServerTiming as n, CreateWallPhase as o, parseServerTimingDurations as r, CreateWallPhases as s, ServerTimingEntry as t, readCreateWallTiming as u };
36
- //# sourceMappingURL=server-timing-C9RFa_A_.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server-timing-C9RFa_A_.d.mts","names":["ServerTimingEntry","name","dur","desc","parseServerTiming","header","parseServerTimingDurations","Record"],"sources":["../src/create-wall.ts","../src/server-timing-parser.d.mts"],"mappings":";;cACa,kBAAA;AAAA,KAiBD,eAAA,WAA0B,kBAAA;AAAA,KAC1B,gBAAA,GAAmB,MAAA,CAAO,eAAA;AAAA,UACrB,qBAAA;EACf,MAAA,EAAQ,gBAAA;EACR,OAAA;EAJyB;EAMzB,uBAAA;AAAA;;iBAWc,yBAAA,CAA0B,MAAA,EAAQ,gBAAA;;;;;AAflD;iBA6BgB,gBAAA,CAAiB,SAAA;cAUjB,eAAA,EAAe,EAAA;6BAWP,WAAA,WAEjB,qBAAA;AAAA;;iBA6BS,oBAAA,CACd,MAAA,EAAQ,QAAA,CAAS,MAAA,oBAChB,qBAAA;;;UCvGcA,iBAAAA;EACfC,IAAAA;EACAC,GAAAA;EACAC,IAAAA;AAAAA;AAAAA,iBAGcC,iBAAAA,CACdC,MAAAA,8BACCL,iBAAAA;AAAAA,iBAEaM,0BAAAA,CACdD,MAAAA,8BACCE,MAAAA"}
@@ -1,135 +0,0 @@
1
- //#region src/create-wall.ts
2
- /** Exclusive create-request wall phases; nested service spans are a separate view. */
3
- const CREATE_WALL_PHASES = [
4
- "middleware",
5
- "identity",
6
- "preflight",
7
- "tenantCoordination",
8
- "configuration",
9
- "leaseSelection",
10
- "credentialJournal",
11
- "quotaReservation",
12
- "orchestrator",
13
- "provisionResponse",
14
- "responseBody",
15
- "credentialAllocation",
16
- "postCreate",
17
- "response"
18
- ];
19
- const REQUIRED_PHASES = CREATE_WALL_PHASES.filter((phase) => phase !== "middleware" && phase !== "leaseSelection" && phase !== "tenantCoordination");
20
- /** The original other-Worker + post-create budget, including auth/middleware. */
21
- function createBookkeepingPostWall(phases) {
22
- return CREATE_WALL_PHASES.reduce((sum, phase) => sum + (phase === "preflight" || phase === "orchestrator" ? 0 : phases[phase]), 0);
23
- }
24
- /**
25
- * One cursor owned by the sequential request path. Parallel operations keep
26
- * their own spans and never transition this cursor from their callbacks.
27
- * Invalid clocks or missing caller hooks withhold a complete measurement.
28
- */
29
- function createWallTiming(startedAt) {
30
- const phases = Object.fromEntries(CREATE_WALL_PHASES.map((phase) => [phase, 0]));
31
- const visited = new Set(["identity"]);
32
- let current = "identity";
33
- let cursor = startedAt;
34
- let valid = Number.isFinite(startedAt);
35
- let finished = false;
36
- return {
37
- phase(name, at) {
38
- if (finished || !Number.isFinite(at) || at < cursor) {
39
- valid = false;
40
- return;
41
- }
42
- phases[current] += at - cursor;
43
- cursor = at;
44
- current = name;
45
- visited.add(name);
46
- },
47
- finish(receivedAt, respondedAt) {
48
- if (finished || !valid || !Number.isFinite(receivedAt) || !Number.isFinite(respondedAt) || receivedAt > startedAt || respondedAt < cursor || REQUIRED_PHASES.some((phase) => !visited.has(phase))) {
49
- finished = true;
50
- return null;
51
- }
52
- finished = true;
53
- phases[current] += respondedAt - cursor;
54
- phases.middleware = startedAt - receivedAt;
55
- const totalMs = respondedAt - receivedAt;
56
- if (Object.values(phases).reduce((sum, ms) => sum + ms, 0) !== totalMs) return null;
57
- return {
58
- phases: { ...phases },
59
- totalMs,
60
- bookkeepingPostCreateMs: createBookkeepingPostWall(phases)
61
- };
62
- }
63
- };
64
- }
65
- /** Read the already-parsed header. Historical/incomplete/overlapping rows stay unknown. */
66
- function readCreateWallTiming(stages) {
67
- const totalMs = stages["createWall.total"];
68
- if (!Number.isFinite(totalMs) || totalMs < 0 || totalMs !== stages.outerWall) return null;
69
- const phases = {};
70
- for (const phase of CREATE_WALL_PHASES) {
71
- const value = stages[`createWall.${phase}`];
72
- if (!Number.isFinite(value) || value < 0) return null;
73
- phases[phase] = value;
74
- }
75
- if (Object.values(phases).reduce((sum, ms) => sum + ms, 0) !== totalMs) return null;
76
- return {
77
- phases,
78
- totalMs,
79
- bookkeepingPostCreateMs: createBookkeepingPostWall(phases)
80
- };
81
- }
82
- //#endregion
83
- //#region src/server-timing-parser.mjs
84
- function splitHeader(value, separator) {
85
- const parts = [];
86
- let start = 0;
87
- let quoted = false;
88
- for (let i = 0; i < value.length; i++) if (quoted && value[i] === "\\") i++;
89
- else if (value[i] === "\"") quoted = !quoted;
90
- else if (!quoted && value[i] === separator) {
91
- parts.push(value.slice(start, i));
92
- start = i + 1;
93
- }
94
- parts.push(value.slice(start));
95
- return parts;
96
- }
97
- /** Missing or malformed durations remain unmeasured, never zero. */
98
- function parseServerTiming(header) {
99
- if (!header) return [];
100
- const entries = [];
101
- for (const metric of splitHeader(header, ",")) {
102
- const [rawName, ...params] = splitHeader(metric, ";");
103
- const name = rawName.trim();
104
- if (!/^[!#$%&'*+.^_`|~\w-]+$/.test(name)) continue;
105
- const entry = { name };
106
- const seen = /* @__PURE__ */ new Set();
107
- for (const param of params) {
108
- const eq = param.indexOf("=");
109
- const key = (eq < 0 ? param : param.slice(0, eq)).trim().toLowerCase();
110
- if (seen.has(key)) continue;
111
- seen.add(key);
112
- if (eq < 0) continue;
113
- let value = param.slice(eq + 1).trim();
114
- if (value.startsWith("\"")) {
115
- if (!/^"(?:[^"\\]|\\[\s\S])*"$/.test(value)) continue;
116
- value = value.slice(1, -1).replace(/\\([\s\S])/g, "$1");
117
- }
118
- if (key === "desc") entry.desc = value;
119
- else if (key === "dur" && /^[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(value)) {
120
- const duration = Number(value);
121
- if (Number.isFinite(duration)) entry.dur = duration;
122
- }
123
- }
124
- entries.push(entry);
125
- }
126
- return entries;
127
- }
128
- /** A stage ledger retains only duration-bearing entries; later metrics win. */
129
- function parseServerTimingDurations(header) {
130
- return Object.fromEntries(parseServerTiming(header).filter((entry) => entry.dur !== void 0).map(({ name, dur }) => [name, dur]));
131
- }
132
- //#endregion
133
- export { createWallTiming as a, createBookkeepingPostWall as i, parseServerTimingDurations as n, readCreateWallTiming as o, CREATE_WALL_PHASES as r, parseServerTiming as t };
134
-
135
- //# sourceMappingURL=server-timing-DakHMNHj.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server-timing-DakHMNHj.mjs","names":[],"sources":["../src/create-wall.ts","../src/server-timing-parser.mjs"],"sourcesContent":["/** Exclusive create-request wall phases; nested service spans are a separate view. */\nexport const CREATE_WALL_PHASES = [\n \"middleware\",\n \"identity\",\n \"preflight\",\n \"tenantCoordination\",\n \"configuration\",\n \"leaseSelection\",\n \"credentialJournal\",\n \"quotaReservation\",\n \"orchestrator\",\n \"provisionResponse\",\n \"responseBody\",\n \"credentialAllocation\",\n \"postCreate\",\n \"response\",\n] as const;\n\nexport type CreateWallPhase = (typeof CREATE_WALL_PHASES)[number];\nexport type CreateWallPhases = Record<CreateWallPhase, number>;\nexport interface CreateWallMeasurement {\n phases: CreateWallPhases;\n totalMs: number;\n /** Includes middleware/auth, preserving the original bookkeeping + post budget. */\n bookkeepingPostCreateMs: number;\n}\n\nconst REQUIRED_PHASES = CREATE_WALL_PHASES.filter(\n (phase) =>\n phase !== \"middleware\" &&\n phase !== \"leaseSelection\" &&\n phase !== \"tenantCoordination\",\n);\n\n/** The original other-Worker + post-create budget, including auth/middleware. */\nexport function createBookkeepingPostWall(phases: CreateWallPhases): number {\n return CREATE_WALL_PHASES.reduce(\n (sum, phase) =>\n sum +\n (phase === \"preflight\" || phase === \"orchestrator\" ? 0 : phases[phase]),\n 0,\n );\n}\n\n/**\n * One cursor owned by the sequential request path. Parallel operations keep\n * their own spans and never transition this cursor from their callbacks.\n * Invalid clocks or missing caller hooks withhold a complete measurement.\n */\nexport function createWallTiming(startedAt: number) {\n const phases = Object.fromEntries(\n CREATE_WALL_PHASES.map((phase) => [phase, 0]),\n ) as CreateWallPhases;\n const visited = new Set<CreateWallPhase>([\"identity\"]);\n let current: CreateWallPhase = \"identity\";\n let cursor = startedAt;\n let valid = Number.isFinite(startedAt);\n let finished = false;\n return {\n phase(name: CreateWallPhase, at: number): void {\n if (finished || !Number.isFinite(at) || at < cursor) {\n valid = false;\n return;\n }\n phases[current] += at - cursor;\n cursor = at;\n current = name;\n visited.add(name);\n },\n finish(\n receivedAt: number,\n respondedAt: number,\n ): CreateWallMeasurement | null {\n if (\n finished ||\n !valid ||\n !Number.isFinite(receivedAt) ||\n !Number.isFinite(respondedAt) ||\n receivedAt > startedAt ||\n respondedAt < cursor ||\n REQUIRED_PHASES.some((phase) => !visited.has(phase))\n ) {\n finished = true;\n return null;\n }\n finished = true;\n phases[current] += respondedAt - cursor;\n phases.middleware = startedAt - receivedAt;\n const totalMs = respondedAt - receivedAt;\n if (Object.values(phases).reduce((sum, ms) => sum + ms, 0) !== totalMs)\n return null;\n return {\n phases: { ...phases },\n totalMs,\n bookkeepingPostCreateMs: createBookkeepingPostWall(phases),\n };\n },\n };\n}\n\n/** Read the already-parsed header. Historical/incomplete/overlapping rows stay unknown. */\nexport function readCreateWallTiming(\n stages: Readonly<Record<string, number>>,\n): CreateWallMeasurement | null {\n const totalMs = stages[\"createWall.total\"];\n if (!Number.isFinite(totalMs) || totalMs < 0 || totalMs !== stages.outerWall)\n return null;\n const phases = {} as CreateWallPhases;\n for (const phase of CREATE_WALL_PHASES) {\n const value = stages[`createWall.${phase}`];\n if (!Number.isFinite(value) || value < 0) return null;\n phases[phase] = value;\n }\n if (Object.values(phases).reduce((sum, ms) => sum + ms, 0) !== totalMs)\n return null;\n return {\n phases,\n totalMs,\n bookkeepingPostCreateMs: createBookkeepingPostWall(phases),\n };\n}\n","// HTTP quoted strings can contain both separators and escaped quotes.\nfunction splitHeader(value, separator) {\n const parts = [];\n let start = 0;\n let quoted = false;\n for (let i = 0; i < value.length; i++) {\n if (quoted && value[i] === \"\\\\\") i++;\n else if (value[i] === '\"') quoted = !quoted;\n else if (!quoted && value[i] === separator) {\n parts.push(value.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(value.slice(start));\n return parts;\n}\n\n/** Missing or malformed durations remain unmeasured, never zero. */\nexport function parseServerTiming(header) {\n if (!header) return [];\n const entries = [];\n for (const metric of splitHeader(header, \",\")) {\n const [rawName, ...params] = splitHeader(metric, \";\");\n const name = rawName.trim();\n if (!/^[!#$%&'*+.^_`|~\\w-]+$/.test(name)) continue;\n const entry = { name };\n const seen = new Set();\n for (const param of params) {\n const eq = param.indexOf(\"=\");\n const key = (eq < 0 ? param : param.slice(0, eq)).trim().toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n if (eq < 0) continue;\n let value = param.slice(eq + 1).trim();\n if (value.startsWith('\"')) {\n if (!/^\"(?:[^\"\\\\]|\\\\[\\s\\S])*\"$/.test(value)) continue;\n value = value.slice(1, -1).replace(/\\\\([\\s\\S])/g, \"$1\");\n }\n if (key === \"desc\") entry.desc = value;\n else if (\n key === \"dur\" &&\n /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)(?:e[+-]?\\d+)?$/i.test(value)\n ) {\n const duration = Number(value);\n if (Number.isFinite(duration)) entry.dur = duration;\n }\n }\n entries.push(entry);\n }\n return entries;\n}\n\n/** A stage ledger retains only duration-bearing entries; later metrics win. */\nexport function parseServerTimingDurations(header) {\n return Object.fromEntries(\n parseServerTiming(header)\n .filter((entry) => entry.dur !== undefined)\n .map(({ name, dur }) => [name, dur]),\n );\n}\n"],"mappings":"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"}