@tangle-network/sdk-telemetry 0.7.10 → 0.7.12

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.
@@ -1,12 +1,5 @@
1
1
  //#region src/lifecycle-wall.d.ts
2
- /**
3
- * Per-flow shape of the accounting window. `totalOperation` is the span whose
4
- * wall the named leaves must tile; `postReadyOperations` run AFTER it is
5
- * stamped (excluded from the leaf sum); `prepUmbrella` is the optional
6
- * create-style split of an entry umbrella minus its measured leaf children. Absent
7
- * `prepUmbrella` ⇒ `prepUnaccountedMs` is always 0 and the whole dark falls
8
- * into `unaccountedMs` (the shape every non-create flow uses).
9
- */
2
+ /** Per-flow shape of the accounting window. */
10
3
  type FlowAccountingSpec = {
11
4
  totalOperation: string;
12
5
  postReadyOperations?: ReadonlySet<string>;
@@ -43,25 +36,7 @@ interface LifecycleWallFlow extends Partial<FlowAccountingSpec> {
43
36
  settleHop?: string;
44
37
  workerNamedHops?: readonly string[];
45
38
  }
46
- /**
47
- * A flat `{name: ms}` ledger read as the tree its names describe.
48
- *
49
- * Every producer in this repo emits nested stages FLAT, with the containment
50
- * in the name: `capture.<hostPhase>` and `capture.restic_<phase>` inside
51
- * `capture` (snapshot-helpers.ts), `materialize.parentRead|precreate|
52
- * branchComplete|host.*|child.*|residual` inside `materialize` (branch.ts),
53
- * `delete.<hostPhase>` inside `delete` and `restore_workspace.<phase>` inside
54
- * `restore_workspace` (snapshots.ts). Summing every entry as a sibling counts
55
- * the children inside their parent a second time and reports a wall the
56
- * orchestrator never spent.
57
- *
58
- * So a dotted name is NEVER top-level. It attaches to the longest prefix that
59
- * exists as a stage; when no prefix exists — the restore job's `host.<phase>`,
60
- * which the queue records inside `restore_workspace` without naming it
61
- * (snapshot-job-queue.ts:394) — it is still excluded from the top-level sum
62
- * and reported as a child of the ledger at large. Excluding it can only leave
63
- * MORE time unnamed, never fabricate a reconciliation.
64
- */
39
+ /** Longest present prefix owns a dotted stage; orphan detail never enters the root sum. */
65
40
  declare function stageTree(stages: Readonly<Record<string, number>>): {
66
41
  nodes: {
67
42
  name: string;
@@ -80,33 +55,20 @@ declare function stageTree(stages: Readonly<Record<string, number>>): {
80
55
  }[];
81
56
  topLevelMs: number;
82
57
  };
83
- /**
84
- * A response's span tree as `<stage>.<path>` rows and each parent's wall minus
85
- * its children as `<parent>.unattributed` (0 when children overlap), residuals
86
- * first so a capped header keeps them. Unparented spans nest in the total span.
87
- */
58
+ /** Parent minus its direct children; overlapping evidence never invents dark time. */
59
+ declare function unattributedStages(stages: Readonly<Record<string, number>>, parents: Readonly<Record<string, readonly string[]>>): Record<string, number>;
60
+ /** A response's span tree as `<stage>.<path>` rows and each parent's wall minus its children as `<parent>.unattributed` (0 when children overlap), residuals first so a capped header keeps them. Unparented spans nest in the total span. */
88
61
  declare function spanTreeStages(stage: string, stageMs: Readonly<Record<string, number>>, operations?: readonly (LifecycleStageTiming & {
89
62
  status?: string;
90
63
  })[], spec?: Partial<FlowAccountingSpec>): Record<string, number>;
91
64
  /** Parent operations contain their descendants and are never counted as leaves. */
92
65
  declare function parentOperations(operations: readonly LifecycleStageTiming[]): ReadonlySet<string>;
93
- /**
94
- * The measured leaves of one response's span tree, per the flow's own spec.
95
- *
96
- * Identical rule to the orchestrator's `computeFlowAccountingResiduals`: drop
97
- * the total span (it is the window), drop the spans stamped after it closes,
98
- * and drop any span another span names as its parent (a parent re-measures its
99
- * children). What is left sums to the window minus its named residual.
100
- */
66
+ /** The measured leaves of one response's span tree, per the flow's own spec. */
101
67
  declare function leafOperations<T extends LifecycleStageTiming>(operations: readonly T[], excluded?: ReadonlySet<string>, parents?: ReadonlySet<string>): (T & {
102
68
  durationMs: number;
103
69
  })[];
104
70
  declare function operationLeafDurations(operations: readonly LifecycleStageTiming[], excluded?: ReadonlySet<string>): Map<string, number>;
105
- /**
106
- * Partition one input before aggregation: null is unavailable; a negative
107
- * residual is overlapping evidence, never an instruction to publish zero.
108
- * Callers retain their population grouping, medians and display labels.
109
- */
71
+ /** Partition one input before aggregation: null is unavailable; a negative residual is overlapping evidence, never an instruction to publish zero. Callers retain their population grouping, medians and display labels. */
110
72
  declare function partitionLifecycleWalls(sample: LifecycleWallSample, flow: LifecycleWallFlow): {
111
73
  wallMs: number;
112
74
  httpMs: number;
@@ -189,5 +151,5 @@ declare function partitionLifecycleWalls(sample: LifecycleWallSample, flow: Life
189
151
  };
190
152
  };
191
153
  //#endregion
192
- export { LifecycleWallSample as a, leafOperations as c, partitionLifecycleWalls as d, spanTreeStages as f, LifecycleWallFlow as i, operationLeafDurations as l, DELETE_ACCOUNTING_SPEC as n, RESUME_ACCOUNTING_SPEC as o, stageTree as p, FlowAccountingSpec as r, STOP_ACCOUNTING_SPEC as s, CREATE_ACCOUNTING_SPEC as t, parentOperations as u };
193
- //# sourceMappingURL=lifecycle-wall-BnN-KFBx.d.mts.map
154
+ export { LifecycleWallSample as a, leafOperations as c, partitionLifecycleWalls as d, spanTreeStages as f, LifecycleWallFlow as i, operationLeafDurations as l, unattributedStages as m, DELETE_ACCOUNTING_SPEC as n, RESUME_ACCOUNTING_SPEC as o, stageTree as p, FlowAccountingSpec as r, STOP_ACCOUNTING_SPEC as s, CREATE_ACCOUNTING_SPEC as t, parentOperations as u };
155
+ //# sourceMappingURL=lifecycle-wall-BL6-gCBp.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-wall-BL6-gCBp.d.mts","names":[],"sources":["../src/lifecycle-wall.ts"],"mappings":";;KAOY,kBAAA;EACV,cAAA;EACA,mBAAA,GAAsB,WAAA;EACtB,YAAA;IAAiB,SAAA;EAAA;AAAA;AAAA,cAGN,sBAAA,EAAwB,kBAAA;AAAA,cAQxB,sBAAA,EAAwB,kBAAA;AAAA,cAWxB,oBAAA,EAAsB,kBAAA;AAAA,cAItB,sBAAA,EAAwB,kBAAA;AAAA,UAIpB,oBAAA;EACf,SAAA;EACA,UAAA;EACA,MAAA;AAAA;AAAA,KAEG,MAAA,GAAS,QAAA,CAAS,MAAA;AAAA,UACN,mBAAA;EACf,MAAA;EACA,MAAA;EACA,IAAA,GAAO,MAAA;EACP,OAAA,YAAmB,oBAAA;EACnB,UAAA,GAAa,MAAA;EACb,WAAA;EACA,UAAA,GAAa,MAAA;EACb,SAAA,GAAY,MAAA;EACZ,KAAA;EACA,QAAA;EACA,eAAA;AAAA;AAAA,UAEe,iBAAA,SAA0B,OAAA,CAAQ,kBAAA;EACjD,cAAA;EACA,aAAA;EACA,SAAA;EACA,eAAA;AAAA;;iBAIc,SAAA,CAAU,MAAA,EAAQ,QAAA,CAAS,MAAA;;;;;;;;;;OAlBlC;;;;;;;;;iBA6CO,kBAAA,CACd,MAAA,EAAQ,QAAA,CAAS,MAAA,mBACjB,OAAA,EAAS,QAAA,CAAS,MAAA,+BACjB,MAAA;;iBA0Ba,cAAA,CACd,KAAA,UACA,OAAA,EAAS,QAAA,CAAS,MAAA,mBAClB,UAAA,aAAsB,oBAAA;EAAyB,MAAA;AAAA,MAC/C,IAAA,GAAO,OAAA,CAAQ,kBAAA,IACd,MAAA;;iBA4Ca,gBAAA,CACd,UAAA,WAAqB,oBAAA,KACpB,WAAA;;iBASa,cAAA,WAAyB,oBAAA,CAAA,CACvC,UAAA,WAAqB,CAAA,IACrB,QAAA,GAAU,WAAA,UACV,OAAA,GAAO,WAAA,YAA+B,CAAA;;;iBAWxB,sBAAA,CACd,UAAA,WAAqB,oBAAA,IACrB,QAAA,GAAU,WAAA,WAA+B,GAAA;;iBAgB3B,uBAAA,CACd,MAAA,EAAQ,mBAAA,EACR,IAAA,EAAM,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA1HW;;;;;;;;;;;;;;;;;;SA8BC"}
@@ -17,25 +17,7 @@ const RESUME_ACCOUNTING_SPEC = {
17
17
  };
18
18
  const STOP_ACCOUNTING_SPEC = { totalOperation: "orchestrator.stop_complete" };
19
19
  const DELETE_ACCOUNTING_SPEC = { totalOperation: "orchestrator.delete_complete" };
20
- /**
21
- * A flat `{name: ms}` ledger read as the tree its names describe.
22
- *
23
- * Every producer in this repo emits nested stages FLAT, with the containment
24
- * in the name: `capture.<hostPhase>` and `capture.restic_<phase>` inside
25
- * `capture` (snapshot-helpers.ts), `materialize.parentRead|precreate|
26
- * branchComplete|host.*|child.*|residual` inside `materialize` (branch.ts),
27
- * `delete.<hostPhase>` inside `delete` and `restore_workspace.<phase>` inside
28
- * `restore_workspace` (snapshots.ts). Summing every entry as a sibling counts
29
- * the children inside their parent a second time and reports a wall the
30
- * orchestrator never spent.
31
- *
32
- * So a dotted name is NEVER top-level. It attaches to the longest prefix that
33
- * exists as a stage; when no prefix exists — the restore job's `host.<phase>`,
34
- * which the queue records inside `restore_workspace` without naming it
35
- * (snapshot-job-queue.ts:394) — it is still excluded from the top-level sum
36
- * and reported as a child of the ledger at large. Excluding it can only leave
37
- * MORE time unnamed, never fabricate a reconciliation.
38
- */
20
+ /** Longest present prefix owns a dotted stage; orphan detail never enters the root sum. */
39
21
  function stageTree(stages) {
40
22
  const present = new Set(Object.keys(stages));
41
23
  const parentOf = (name) => {
@@ -61,11 +43,22 @@ function stageTree(stages) {
61
43
  topLevelMs: topLevel.reduce((sum, node) => sum + node.ms, 0)
62
44
  };
63
45
  }
64
- /**
65
- * A response's span tree as `<stage>.<path>` rows and each parent's wall minus
66
- * its children as `<parent>.unattributed` (0 when children overlap), residuals
67
- * first so a capped header keeps them. Unparented spans nest in the total span.
68
- */
46
+ /** Parent minus its direct children; overlapping evidence never invents dark time. */
47
+ function unattributedStages(stages, parents) {
48
+ const out = {};
49
+ for (const [parent, children] of Object.entries(parents)) {
50
+ const wall = stages[parent];
51
+ if (wall === void 0 || !Number.isFinite(wall)) continue;
52
+ const named = new Set(children.flatMap((child) => {
53
+ if (!child.endsWith(".*")) return [child];
54
+ const prefix = child.slice(0, -1);
55
+ return Object.keys(stages).filter((name) => name.startsWith(prefix) && !name.slice(prefix.length).includes(".") && name !== `${parent}.unattributed`);
56
+ }));
57
+ out[`${parent}.unattributed`] = Math.max(0, [...named].reduce((left, name) => left - (stages[name] ?? 0), wall));
58
+ }
59
+ return out;
60
+ }
61
+ /** A response's span tree as `<stage>.<path>` rows and each parent's wall minus its children as `<parent>.unattributed` (0 when children overlap), residuals first so a capped header keeps them. Unparented spans nest in the total span. */
69
62
  function spanTreeStages(stage, stageMs, operations = [], spec) {
70
63
  const total = spec?.totalOperation ?? "";
71
64
  const byName = new Map(operations.map((op) => [op.operation, op]));
@@ -77,25 +70,14 @@ function spanTreeStages(stage, stageMs, operations = [], spec) {
77
70
  };
78
71
  const rows = { [stage]: stageMs[stage] ?? 0 };
79
72
  for (const { durationMs: ms, status, ...op } of operations) if (status === "completed" && typeof ms === "number" && ms >= 0) rows[path(op)] = (rows[path(op)] ?? 0) + ms;
80
- const residuals = {};
81
- for (const [parent, ms] of Object.entries(rows)) {
82
- const kids = Object.keys(rows).filter((name) => name.startsWith(`${parent}.`) && !name.slice(parent.length + 1).includes("."));
83
- if (kids.length) residuals[`${parent}.unattributed`] = Math.max(0, kids.reduce((rest, kid) => rest - (rows[kid] ?? 0), ms));
84
- }
73
+ const residuals = unattributedStages(rows, Object.fromEntries(Object.keys(rows).filter((parent) => Object.keys(rows).some((name) => name.startsWith(`${parent}.`) && !name.slice(parent.length + 1).includes("."))).map((parent) => [parent, [`${parent}.*`]])));
85
74
  delete rows[stage];
86
75
  return {
87
76
  ...residuals,
88
77
  ...rows
89
78
  };
90
79
  }
91
- /**
92
- * Hops that describe the SHAPE of the request rather than a slice of it: the
93
- * three nested walls, the transport the walls imply, and the retry counter.
94
- * They are the terms of the summary line, so ranking them again as sub-stages
95
- * would print the same milliseconds twice under a second name. `preHandler`
96
- * joins them because it is the umbrella over the `mw.*` own-times, which ARE
97
- * ranked.
98
- */
80
+ /** Hops that describe the SHAPE of the request rather than a slice of it: the three nested walls, the transport the walls imply, and the retry counter. */
99
81
  const SHAPE_HOPS = new Set([
100
82
  "preHandler",
101
83
  "total",
@@ -109,14 +91,7 @@ const SHAPE_HOPS = new Set([
109
91
  function parentOperations(operations) {
110
92
  return new Set(operations.flatMap((op) => typeof op.parent === "string" ? [op.parent] : []));
111
93
  }
112
- /**
113
- * The measured leaves of one response's span tree, per the flow's own spec.
114
- *
115
- * Identical rule to the orchestrator's `computeFlowAccountingResiduals`: drop
116
- * the total span (it is the window), drop the spans stamped after it closes,
117
- * and drop any span another span names as its parent (a parent re-measures its
118
- * children). What is left sums to the window minus its named residual.
119
- */
94
+ /** The measured leaves of one response's span tree, per the flow's own spec. */
120
95
  function leafOperations(operations, excluded = /* @__PURE__ */ new Set(), parents = parentOperations(operations)) {
121
96
  return operations.filter((op) => !excluded.has(op.operation) && !parents.has(op.operation) && typeof op.durationMs === "number" && Number.isFinite(op.durationMs));
122
97
  }
@@ -130,11 +105,7 @@ const positiveDifference = (a, b) => {
130
105
  const value = difference(a, b);
131
106
  return value === null ? null : Math.max(0, value);
132
107
  };
133
- /**
134
- * Partition one input before aggregation: null is unavailable; a negative
135
- * residual is overlapping evidence, never an instruction to publish zero.
136
- * Callers retain their population grouping, medians and display labels.
137
- */
108
+ /** Partition one input before aggregation: null is unavailable; a negative residual is overlapping evidence, never an instruction to publish zero. Callers retain their population grouping, medians and display labels. */
138
109
  function partitionLifecycleWalls(sample, flow) {
139
110
  const present = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
140
111
  const finiteStages = (values) => Object.fromEntries(Object.entries(values ?? {}).filter(([, ms]) => Number.isFinite(ms)));
@@ -223,6 +194,6 @@ function partitionLifecycleWalls(sample, flow) {
223
194
  };
224
195
  }
225
196
  //#endregion
226
- export { leafOperations as a, partitionLifecycleWalls as c, STOP_ACCOUNTING_SPEC as i, spanTreeStages as l, DELETE_ACCOUNTING_SPEC as n, operationLeafDurations as o, RESUME_ACCOUNTING_SPEC as r, parentOperations as s, CREATE_ACCOUNTING_SPEC as t, stageTree as u };
197
+ export { leafOperations as a, partitionLifecycleWalls as c, unattributedStages as d, STOP_ACCOUNTING_SPEC as i, spanTreeStages as l, DELETE_ACCOUNTING_SPEC as n, operationLeafDurations as o, RESUME_ACCOUNTING_SPEC as r, parentOperations as s, CREATE_ACCOUNTING_SPEC as t, stageTree as u };
227
198
 
228
- //# sourceMappingURL=lifecycle-wall-BeaxDTJ8.mjs.map
199
+ //# sourceMappingURL=lifecycle-wall-CVuGfuSq.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle-wall-CVuGfuSq.mjs","names":[],"sources":["../src/lifecycle-wall.ts"],"sourcesContent":["const CREATE_POST_READY_OPERATIONS = new Set([\n \"orchestrator.container_lookup\",\n \"orchestrator.snapshot_restore_check\",\n \"orchestrator.provision_finalize\",\n]);\n\n/** Per-flow shape of the accounting window. */\nexport type FlowAccountingSpec = {\n totalOperation: string;\n postReadyOperations?: ReadonlySet<string>;\n prepUmbrella?: { operation: string };\n};\n\nexport const CREATE_ACCOUNTING_SPEC: FlowAccountingSpec = {\n totalOperation: \"orchestrator.ready\",\n postReadyOperations: CREATE_POST_READY_OPERATIONS,\n prepUmbrella: {\n operation: \"orchestrator.provision_prep\",\n },\n};\n\nexport const RESUME_ACCOUNTING_SPEC: FlowAccountingSpec = {\n // `orchestrator.ready` runs from the request to the sidecar's ready stamp;\n // these run after that stamp.\n totalOperation: \"orchestrator.ready\",\n postReadyOperations: new Set([\n \"orchestrator.connection_build\",\n \"orchestrator.metering_restart\",\n \"orchestrator.resume_commit\",\n ]),\n};\n\nexport const STOP_ACCOUNTING_SPEC: FlowAccountingSpec = {\n totalOperation: \"orchestrator.stop_complete\",\n};\n\nexport const DELETE_ACCOUNTING_SPEC: FlowAccountingSpec = {\n totalOperation: \"orchestrator.delete_complete\",\n};\n\nexport interface LifecycleStageTiming {\n operation: string;\n durationMs?: number;\n parent?: string | null;\n}\ntype Values = Readonly<Record<string, number>>;\nexport interface LifecycleWallSample {\n wallMs: number;\n httpMs: number;\n hops?: Values;\n spanOps?: readonly LifecycleStageTiming[];\n spanLeaves?: Values;\n spanTotalMs?: number | null;\n orchStages?: Values | null;\n jobPhases?: Values | null;\n jobMs?: number | null;\n settleMs?: number | null;\n spanAccountedMs?: number;\n}\nexport interface LifecycleWallFlow extends Partial<FlowAccountingSpec> {\n workerTotalHop: string;\n addPreHandler: boolean;\n settleHop?: string;\n workerNamedHops?: readonly string[];\n}\n\n/** Longest present prefix owns a dotted stage; orphan detail never enters the root sum. */\nexport function stageTree(stages: Readonly<Record<string, number>>) {\n const present = new Set(Object.keys(stages));\n const parentOf = (name: string) => {\n let cut = name.lastIndexOf(\".\");\n while (cut > 0) {\n const candidate = name.slice(0, cut);\n if (present.has(candidate)) return candidate;\n cut = candidate.lastIndexOf(\".\");\n }\n return name.includes(\".\") ? \"\" : null;\n };\n const nodes = Object.entries(stages).map(([name, ms]) => ({\n name,\n ms,\n parent: parentOf(name),\n }));\n const topLevel = nodes.filter((node) => node.parent === null);\n return {\n nodes,\n topLevel,\n /** Children whose declared parent is not in the ledger; never summed. */\n orphans: nodes.filter((node) => node.parent === \"\"),\n topLevelMs: topLevel.reduce((sum, node) => sum + node.ms, 0),\n };\n}\n\n/** Parent minus its direct children; overlapping evidence never invents dark time. */\nexport function unattributedStages(\n stages: Readonly<Record<string, number>>,\n parents: Readonly<Record<string, readonly string[]>>,\n): Record<string, number> {\n const out: Record<string, number> = {};\n for (const [parent, children] of Object.entries(parents)) {\n const wall = stages[parent];\n if (wall === undefined || !Number.isFinite(wall)) continue;\n const named = new Set(\n children.flatMap((child) => {\n if (!child.endsWith(\".*\")) return [child];\n const prefix = child.slice(0, -1);\n return Object.keys(stages).filter(\n (name) =>\n name.startsWith(prefix) &&\n !name.slice(prefix.length).includes(\".\") &&\n name !== `${parent}.unattributed`,\n );\n }),\n );\n out[`${parent}.unattributed`] = Math.max(\n 0,\n [...named].reduce((left, name) => left - (stages[name] ?? 0), wall),\n );\n }\n return out;\n}\n\n/** A response's span tree as `<stage>.<path>` rows and each parent's wall minus its children as `<parent>.unattributed` (0 when children overlap), residuals first so a capped header keeps them. Unparented spans nest in the total span. */\nexport function spanTreeStages(\n stage: string,\n stageMs: Readonly<Record<string, number>>,\n operations: readonly (LifecycleStageTiming & { status?: string })[] = [],\n spec?: Partial<FlowAccountingSpec>,\n): Record<string, number> {\n const total = spec?.totalOperation ?? \"\";\n const byName = new Map(operations.map((op) => [op.operation, op]));\n const path = (op: LifecycleStageTiming, depth = 0): string => {\n const outside =\n op.operation === total || spec?.postReadyOperations?.has(op.operation);\n const parent = byName.get(op.parent ?? (outside ? \"\" : total));\n const name = op.operation.slice(op.operation.lastIndexOf(\".\") + 1);\n return `${parent && depth < 8 ? path(parent, depth + 1) : stage}.${name}`;\n };\n const rows: Record<string, number> = { [stage]: stageMs[stage] ?? 0 };\n for (const { durationMs: ms, status, ...op } of operations)\n if (status === \"completed\" && typeof ms === \"number\" && ms >= 0)\n rows[path(op)] = (rows[path(op)] ?? 0) + ms;\n const residuals = unattributedStages(\n rows,\n Object.fromEntries(\n Object.keys(rows)\n .filter((parent) =>\n Object.keys(rows).some(\n (name) =>\n name.startsWith(`${parent}.`) &&\n !name.slice(parent.length + 1).includes(\".\"),\n ),\n )\n .map((parent) => [parent, [`${parent}.*`]]),\n ),\n );\n delete rows[stage];\n return { ...residuals, ...rows };\n}\n\n/** Hops that describe the SHAPE of the request rather than a slice of it: the three nested walls, the transport the walls imply, and the retry counter. */\nconst SHAPE_HOPS = new Set([\n \"preHandler\",\n \"total\",\n \"serverWall\",\n \"orchestrator\",\n \"orchestratorServer\",\n \"transportMarkup\",\n \"orchestratorRetries\",\n]);\n\n/** Parent operations contain their descendants and are never counted as leaves. */\nexport function parentOperations(\n operations: readonly LifecycleStageTiming[],\n): ReadonlySet<string> {\n return new Set(\n operations.flatMap((op) =>\n typeof op.parent === \"string\" ? [op.parent] : [],\n ),\n );\n}\n\n/** The measured leaves of one response's span tree, per the flow's own spec. */\nexport function leafOperations<T extends LifecycleStageTiming>(\n operations: readonly T[],\n excluded: ReadonlySet<string> = new Set(),\n parents = parentOperations(operations),\n) {\n return operations.filter(\n (op): op is T & { durationMs: number } =>\n !excluded.has(op.operation) &&\n !parents.has(op.operation) &&\n typeof op.durationMs === \"number\" &&\n Number.isFinite(op.durationMs),\n );\n}\n\nexport function operationLeafDurations(\n operations: readonly LifecycleStageTiming[],\n excluded: ReadonlySet<string> = new Set(),\n) {\n const leaves = new Map<string, number>();\n for (const op of leafOperations(operations, excluded))\n leaves.set(op.operation, (leaves.get(op.operation) ?? 0) + op.durationMs);\n return leaves;\n}\n\nconst difference = (a: number | null, b: number | null) =>\n a === null || b === null ? null : a - b;\nconst positiveDifference = (a: number | null, b: number | null) => {\n const value = difference(a, b);\n return value === null ? null : Math.max(0, value);\n};\n\n/** Partition one input before aggregation: null is unavailable; a negative residual is overlapping evidence, never an instruction to publish zero. Callers retain their population grouping, medians and display labels. */\nexport function partitionLifecycleWalls(\n sample: LifecycleWallSample,\n flow: LifecycleWallFlow,\n) {\n const present = (value: number | null | undefined) =>\n typeof value === \"number\" && Number.isFinite(value) ? value : null;\n const finiteStages = (values?: Values | null) =>\n Object.fromEntries(\n Object.entries(values ?? {}).filter(([, ms]) => Number.isFinite(ms)),\n );\n const hops = sample.hops ?? {};\n const hop = (key: string) => present(hops[key]);\n const handler = hop(flow.workerTotalHop);\n const preHandler = hop(\"preHandler\");\n const hold = flow.settleHop ? (hop(flow.settleHop) ?? 0) : 0;\n const workerWallMs =\n handler === null\n ? null\n : Math.max(0, handler - hold) +\n (flow.addPreHandler ? (preHandler ?? 0) : 0);\n const roundTripMs = hop(\"orchestrator\");\n const orchServerMs = hop(\"orchestratorServer\");\n const orchWall = roundTripMs ?? orchServerMs;\n const terms = {\n edge: positiveDifference(sample.httpMs, workerWallMs),\n worker: positiveDifference(workerWallMs, orchWall ?? 0),\n transport: positiveDifference(roundTripMs, orchServerMs),\n orch: orchServerMs ?? roundTripMs,\n job: present(sample.jobMs),\n settle: present(sample.settleMs),\n dark: 0,\n };\n terms.dark =\n sample.wallMs -\n Object.values(terms).reduce<number>((sum, ms) => sum + (ms ?? 0), 0);\n const postReady = flow.postReadyOperations ?? new Set();\n const rawLeaves =\n sample.spanLeaves ??\n Object.fromEntries(operationLeafDurations(sample.spanOps ?? []));\n const spanLeaves = Object.fromEntries(\n Object.entries(rawLeaves).filter(\n ([name, ms]) =>\n name !== flow.totalOperation &&\n !postReady.has(name) &&\n Number.isFinite(ms),\n ),\n );\n // Exclude nested walls, transport and middleware outside the handler's total.\n const workerStages = Object.fromEntries(\n Object.entries(hops).filter(\n ([name]) =>\n Number.isFinite(hops[name]) &&\n !SHAPE_HOPS.has(name) &&\n name !== flow.settleHop &&\n !name.startsWith(\"orch.\") &&\n !name.startsWith(\"mw.\"),\n ),\n );\n const orchTree = stageTree(finiteStages(sample.orchStages));\n const jobTree = stageTree(finiteStages(sample.jobPhases));\n const spanSum = Object.values(spanLeaves).reduce((sum, ms) => sum + ms, 0);\n const workerNamed =\n (flow.addPreHandler ? (preHandler ?? 0) : 0) +\n (flow.workerNamedHops\n ? flow.workerNamedHops.reduce((sum, key) => sum + (hop(key) ?? 0), 0)\n : stageTree(workerStages).topLevelMs);\n const workerUnattributedMs = difference(terms.worker, workerNamed);\n const orchNamed = orchTree.topLevel.length\n ? orchTree.topLevelMs\n : spanSum > 0\n ? spanSum\n : 0;\n const orchUnattributedMs = difference(terms.orch, orchNamed);\n const jobUnattributedMs = difference(terms.job, jobTree.topLevelMs);\n const unnamedMs =\n Math.max(0, workerUnattributedMs ?? terms.worker ?? 0) +\n Math.max(0, orchUnattributedMs ?? terms.orch ?? 0) +\n Math.max(0, jobUnattributedMs ?? terms.job ?? 0) +\n Math.max(0, terms.dark);\n const measuredTotal = (sample.spanOps ?? []).find(\n (op) => op.operation === flow.totalOperation,\n )?.durationMs;\n const spanTotalMs = present(sample.spanTotalMs ?? measuredTotal);\n const readySum = sample.spanAccountedMs ?? spanSum;\n const readyTerm = spanTotalMs ?? readySum;\n const orchTerm = roundTripMs ?? orchServerMs ?? readyTerm;\n let clampedMs = 0;\n const diff = (a: number | null, b: number | null) => {\n const delta = difference(a, b);\n if (delta === null) return null;\n clampedMs += Math.max(0, -delta);\n return Math.max(0, delta);\n };\n const transportMs = diff(roundTripMs, orchServerMs);\n const afterSpanMs = diff(orchServerMs, spanTotalMs);\n const pathSum = workerNamed + orchTerm;\n const outerMs =\n workerWallMs === null\n ? diff(\n sample.wallMs - readyTerm,\n workerNamed + (transportMs ?? 0) + (afterSpanMs ?? 0),\n )\n : diff(sample.wallMs, workerWallMs);\n const window = {\n transportMs,\n afterSpanMs,\n outerMs,\n workerUnattributedMs: positiveDifference(workerWallMs, pathSum),\n workerOwnMs: positiveDifference(workerWallMs, orchTerm),\n gaps: {\n overlapMs: positiveDifference(readySum, spanTotalMs) ?? 0,\n underTileMs: positiveDifference(spanTotalMs, readySum) ?? 0,\n workerOverlapMs: positiveDifference(pathSum, workerWallMs) ?? 0,\n unrowedMs:\n workerWallMs === null\n ? 0\n : Math.max(\n 0,\n orchTerm - readyTerm - (transportMs ?? 0) - (afterSpanMs ?? 0),\n ),\n clampedMs,\n },\n };\n return {\n wallMs: sample.wallMs,\n httpMs: sample.httpMs,\n workerWallMs,\n roundTripMs,\n orchServerMs,\n orchIncludesTransport: orchServerMs === null && roundTripMs !== null,\n workerIncludesTransport: roundTripMs === null && orchServerMs !== null,\n terms,\n workerUnattributedMs,\n orchUnattributedMs,\n jobUnattributedMs,\n unnamedMs,\n unnamedShare: sample.wallMs > 0 ? unnamedMs / sample.wallMs : 0,\n overcountMs: Math.max(0, -terms.dark),\n spanLeaves,\n workerStages,\n orchTree,\n jobTree,\n spanTotalMs,\n window,\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { a as LifecycleWallSample, d as partitionLifecycleWalls, i as LifecycleWallFlow } from "./lifecycle-wall-BnN-KFBx.mjs";
1
+ import { a as LifecycleWallSample, d as partitionLifecycleWalls, i as LifecycleWallFlow, m as unattributedStages } from "./lifecycle-wall-BL6-gCBp.mjs";
2
2
 
3
3
  //#region src/create-wall.d.ts
4
4
  /** Exclusive create-request wall phases; nested service spans are a separate view. */
@@ -8,10 +8,9 @@ type CreateWallPhases = Record<CreateWallPhase, number>;
8
8
  interface CreateWallMeasurement {
9
9
  phases: CreateWallPhases;
10
10
  totalMs: number;
11
- /** Includes middleware/auth, preserving the original bookkeeping + post budget. */
11
+ offsets?: Record<string, number | null>;
12
12
  bookkeepingPostCreateMs: number;
13
13
  }
14
- /** The original other-Worker + post-create budget, including auth/middleware. */
15
14
  declare function createBookkeepingPostWall(phases: CreateWallPhases): number;
16
15
  /** Sequential cursor; parallel spans stay separate. Invalid or incomplete walls stay unknown. */
17
16
  declare function createWallTiming(startedAt: number): {
@@ -48,5 +47,5 @@ declare const FAILURE_FACT_NAMES: readonly string[];
48
47
  declare const FAILURE_FACT_CODES: readonly string[];
49
48
  declare const FAILURE_FACT_KINDS: readonly string[];
50
49
  //#endregion
51
- export { CREATE_WALL_PHASES, type CreateWallMeasurement, type CreateWallPhase, type CreateWallPhases, FAILURE_FACT_CODES, FAILURE_FACT_KINDS, FAILURE_FACT_NAMES, HTTP_PHASE_COVERAGE_FIELDS, HTTP_REQUEST_PHASE_NAMES, type HttpRequestPhaseName, type LifecycleWallFlow, type LifecycleWallSample, PLATFORM_VERDICT_EVIDENCE_ORDERS, PLATFORM_VERDICT_REUSE_REASONS, PLATFORM_VERDICT_SCOPE_CLASSES, type PlatformVerdictDependencyMismatch, type PlatformVerdictReuseRejection, type ServerTimingEntry, createBookkeepingPostWall, createUpstreamHttpPhaseProjection, createWallTiming, parseServerTiming, parseServerTimingDurations, partitionLifecycleWalls, readCreateWallTiming };
50
+ export { CREATE_WALL_PHASES, type CreateWallMeasurement, type CreateWallPhase, type CreateWallPhases, FAILURE_FACT_CODES, FAILURE_FACT_KINDS, FAILURE_FACT_NAMES, HTTP_PHASE_COVERAGE_FIELDS, HTTP_REQUEST_PHASE_NAMES, type HttpRequestPhaseName, type LifecycleWallFlow, type LifecycleWallSample, PLATFORM_VERDICT_EVIDENCE_ORDERS, PLATFORM_VERDICT_REUSE_REASONS, PLATFORM_VERDICT_SCOPE_CLASSES, type PlatformVerdictDependencyMismatch, type PlatformVerdictReuseRejection, type ServerTimingEntry, createBookkeepingPostWall, createUpstreamHttpPhaseProjection, createWallTiming, parseServerTiming, parseServerTimingDurations, partitionLifecycleWalls, readCreateWallTiming, unattributedStages };
52
51
  //# sourceMappingURL=server-timing.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-timing.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","FAILURE_FACT_NAMES","FAILURE_FACT_CODES","FAILURE_FACT_KINDS"],"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;EANQ;EAQR,uBAAA;AAAA;;iBAWc,yBAAA,CAA0B,MAAA,EAAQ,gBAAA;;iBAUlC,gBAAA,CAAiB,SAAA;cAUjB,eAAA,EAAe,EAAA;6BAWP,WAAA,WAEjB,qBAAA;AAAA;;iBA6BS,oBAAA,CACd,MAAA,EAAQ,QAAA,CAAS,MAAA,oBAChB,qBAAA;;;UCnGcA,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,KAkCDC,oBAAAA,WAA+BD,wBAAAA;AAAAA,cAI9BG,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;AAAAA,cAQAC,kBAAAA;AAAAA,cACAC,kBAAAA;AAAAA,cACAC,kBAAAA"}
1
+ {"version":3,"file":"server-timing.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","FAILURE_FACT_NAMES","FAILURE_FACT_CODES","FAILURE_FACT_KINDS"],"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;EACA,OAAA,GAAU,MAAA;EACV,uBAAA;AAAA;AAAA,iBAUc,yBAAA,CAA0B,MAAA,EAAQ,gBAAA;;iBAUlC,gBAAA,CAAiB,SAAA;cAajB,eAAA,EAAe,EAAA;6BAYP,WAAA,WAEjB,qBAAA;AAAA;;iBAsCS,oBAAA,CACd,MAAA,EAAQ,QAAA,CAAS,MAAA,oBAChB,qBAAA;;;UC/GcA,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,KAkCDC,oBAAAA,WAA+BD,wBAAAA;AAAAA,cAI9BG,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;AAAAA,cAQAC,kBAAAA;AAAAA,cACAC,kBAAAA;AAAAA,cACAC,kBAAAA"}
@@ -1,4 +1,4 @@
1
- import { c as partitionLifecycleWalls } from "./lifecycle-wall-BeaxDTJ8.mjs";
1
+ import { c as partitionLifecycleWalls, d as unattributedStages } from "./lifecycle-wall-CVuGfuSq.mjs";
2
2
  //#region src/create-wall.ts
3
3
  /** Exclusive create-request wall phases; nested service spans are a separate view. */
4
4
  const CREATE_WALL_PHASES = [
@@ -18,7 +18,6 @@ const CREATE_WALL_PHASES = [
18
18
  "response"
19
19
  ];
20
20
  const REQUIRED_PHASES = CREATE_WALL_PHASES.filter((phase) => phase !== "middleware" && phase !== "leaseSelection" && phase !== "tenantCoordination");
21
- /** The original other-Worker + post-create budget, including auth/middleware. */
22
21
  function createBookkeepingPostWall(phases) {
23
22
  return CREATE_WALL_PHASES.reduce((sum, phase) => sum + (phase === "preflight" || phase === "orchestrator" ? 0 : phases[phase]), 0);
24
23
  }
@@ -28,6 +27,7 @@ function createWallTiming(startedAt) {
28
27
  const visited = new Set(["identity"]);
29
28
  let current = "identity";
30
29
  let cursor = startedAt;
30
+ const starts = { identity: startedAt };
31
31
  let valid = Number.isFinite(startedAt);
32
32
  let finished = false;
33
33
  return {
@@ -38,6 +38,7 @@ function createWallTiming(startedAt) {
38
38
  }
39
39
  phases[current] += at - cursor;
40
40
  cursor = at;
41
+ if (current !== name) starts[name] = visited.has(name) ? null : at;
41
42
  current = name;
42
43
  visited.add(name);
43
44
  },
@@ -54,6 +55,7 @@ function createWallTiming(startedAt) {
54
55
  return {
55
56
  phases: { ...phases },
56
57
  totalMs,
58
+ offsets: Object.fromEntries([["createWall.total", 0], ...CREATE_WALL_PHASES.map((phase) => [`createWall.${phase}`, starts[phase] === null ? null : (starts[phase] ?? receivedAt) - receivedAt])]),
57
59
  bookkeepingPostCreateMs: createBookkeepingPostWall(phases)
58
60
  };
59
61
  }
@@ -298,7 +300,7 @@ function createUpstreamHttpPhaseProjection() {
298
300
  dropped++;
299
301
  continue;
300
302
  }
301
- keep(`orch.${entry.name};dur=${Math.round(entry.dur)};desc="${entry.desc}"`);
303
+ keep(`orch.${entry.name};dur=${entry.dur};desc="${entry.desc}"`);
302
304
  }
303
305
  },
304
306
  entries() {
@@ -307,6 +309,6 @@ function createUpstreamHttpPhaseProjection() {
307
309
  };
308
310
  }
309
311
  //#endregion
310
- export { CREATE_WALL_PHASES, FAILURE_FACT_CODES, FAILURE_FACT_KINDS, FAILURE_FACT_NAMES, HTTP_PHASE_COVERAGE_FIELDS, HTTP_REQUEST_PHASE_NAMES, PLATFORM_VERDICT_EVIDENCE_ORDERS, PLATFORM_VERDICT_REUSE_REASONS, PLATFORM_VERDICT_SCOPE_CLASSES, createBookkeepingPostWall, createUpstreamHttpPhaseProjection, createWallTiming, parseServerTiming, parseServerTimingDurations, partitionLifecycleWalls, readCreateWallTiming };
312
+ export { CREATE_WALL_PHASES, FAILURE_FACT_CODES, FAILURE_FACT_KINDS, FAILURE_FACT_NAMES, HTTP_PHASE_COVERAGE_FIELDS, HTTP_REQUEST_PHASE_NAMES, PLATFORM_VERDICT_EVIDENCE_ORDERS, PLATFORM_VERDICT_REUSE_REASONS, PLATFORM_VERDICT_SCOPE_CLASSES, createBookkeepingPostWall, createUpstreamHttpPhaseProjection, createWallTiming, parseServerTiming, parseServerTimingDurations, partitionLifecycleWalls, readCreateWallTiming, unattributedStages };
311
313
 
312
314
  //# sourceMappingURL=server-timing.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-timing.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/** Sequential cursor; parallel spans stay separate. Invalid or incomplete walls stay unknown. */\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 (\n totalMs === undefined ||\n !Number.isFinite(totalMs) ||\n totalMs < 0 ||\n totalMs !== stages.outerWall\n )\n return null;\n const phases = {} as CreateWallPhases;\n for (const phase of CREATE_WALL_PHASES) {\n const value = stages[`createWall.${phase}`];\n if (value === undefined || !Number.isFinite(value) || value < 0)\n 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 \"host.records.ready\",\n \"host.records.scan\",\n \"host.records.read\",\n \"host.records.metadata\",\n \"host.records.project\",\n \"host.records.retry\",\n \"admission.placement\",\n \"observability.refresh.wait\",\n \"fleet.sidecars\",\n \"native-export.snapshot.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/** Closed failure facts: thrown values can carry credentials or URLs, so only these names leave. */\nexport const FAILURE_FACT_NAMES = Object.freeze([\n \"Error\",\n \"TypeError\",\n \"AbortError\",\n \"TimeoutError\",\n \"RangeError\",\n \"Other\",\n]);\nexport const FAILURE_FACT_CODES = Object.freeze([\n \"ECONNRESET\",\n \"ECONNREFUSED\",\n \"ECONNABORTED\",\n \"ETIMEDOUT\",\n \"EPIPE\",\n \"ENOTFOUND\",\n \"EAI_AGAIN\",\n \"ENETUNREACH\",\n \"EHOSTUNREACH\",\n \"ENETDOWN\",\n \"EADDRNOTAVAIL\",\n \"UND_ERR_CONNECT_TIMEOUT\",\n \"UND_ERR_HEADERS_TIMEOUT\",\n \"UND_ERR_BODY_TIMEOUT\",\n \"UND_ERR_SOCKET\",\n \"UND_ERR_ABORTED\",\n]);\nexport const FAILURE_FACT_KINDS = Object.freeze([\n \"request-context\",\n \"connection-lost\",\n \"fetch-failed\",\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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"}
1
+ {"version":3,"file":"server-timing.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 offsets?: Record<string, number | null>;\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\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/** Sequential cursor; parallel spans stay separate. Invalid or incomplete walls stay unknown. */\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 const starts: Partial<Record<CreateWallPhase, number | null>> = {\n identity: startedAt,\n };\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 if (current !== name) starts[name] = visited.has(name) ? null : 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 offsets: Object.fromEntries([\n [\"createWall.total\", 0],\n ...CREATE_WALL_PHASES.map((phase) => [\n `createWall.${phase}`,\n starts[phase] === null\n ? null\n : (starts[phase] ?? receivedAt) - receivedAt,\n ]),\n ]),\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 (\n totalMs === undefined ||\n !Number.isFinite(totalMs) ||\n totalMs < 0 ||\n totalMs !== stages.outerWall\n )\n return null;\n const phases = {} as CreateWallPhases;\n for (const phase of CREATE_WALL_PHASES) {\n const value = stages[`createWall.${phase}`];\n if (value === undefined || !Number.isFinite(value) || value < 0)\n 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 \"host.records.ready\",\n \"host.records.scan\",\n \"host.records.read\",\n \"host.records.metadata\",\n \"host.records.project\",\n \"host.records.retry\",\n \"admission.placement\",\n \"observability.refresh.wait\",\n \"fleet.sidecars\",\n \"native-export.snapshot.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/** Closed failure facts: thrown values can carry credentials or URLs, so only these names leave. */\nexport const FAILURE_FACT_NAMES = Object.freeze([\n \"Error\",\n \"TypeError\",\n \"AbortError\",\n \"TimeoutError\",\n \"RangeError\",\n \"Other\",\n]);\nexport const FAILURE_FACT_CODES = Object.freeze([\n \"ECONNRESET\",\n \"ECONNREFUSED\",\n \"ECONNABORTED\",\n \"ETIMEDOUT\",\n \"EPIPE\",\n \"ENOTFOUND\",\n \"EAI_AGAIN\",\n \"ENETUNREACH\",\n \"EHOSTUNREACH\",\n \"ENETDOWN\",\n \"EADDRNOTAVAIL\",\n \"UND_ERR_CONNECT_TIMEOUT\",\n \"UND_ERR_HEADERS_TIMEOUT\",\n \"UND_ERR_BODY_TIMEOUT\",\n \"UND_ERR_SOCKET\",\n \"UND_ERR_ABORTED\",\n]);\nexport const FAILURE_FACT_KINDS = Object.freeze([\n \"request-context\",\n \"connection-lost\",\n \"fetch-failed\",\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(`orch.${entry.name};dur=${entry.dur};desc=\"${entry.desc}\"`);\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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"}
@@ -1,4 +1,4 @@
1
- import { c as leafOperations, f as spanTreeStages, l as operationLeafDurations, n as DELETE_ACCOUNTING_SPEC, o as RESUME_ACCOUNTING_SPEC, p as stageTree, r as FlowAccountingSpec, s as STOP_ACCOUNTING_SPEC, t as CREATE_ACCOUNTING_SPEC, u as parentOperations } from "./lifecycle-wall-BnN-KFBx.mjs";
1
+ import { c as leafOperations, f as spanTreeStages, l as operationLeafDurations, n as DELETE_ACCOUNTING_SPEC, o as RESUME_ACCOUNTING_SPEC, p as stageTree, r as FlowAccountingSpec, s as STOP_ACCOUNTING_SPEC, t as CREATE_ACCOUNTING_SPEC, u as parentOperations } from "./lifecycle-wall-BL6-gCBp.mjs";
2
2
 
3
3
  //#region src/stage-span.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { a as leafOperations, i as STOP_ACCOUNTING_SPEC, l as spanTreeStages, n as DELETE_ACCOUNTING_SPEC, o as operationLeafDurations, r as RESUME_ACCOUNTING_SPEC, s as parentOperations, t as CREATE_ACCOUNTING_SPEC, u as stageTree } from "./lifecycle-wall-BeaxDTJ8.mjs";
1
+ import { a as leafOperations, i as STOP_ACCOUNTING_SPEC, l as spanTreeStages, n as DELETE_ACCOUNTING_SPEC, o as operationLeafDurations, r as RESUME_ACCOUNTING_SPEC, s as parentOperations, t as CREATE_ACCOUNTING_SPEC, u as stageTree } from "./lifecycle-wall-CVuGfuSq.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.7.10",
3
+ "version": "0.7.12",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -70,8 +70,8 @@
70
70
  }
71
71
  },
72
72
  "tangleRelease": {
73
- "sourceSha": "72e7f17f94d9512ecaca0d9b938c582954362a4a",
74
- "mergedAt": "2026-11-05T14:42:53-08:00"
73
+ "sourceSha": "51165f630f81927a6819ea6dd4a71a5cf75c3241",
74
+ "mergedAt": "2026-11-06T06:41:07-08:00"
75
75
  },
76
76
  "scripts": {
77
77
  "build": "tsdown",
@@ -1 +0,0 @@
1
- {"version":3,"file":"lifecycle-wall-BeaxDTJ8.mjs","names":[],"sources":["../src/lifecycle-wall.ts"],"sourcesContent":["/**\n * The `ready` span carries the end-to-end create wall (caller start → the end\n * of createSidecar). These operations run AFTER `ready` is stamped, so they sit\n * OUTSIDE the ready window and must never be summed into the leaf total or the\n * residual goes negative.\n */\nconst CREATE_POST_READY_OPERATIONS = new Set([\n \"orchestrator.container_lookup\",\n \"orchestrator.snapshot_restore_check\",\n \"orchestrator.provision_finalize\",\n]);\n\n/**\n * Per-flow shape of the accounting window. `totalOperation` is the span whose\n * wall the named leaves must tile; `postReadyOperations` run AFTER it is\n * stamped (excluded from the leaf sum); `prepUmbrella` is the optional\n * create-style split of an entry umbrella minus its measured leaf children. Absent\n * `prepUmbrella` ⇒ `prepUnaccountedMs` is always 0 and the whole dark falls\n * into `unaccountedMs` (the shape every non-create flow uses).\n */\nexport type FlowAccountingSpec = {\n totalOperation: string;\n postReadyOperations?: ReadonlySet<string>;\n prepUmbrella?: { operation: string };\n};\n\nexport const CREATE_ACCOUNTING_SPEC: FlowAccountingSpec = {\n totalOperation: \"orchestrator.ready\",\n postReadyOperations: CREATE_POST_READY_OPERATIONS,\n prepUmbrella: {\n operation: \"orchestrator.provision_prep\",\n },\n};\n\nexport const RESUME_ACCOUNTING_SPEC: FlowAccountingSpec = {\n // `orchestrator.ready` runs from the request to the sidecar's ready stamp;\n // these run after that stamp.\n totalOperation: \"orchestrator.ready\",\n postReadyOperations: new Set([\n \"orchestrator.connection_build\",\n \"orchestrator.metering_restart\",\n \"orchestrator.resume_commit\",\n ]),\n};\n\nexport const STOP_ACCOUNTING_SPEC: FlowAccountingSpec = {\n totalOperation: \"orchestrator.stop_complete\",\n};\n\nexport const DELETE_ACCOUNTING_SPEC: FlowAccountingSpec = {\n totalOperation: \"orchestrator.delete_complete\",\n};\n\nexport interface LifecycleStageTiming {\n operation: string;\n durationMs?: number;\n parent?: string | null;\n}\ntype Values = Readonly<Record<string, number>>;\nexport interface LifecycleWallSample {\n wallMs: number;\n httpMs: number;\n hops?: Values;\n spanOps?: readonly LifecycleStageTiming[];\n spanLeaves?: Values;\n spanTotalMs?: number | null;\n orchStages?: Values | null;\n jobPhases?: Values | null;\n jobMs?: number | null;\n settleMs?: number | null;\n spanAccountedMs?: number;\n}\nexport interface LifecycleWallFlow extends Partial<FlowAccountingSpec> {\n workerTotalHop: string;\n addPreHandler: boolean;\n settleHop?: string;\n workerNamedHops?: readonly string[];\n}\n\n/**\n * A flat `{name: ms}` ledger read as the tree its names describe.\n *\n * Every producer in this repo emits nested stages FLAT, with the containment\n * in the name: `capture.<hostPhase>` and `capture.restic_<phase>` inside\n * `capture` (snapshot-helpers.ts), `materialize.parentRead|precreate|\n * branchComplete|host.*|child.*|residual` inside `materialize` (branch.ts),\n * `delete.<hostPhase>` inside `delete` and `restore_workspace.<phase>` inside\n * `restore_workspace` (snapshots.ts). Summing every entry as a sibling counts\n * the children inside their parent a second time and reports a wall the\n * orchestrator never spent.\n *\n * So a dotted name is NEVER top-level. It attaches to the longest prefix that\n * exists as a stage; when no prefix exists — the restore job's `host.<phase>`,\n * which the queue records inside `restore_workspace` without naming it\n * (snapshot-job-queue.ts:394) — it is still excluded from the top-level sum\n * and reported as a child of the ledger at large. Excluding it can only leave\n * MORE time unnamed, never fabricate a reconciliation.\n */\nexport function stageTree(stages: Readonly<Record<string, number>>) {\n const present = new Set(Object.keys(stages));\n const parentOf = (name: string) => {\n let cut = name.lastIndexOf(\".\");\n while (cut > 0) {\n const candidate = name.slice(0, cut);\n if (present.has(candidate)) return candidate;\n cut = candidate.lastIndexOf(\".\");\n }\n return name.includes(\".\") ? \"\" : null;\n };\n const nodes = Object.entries(stages).map(([name, ms]) => ({\n name,\n ms,\n parent: parentOf(name),\n }));\n const topLevel = nodes.filter((node) => node.parent === null);\n return {\n nodes,\n topLevel,\n /** Children whose declared parent is not in the ledger; never summed. */\n orphans: nodes.filter((node) => node.parent === \"\"),\n topLevelMs: topLevel.reduce((sum, node) => sum + node.ms, 0),\n };\n}\n\n/**\n * A response's span tree as `<stage>.<path>` rows and each parent's wall minus\n * its children as `<parent>.unattributed` (0 when children overlap), residuals\n * first so a capped header keeps them. Unparented spans nest in the total span.\n */\nexport function spanTreeStages(\n stage: string,\n stageMs: Readonly<Record<string, number>>,\n operations: readonly (LifecycleStageTiming & { status?: string })[] = [],\n spec?: Partial<FlowAccountingSpec>,\n): Record<string, number> {\n const total = spec?.totalOperation ?? \"\";\n const byName = new Map(operations.map((op) => [op.operation, op]));\n const path = (op: LifecycleStageTiming, depth = 0): string => {\n const outside =\n op.operation === total || spec?.postReadyOperations?.has(op.operation);\n const parent = byName.get(op.parent ?? (outside ? \"\" : total));\n const name = op.operation.slice(op.operation.lastIndexOf(\".\") + 1);\n return `${parent && depth < 8 ? path(parent, depth + 1) : stage}.${name}`;\n };\n const rows: Record<string, number> = { [stage]: stageMs[stage] ?? 0 };\n for (const { durationMs: ms, status, ...op } of operations)\n if (status === \"completed\" && typeof ms === \"number\" && ms >= 0)\n rows[path(op)] = (rows[path(op)] ?? 0) + ms;\n const residuals: Record<string, number> = {};\n for (const [parent, ms] of Object.entries(rows)) {\n const kids = Object.keys(rows).filter(\n (name) =>\n name.startsWith(`${parent}.`) &&\n !name.slice(parent.length + 1).includes(\".\"),\n );\n if (kids.length)\n residuals[`${parent}.unattributed`] = Math.max(\n 0,\n kids.reduce((rest, kid) => rest - (rows[kid] ?? 0), ms),\n );\n }\n delete rows[stage];\n return { ...residuals, ...rows };\n}\n\n/**\n * Hops that describe the SHAPE of the request rather than a slice of it: the\n * three nested walls, the transport the walls imply, and the retry counter.\n * They are the terms of the summary line, so ranking them again as sub-stages\n * would print the same milliseconds twice under a second name. `preHandler`\n * joins them because it is the umbrella over the `mw.*` own-times, which ARE\n * ranked.\n */\nconst SHAPE_HOPS = new Set([\n \"preHandler\",\n \"total\",\n \"serverWall\",\n \"orchestrator\",\n \"orchestratorServer\",\n \"transportMarkup\",\n \"orchestratorRetries\",\n]);\n\n/** Parent operations contain their descendants and are never counted as leaves. */\nexport function parentOperations(\n operations: readonly LifecycleStageTiming[],\n): ReadonlySet<string> {\n return new Set(\n operations.flatMap((op) =>\n typeof op.parent === \"string\" ? [op.parent] : [],\n ),\n );\n}\n\n/**\n * The measured leaves of one response's span tree, per the flow's own spec.\n *\n * Identical rule to the orchestrator's `computeFlowAccountingResiduals`: drop\n * the total span (it is the window), drop the spans stamped after it closes,\n * and drop any span another span names as its parent (a parent re-measures its\n * children). What is left sums to the window minus its named residual.\n */\nexport function leafOperations<T extends LifecycleStageTiming>(\n operations: readonly T[],\n excluded: ReadonlySet<string> = new Set(),\n parents = parentOperations(operations),\n) {\n return operations.filter(\n (op): op is T & { durationMs: number } =>\n !excluded.has(op.operation) &&\n !parents.has(op.operation) &&\n typeof op.durationMs === \"number\" &&\n Number.isFinite(op.durationMs),\n );\n}\n\nexport function operationLeafDurations(\n operations: readonly LifecycleStageTiming[],\n excluded: ReadonlySet<string> = new Set(),\n) {\n const leaves = new Map<string, number>();\n for (const op of leafOperations(operations, excluded))\n leaves.set(op.operation, (leaves.get(op.operation) ?? 0) + op.durationMs);\n return leaves;\n}\n\nconst difference = (a: number | null, b: number | null) =>\n a === null || b === null ? null : a - b;\nconst positiveDifference = (a: number | null, b: number | null) => {\n const value = difference(a, b);\n return value === null ? null : Math.max(0, value);\n};\n\n/**\n * Partition one input before aggregation: null is unavailable; a negative\n * residual is overlapping evidence, never an instruction to publish zero.\n * Callers retain their population grouping, medians and display labels.\n */\nexport function partitionLifecycleWalls(\n sample: LifecycleWallSample,\n flow: LifecycleWallFlow,\n) {\n const present = (value: number | null | undefined) =>\n typeof value === \"number\" && Number.isFinite(value) ? value : null;\n const finiteStages = (values?: Values | null) =>\n Object.fromEntries(\n Object.entries(values ?? {}).filter(([, ms]) => Number.isFinite(ms)),\n );\n const hops = sample.hops ?? {};\n const hop = (key: string) => present(hops[key]);\n const handler = hop(flow.workerTotalHop);\n const preHandler = hop(\"preHandler\");\n const hold = flow.settleHop ? (hop(flow.settleHop) ?? 0) : 0;\n const workerWallMs =\n handler === null\n ? null\n : Math.max(0, handler - hold) +\n (flow.addPreHandler ? (preHandler ?? 0) : 0);\n const roundTripMs = hop(\"orchestrator\");\n const orchServerMs = hop(\"orchestratorServer\");\n const orchWall = roundTripMs ?? orchServerMs;\n const terms = {\n edge: positiveDifference(sample.httpMs, workerWallMs),\n worker: positiveDifference(workerWallMs, orchWall ?? 0),\n transport: positiveDifference(roundTripMs, orchServerMs),\n orch: orchServerMs ?? roundTripMs,\n job: present(sample.jobMs),\n settle: present(sample.settleMs),\n dark: 0,\n };\n terms.dark =\n sample.wallMs -\n Object.values(terms).reduce<number>((sum, ms) => sum + (ms ?? 0), 0);\n const postReady = flow.postReadyOperations ?? new Set();\n const rawLeaves =\n sample.spanLeaves ??\n Object.fromEntries(operationLeafDurations(sample.spanOps ?? []));\n const spanLeaves = Object.fromEntries(\n Object.entries(rawLeaves).filter(\n ([name, ms]) =>\n name !== flow.totalOperation &&\n !postReady.has(name) &&\n Number.isFinite(ms),\n ),\n );\n // Exclude nested walls, transport and middleware outside the handler's total.\n const workerStages = Object.fromEntries(\n Object.entries(hops).filter(\n ([name]) =>\n Number.isFinite(hops[name]) &&\n !SHAPE_HOPS.has(name) &&\n name !== flow.settleHop &&\n !name.startsWith(\"orch.\") &&\n !name.startsWith(\"mw.\"),\n ),\n );\n const orchTree = stageTree(finiteStages(sample.orchStages));\n const jobTree = stageTree(finiteStages(sample.jobPhases));\n const spanSum = Object.values(spanLeaves).reduce((sum, ms) => sum + ms, 0);\n const workerNamed =\n (flow.addPreHandler ? (preHandler ?? 0) : 0) +\n (flow.workerNamedHops\n ? flow.workerNamedHops.reduce((sum, key) => sum + (hop(key) ?? 0), 0)\n : stageTree(workerStages).topLevelMs);\n const workerUnattributedMs = difference(terms.worker, workerNamed);\n const orchNamed = orchTree.topLevel.length\n ? orchTree.topLevelMs\n : spanSum > 0\n ? spanSum\n : 0;\n const orchUnattributedMs = difference(terms.orch, orchNamed);\n const jobUnattributedMs = difference(terms.job, jobTree.topLevelMs);\n const unnamedMs =\n Math.max(0, workerUnattributedMs ?? terms.worker ?? 0) +\n Math.max(0, orchUnattributedMs ?? terms.orch ?? 0) +\n Math.max(0, jobUnattributedMs ?? terms.job ?? 0) +\n Math.max(0, terms.dark);\n const measuredTotal = (sample.spanOps ?? []).find(\n (op) => op.operation === flow.totalOperation,\n )?.durationMs;\n const spanTotalMs = present(sample.spanTotalMs ?? measuredTotal);\n const readySum = sample.spanAccountedMs ?? spanSum;\n const readyTerm = spanTotalMs ?? readySum;\n const orchTerm = roundTripMs ?? orchServerMs ?? readyTerm;\n let clampedMs = 0;\n const diff = (a: number | null, b: number | null) => {\n const delta = difference(a, b);\n if (delta === null) return null;\n clampedMs += Math.max(0, -delta);\n return Math.max(0, delta);\n };\n const transportMs = diff(roundTripMs, orchServerMs);\n const afterSpanMs = diff(orchServerMs, spanTotalMs);\n const pathSum = workerNamed + orchTerm;\n const outerMs =\n workerWallMs === null\n ? diff(\n sample.wallMs - readyTerm,\n workerNamed + (transportMs ?? 0) + (afterSpanMs ?? 0),\n )\n : diff(sample.wallMs, workerWallMs);\n const window = {\n transportMs,\n afterSpanMs,\n outerMs,\n workerUnattributedMs: positiveDifference(workerWallMs, pathSum),\n workerOwnMs: positiveDifference(workerWallMs, orchTerm),\n gaps: {\n overlapMs: positiveDifference(readySum, spanTotalMs) ?? 0,\n underTileMs: positiveDifference(spanTotalMs, readySum) ?? 0,\n workerOverlapMs: positiveDifference(pathSum, workerWallMs) ?? 0,\n unrowedMs:\n workerWallMs === null\n ? 0\n : Math.max(\n 0,\n orchTerm - readyTerm - (transportMs ?? 0) - (afterSpanMs ?? 0),\n ),\n clampedMs,\n },\n };\n return {\n wallMs: sample.wallMs,\n httpMs: sample.httpMs,\n workerWallMs,\n roundTripMs,\n orchServerMs,\n orchIncludesTransport: orchServerMs === null && roundTripMs !== null,\n workerIncludesTransport: roundTripMs === null && orchServerMs !== null,\n terms,\n workerUnattributedMs,\n orchUnattributedMs,\n jobUnattributedMs,\n unnamedMs,\n unnamedShare: sample.wallMs > 0 ? unnamedMs / sample.wallMs : 0,\n overcountMs: Math.max(0, -terms.dark),\n spanLeaves,\n workerStages,\n orchTree,\n jobTree,\n spanTotalMs,\n window,\n };\n}\n"],"mappings":"AA0BA,MAAa,yBAA6C;CACxD,gBAAgB;CAChB,qBAAqB,IAtBkB,IAAI;EAC3C;EACA;EACA;EACD,CAkBsB;CACrB,cAAc,EACZ,WAAW,+BACZ;CACF;AAED,MAAa,yBAA6C;CAGxD,gBAAgB;CAChB,qBAAqB,IAAI,IAAI;EAC3B;EACA;EACA;EACD,CAAC;CACH;AAED,MAAa,uBAA2C,EACtD,gBAAgB,8BACjB;AAED,MAAa,yBAA6C,EACxD,gBAAgB,gCACjB;;;;;;;;;;;;;;;;;;;;AA+CD,SAAgB,UAAU,QAA0C;CAClE,MAAM,UAAU,IAAI,IAAI,OAAO,KAAK,OAAO,CAAC;CAC5C,MAAM,YAAY,SAAiB;EACjC,IAAI,MAAM,KAAK,YAAY,IAAI;AAC/B,SAAO,MAAM,GAAG;GACd,MAAM,YAAY,KAAK,MAAM,GAAG,IAAI;AACpC,OAAI,QAAQ,IAAI,UAAU,CAAE,QAAO;AACnC,SAAM,UAAU,YAAY,IAAI;;AAElC,SAAO,KAAK,SAAS,IAAI,GAAG,KAAK;;CAEnC,MAAM,QAAQ,OAAO,QAAQ,OAAO,CAAC,KAAK,CAAC,MAAM,SAAS;EACxD;EACA;EACA,QAAQ,SAAS,KAAK;EACvB,EAAE;CACH,MAAM,WAAW,MAAM,QAAQ,SAAS,KAAK,WAAW,KAAK;AAC7D,QAAO;EACL;EACA;;EAEA,SAAS,MAAM,QAAQ,SAAS,KAAK,WAAW,GAAG;EACnD,YAAY,SAAS,QAAQ,KAAK,SAAS,MAAM,KAAK,IAAI,EAAE;EAC7D;;;;;;;AAQH,SAAgB,eACd,OACA,SACA,aAAsE,EAAE,EACxE,MACwB;CACxB,MAAM,QAAQ,MAAM,kBAAkB;CACtC,MAAM,SAAS,IAAI,IAAI,WAAW,KAAK,OAAO,CAAC,GAAG,WAAW,GAAG,CAAC,CAAC;CAClE,MAAM,QAAQ,IAA0B,QAAQ,MAAc;EAC5D,MAAM,UACJ,GAAG,cAAc,SAAS,MAAM,qBAAqB,IAAI,GAAG,UAAU;EACxE,MAAM,SAAS,OAAO,IAAI,GAAG,WAAW,UAAU,KAAK,OAAO;EAC9D,MAAM,OAAO,GAAG,UAAU,MAAM,GAAG,UAAU,YAAY,IAAI,GAAG,EAAE;AAClE,SAAO,GAAG,UAAU,QAAQ,IAAI,KAAK,QAAQ,QAAQ,EAAE,GAAG,MAAM,GAAG;;CAErE,MAAM,OAA+B,GAAG,QAAQ,QAAQ,UAAU,GAAG;AACrE,MAAK,MAAM,EAAE,YAAY,IAAI,QAAQ,GAAG,QAAQ,WAC9C,KAAI,WAAW,eAAe,OAAO,OAAO,YAAY,MAAM,EAC5D,MAAK,KAAK,GAAG,KAAK,KAAK,KAAK,GAAG,KAAK,KAAK;CAC7C,MAAM,YAAoC,EAAE;AAC5C,MAAK,MAAM,CAAC,QAAQ,OAAO,OAAO,QAAQ,KAAK,EAAE;EAC/C,MAAM,OAAO,OAAO,KAAK,KAAK,CAAC,QAC5B,SACC,KAAK,WAAW,GAAG,OAAO,GAAG,IAC7B,CAAC,KAAK,MAAM,OAAO,SAAS,EAAE,CAAC,SAAS,IAAI,CAC/C;AACD,MAAI,KAAK,OACP,WAAU,GAAG,OAAO,kBAAkB,KAAK,IACzC,GACA,KAAK,QAAQ,MAAM,QAAQ,QAAQ,KAAK,QAAQ,IAAI,GAAG,CACxD;;AAEL,QAAO,KAAK;AACZ,QAAO;EAAE,GAAG;EAAW,GAAG;EAAM;;;;;;;;;;AAWlC,MAAM,aAAa,IAAI,IAAI;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;AAGF,SAAgB,iBACd,YACqB;AACrB,QAAO,IAAI,IACT,WAAW,SAAS,OAClB,OAAO,GAAG,WAAW,WAAW,CAAC,GAAG,OAAO,GAAG,EAAE,CACjD,CACF;;;;;;;;;;AAWH,SAAgB,eACd,YACA,2BAAgC,IAAI,KAAK,EACzC,UAAU,iBAAiB,WAAW,EACtC;AACA,QAAO,WAAW,QACf,OACC,CAAC,SAAS,IAAI,GAAG,UAAU,IAC3B,CAAC,QAAQ,IAAI,GAAG,UAAU,IAC1B,OAAO,GAAG,eAAe,YACzB,OAAO,SAAS,GAAG,WAAW,CACjC;;AAGH,SAAgB,uBACd,YACA,2BAAgC,IAAI,KAAK,EACzC;CACA,MAAM,yBAAS,IAAI,KAAqB;AACxC,MAAK,MAAM,MAAM,eAAe,YAAY,SAAS,CACnD,QAAO,IAAI,GAAG,YAAY,OAAO,IAAI,GAAG,UAAU,IAAI,KAAK,GAAG,WAAW;AAC3E,QAAO;;AAGT,MAAM,cAAc,GAAkB,MACpC,MAAM,QAAQ,MAAM,OAAO,OAAO,IAAI;AACxC,MAAM,sBAAsB,GAAkB,MAAqB;CACjE,MAAM,QAAQ,WAAW,GAAG,EAAE;AAC9B,QAAO,UAAU,OAAO,OAAO,KAAK,IAAI,GAAG,MAAM;;;;;;;AAQnD,SAAgB,wBACd,QACA,MACA;CACA,MAAM,WAAW,UACf,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM,GAAG,QAAQ;CAChE,MAAM,gBAAgB,WACpB,OAAO,YACL,OAAO,QAAQ,UAAU,EAAE,CAAC,CAAC,QAAQ,GAAG,QAAQ,OAAO,SAAS,GAAG,CAAC,CACrE;CACH,MAAM,OAAO,OAAO,QAAQ,EAAE;CAC9B,MAAM,OAAO,QAAgB,QAAQ,KAAK,KAAK;CAC/C,MAAM,UAAU,IAAI,KAAK,eAAe;CACxC,MAAM,aAAa,IAAI,aAAa;CACpC,MAAM,OAAO,KAAK,YAAa,IAAI,KAAK,UAAU,IAAI,IAAK;CAC3D,MAAM,eACJ,YAAY,OACR,OACA,KAAK,IAAI,GAAG,UAAU,KAAK,IAC1B,KAAK,gBAAiB,cAAc,IAAK;CAChD,MAAM,cAAc,IAAI,eAAe;CACvC,MAAM,eAAe,IAAI,qBAAqB;CAC9C,MAAM,WAAW,eAAe;CAChC,MAAM,QAAQ;EACZ,MAAM,mBAAmB,OAAO,QAAQ,aAAa;EACrD,QAAQ,mBAAmB,cAAc,YAAY,EAAE;EACvD,WAAW,mBAAmB,aAAa,aAAa;EACxD,MAAM,gBAAgB;EACtB,KAAK,QAAQ,OAAO,MAAM;EAC1B,QAAQ,QAAQ,OAAO,SAAS;EAChC,MAAM;EACP;AACD,OAAM,OACJ,OAAO,SACP,OAAO,OAAO,MAAM,CAAC,QAAgB,KAAK,OAAO,OAAO,MAAM,IAAI,EAAE;CACtE,MAAM,YAAY,KAAK,uCAAuB,IAAI,KAAK;CACvD,MAAM,YACJ,OAAO,cACP,OAAO,YAAY,uBAAuB,OAAO,WAAW,EAAE,CAAC,CAAC;CAClE,MAAM,aAAa,OAAO,YACxB,OAAO,QAAQ,UAAU,CAAC,QACvB,CAAC,MAAM,QACN,SAAS,KAAK,kBACd,CAAC,UAAU,IAAI,KAAK,IACpB,OAAO,SAAS,GAAG,CACtB,CACF;CAED,MAAM,eAAe,OAAO,YAC1B,OAAO,QAAQ,KAAK,CAAC,QAClB,CAAC,UACA,OAAO,SAAS,KAAK,MAAM,IAC3B,CAAC,WAAW,IAAI,KAAK,IACrB,SAAS,KAAK,aACd,CAAC,KAAK,WAAW,QAAQ,IACzB,CAAC,KAAK,WAAW,MAAM,CAC1B,CACF;CACD,MAAM,WAAW,UAAU,aAAa,OAAO,WAAW,CAAC;CAC3D,MAAM,UAAU,UAAU,aAAa,OAAO,UAAU,CAAC;CACzD,MAAM,UAAU,OAAO,OAAO,WAAW,CAAC,QAAQ,KAAK,OAAO,MAAM,IAAI,EAAE;CAC1E,MAAM,eACH,KAAK,gBAAiB,cAAc,IAAK,MACzC,KAAK,kBACF,KAAK,gBAAgB,QAAQ,KAAK,QAAQ,OAAO,IAAI,IAAI,IAAI,IAAI,EAAE,GACnE,UAAU,aAAa,CAAC;CAC9B,MAAM,uBAAuB,WAAW,MAAM,QAAQ,YAAY;CAClE,MAAM,YAAY,SAAS,SAAS,SAChC,SAAS,aACT,UAAU,IACR,UACA;CACN,MAAM,qBAAqB,WAAW,MAAM,MAAM,UAAU;CAC5D,MAAM,oBAAoB,WAAW,MAAM,KAAK,QAAQ,WAAW;CACnE,MAAM,YACJ,KAAK,IAAI,GAAG,wBAAwB,MAAM,UAAU,EAAE,GACtD,KAAK,IAAI,GAAG,sBAAsB,MAAM,QAAQ,EAAE,GAClD,KAAK,IAAI,GAAG,qBAAqB,MAAM,OAAO,EAAE,GAChD,KAAK,IAAI,GAAG,MAAM,KAAK;CACzB,MAAM,iBAAiB,OAAO,WAAW,EAAE,EAAE,MAC1C,OAAO,GAAG,cAAc,KAAK,eAC/B,EAAE;CACH,MAAM,cAAc,QAAQ,OAAO,eAAe,cAAc;CAChE,MAAM,WAAW,OAAO,mBAAmB;CAC3C,MAAM,YAAY,eAAe;CACjC,MAAM,WAAW,eAAe,gBAAgB;CAChD,IAAI,YAAY;CAChB,MAAM,QAAQ,GAAkB,MAAqB;EACnD,MAAM,QAAQ,WAAW,GAAG,EAAE;AAC9B,MAAI,UAAU,KAAM,QAAO;AAC3B,eAAa,KAAK,IAAI,GAAG,CAAC,MAAM;AAChC,SAAO,KAAK,IAAI,GAAG,MAAM;;CAE3B,MAAM,cAAc,KAAK,aAAa,aAAa;CACnD,MAAM,cAAc,KAAK,cAAc,YAAY;CACnD,MAAM,UAAU,cAAc;CAQ9B,MAAM,SAAS;EACb;EACA;EACA,SATA,iBAAiB,OACb,KACE,OAAO,SAAS,WAChB,eAAe,eAAe,MAAM,eAAe,GACpD,GACD,KAAK,OAAO,QAAQ,aAAa;EAKrC,sBAAsB,mBAAmB,cAAc,QAAQ;EAC/D,aAAa,mBAAmB,cAAc,SAAS;EACvD,MAAM;GACJ,WAAW,mBAAmB,UAAU,YAAY,IAAI;GACxD,aAAa,mBAAmB,aAAa,SAAS,IAAI;GAC1D,iBAAiB,mBAAmB,SAAS,aAAa,IAAI;GAC9D,WACE,iBAAiB,OACb,IACA,KAAK,IACH,GACA,WAAW,aAAa,eAAe,MAAM,eAAe,GAC7D;GACP;GACD;EACF;AACD,QAAO;EACL,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf;EACA;EACA;EACA,uBAAuB,iBAAiB,QAAQ,gBAAgB;EAChE,yBAAyB,gBAAgB,QAAQ,iBAAiB;EAClE;EACA;EACA;EACA;EACA;EACA,cAAc,OAAO,SAAS,IAAI,YAAY,OAAO,SAAS;EAC9D,aAAa,KAAK,IAAI,GAAG,CAAC,MAAM,KAAK;EACrC;EACA;EACA;EACA;EACA;EACA;EACD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"lifecycle-wall-BnN-KFBx.d.mts","names":[],"sources":["../src/lifecycle-wall.ts"],"mappings":";;AAoBA;;;;;;;KAAY,kBAAA;EACV,cAAA;EACA,mBAAA,GAAsB,WAAA;EACtB,YAAA;IAAiB,SAAA;EAAA;AAAA;AAAA,cAGN,sBAAA,EAAwB,kBAAA;AAAA,cAQxB,sBAAA,EAAwB,kBAAA;AAAA,cAWxB,oBAAA,EAAsB,kBAAA;AAAA,cAItB,sBAAA,EAAwB,kBAAA;AAAA,UAIpB,oBAAA;EACf,SAAA;EACA,UAAA;EACA,MAAA;AAAA;AAAA,KAEG,MAAA,GAAS,QAAA,CAAS,MAAA;AAAA,UACN,mBAAA;EACf,MAAA;EACA,MAAA;EACA,IAAA,GAAO,MAAA;EACP,OAAA,YAAmB,oBAAA;EACnB,UAAA,GAAa,MAAA;EACb,WAAA;EACA,UAAA,GAAa,MAAA;EACb,SAAA,GAAY,MAAA;EACZ,KAAA;EACA,QAAA;EACA,eAAA;AAAA;AAAA,UAEe,iBAAA,SAA0B,OAAA,CAAQ,kBAAA;EACjD,cAAA;EACA,aAAA;EACA,SAAA;EACA,eAAA;AAAA;;;AAjBF;;;;;;;;;;;;;;;;;iBAuCgB,SAAA,CAAU,MAAA,EAAQ,QAAA,CAAS,MAAA;;;;;;;;;;OA1B1B;;;;;;;;;;;;AA0BjB;iBA+BgB,cAAA,CACd,KAAA,UACA,OAAA,EAAS,QAAA,CAAS,MAAA,mBAClB,UAAA,aAAsB,oBAAA;EAAyB,MAAA;AAAA,MAC/C,IAAA,GAAO,OAAA,CAAQ,kBAAA,IACd,MAAA;;iBAkDa,gBAAA,CACd,UAAA,WAAqB,oBAAA,KACpB,WAAA;;;;;;;;;iBAgBa,cAAA,WAAyB,oBAAA,CAAA,CACvC,UAAA,WAAqB,CAAA,IACrB,QAAA,GAAU,WAAA,UACV,OAAA,GAAO,WAAA,YAA+B,CAAA;;;iBAWxB,sBAAA,CACd,UAAA,WAAqB,oBAAA,IACrB,QAAA,GAAU,WAAA,WAA+B,GAAA;;;;;AAzF3C;iBA6GgB,uBAAA,CACd,MAAA,EAAQ,mBAAA,EACR,IAAA,EAAM,iBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAnCgC;;;;;;;;;;;;;;;;;;SAaG"}