@lunora/observability 1.0.0-alpha.29 → 1.0.0-alpha.30

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
@@ -1879,12 +1879,25 @@ interface TraceSummary {
1879
1879
  rootName: string;
1880
1880
  shardKey?: string;
1881
1881
  /**
1882
- * Spans ordered by `(offsetMs, depth)`, ready to render as waterfall rows.
1883
- * Start time alone is not enough to order them: spans are recorded on
1884
- * completion and `startTs` has millisecond resolution, so a parent and its
1885
- * child routinely tie. Breaking that tie by depth makes the sequence a valid
1886
- * pre-order traversal of the span tree, so indenting each row by its `depth`
1887
- * yields the nesting without a separate tree walk.
1882
+ * Spans in **pre-order**, ready to render as waterfall rows: every span is
1883
+ * immediately followed by its own subtree, siblings in start order. So
1884
+ * indenting each row by its `depth` yields the real nesting the row above
1885
+ * a `depth`-`n+1` row is genuinely its parent.
1886
+ *
1887
+ * This is a tree walk, not a sort, because no ordering on `(offsetMs,
1888
+ * depth)` can produce it. Given a parent, its child `a`, `a`'s child `a1`
1889
+ * and `a`'s sibling `b` all at offset 0, that comparator yields
1890
+ * `parent, a, b, a1` — which renders `a1` indented beneath `b`, under a
1891
+ * parent it does not belong to.
1892
+ *
1893
+ * **Why they tie is not millisecond resolution.** On the Workers runtime
1894
+ * `Date.now()` is pinned to the time of the last I/O — a Spectre mitigation,
1895
+ * not a bug — so it does not advance at all across pure computation. Every
1896
+ * duration in this package is `Date.now() - startTs`, which means a span
1897
+ * wrapping CPU-only work reports `0`, and a parent whose child performed no
1898
+ * I/O shares its exact start and end. See `docs/concepts/observability`
1899
+ * ("Span durations on Workers"); the practical consequence is that a `0 ms`
1900
+ * span means "no I/O happened here", not "this was fast".
1888
1901
  */
1889
1902
  spans: TraceSpan[];
1890
1903
  startTs: number;
package/dist/index.d.ts CHANGED
@@ -1879,12 +1879,25 @@ interface TraceSummary {
1879
1879
  rootName: string;
1880
1880
  shardKey?: string;
1881
1881
  /**
1882
- * Spans ordered by `(offsetMs, depth)`, ready to render as waterfall rows.
1883
- * Start time alone is not enough to order them: spans are recorded on
1884
- * completion and `startTs` has millisecond resolution, so a parent and its
1885
- * child routinely tie. Breaking that tie by depth makes the sequence a valid
1886
- * pre-order traversal of the span tree, so indenting each row by its `depth`
1887
- * yields the nesting without a separate tree walk.
1882
+ * Spans in **pre-order**, ready to render as waterfall rows: every span is
1883
+ * immediately followed by its own subtree, siblings in start order. So
1884
+ * indenting each row by its `depth` yields the real nesting the row above
1885
+ * a `depth`-`n+1` row is genuinely its parent.
1886
+ *
1887
+ * This is a tree walk, not a sort, because no ordering on `(offsetMs,
1888
+ * depth)` can produce it. Given a parent, its child `a`, `a`'s child `a1`
1889
+ * and `a`'s sibling `b` all at offset 0, that comparator yields
1890
+ * `parent, a, b, a1` — which renders `a1` indented beneath `b`, under a
1891
+ * parent it does not belong to.
1892
+ *
1893
+ * **Why they tie is not millisecond resolution.** On the Workers runtime
1894
+ * `Date.now()` is pinned to the time of the last I/O — a Spectre mitigation,
1895
+ * not a bug — so it does not advance at all across pure computation. Every
1896
+ * duration in this package is `Date.now() - startTs`, which means a span
1897
+ * wrapping CPU-only work reports `0`, and a parent whose child performed no
1898
+ * I/O shares its exact start and end. See `docs/concepts/observability`
1899
+ * ("Span durations on Workers"); the practical consequence is that a `0 ms`
1900
+ * span means "no I/O happened here", not "this was fast".
1888
1901
  */
1889
1902
  spans: TraceSpan[];
1890
1903
  startTs: number;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{AUTH_METRICS_BUCKETS_TABLE as t,AUTH_METRICS_BUCKET_MS as T,AUTH_METRICS_BUCKET_RETENTION as o,AUTH_METRICS_TABLE as a,ensureAuthMetricsTables as s,readAuthMetrics as E,recordAuthEvent as _}from"./packem_shared/AUTH_METRICS_BUCKETS_TABLE-DGMchLuo.mjs";import{createMetrics as S,createSpanCollector as I,createTracedFetch as i,createTracer as n,dispatchRootSpan as M}from"./packem_shared/createMetrics-CTHH5h5E.mjs";import{createDatabaseTally as A,formatTally as C,instrumentDatabase as N}from"./packem_shared/createDatabaseTally-B3Cl-VMH.mjs";import{FUNCTION_METRICS_BUCKETS_TABLE as f,FUNCTION_METRICS_BUCKET_MS as U,FUNCTION_METRICS_BUCKET_RETENTION as d,FUNCTION_METRICS_INDEX_TABLE as R,FUNCTION_METRICS_MAX_PATHS as L,FUNCTION_METRICS_READ_LIMIT as m,FUNCTION_METRICS_SCANS_TABLE as x,FUNCTION_METRICS_TABLE as B,ensureFunctionMetricsTables as F,mergeScanAttribution as l,readFunctionMetricBuckets as g,readFunctionMetricIndexHits as O,readFunctionMetricScans as H,readFunctionMetrics as y,readFunctionMetricsTotals as b,recordFunctionMetric as D}from"./packem_shared/FUNCTION_METRICS_BUCKETS_TABLE-SKpGN7hQ.mjs";import{DEFAULT_EXPLAIN_ISSUE_MODEL as K,explainIssue as q,parseExplainIssueArgs as v}from"./packem_shared/DEFAULT_EXPLAIN_ISSUE_MODEL-BGGX6k5D.mjs";import{ISSUE_SEVERITIES as G,ISSUE_STATE_TABLE as X,ISSUE_STATUSES as P,upsertIssueState as k}from"./packem_shared/ISSUE_SEVERITIES-gLC4VEPQ.mjs";import{LogBuffer as j}from"./packem_shared/LogBuffer-bIvCelI-.mjs";import{M as z}from"./packem_shared/metric-buffer-BGdHQs8k.mjs";import{readMetricHistory as W,recordMetricHistory as Y}from"./packem_shared/readMetricHistory-CbWL3Qhh.mjs";import{readQueryInsights as $,readQueryMetrics as ee,recordQueryMetric as re}from"./packem_shared/readQueryInsights-Ev3XWiWk.mjs";import{R as Te,a as oe,e as ae,b as se,c as Ee,p as _e,r as ce,d as Se,f as Ie}from"./packem_shared/request-log-Dp7JeJec.mjs";import{MIN_ADMIN_TOKEN_LENGTH as ne,MIN_AUTH_SECRET_LENGTH as Me,buildSecurityAudit as ue}from"./packem_shared/MIN_ADMIN_TOKEN_LENGTH-CidkqOQ1.mjs";import{SpanBuffer as Ce,foldTraces as Ne}from"./packem_shared/SpanBuffer-XXY-VTCY.mjs";import{findDanglingReferences as fe}from"./packem_shared/findDanglingReferences-Dxl42LBT.mjs";import{r as de}from"./packem_shared/trace-context-CpFltS-q.mjs";export{t as AUTH_METRICS_BUCKETS_TABLE,T as AUTH_METRICS_BUCKET_MS,o as AUTH_METRICS_BUCKET_RETENTION,a as AUTH_METRICS_TABLE,K as DEFAULT_EXPLAIN_ISSUE_MODEL,f as FUNCTION_METRICS_BUCKETS_TABLE,U as FUNCTION_METRICS_BUCKET_MS,d as FUNCTION_METRICS_BUCKET_RETENTION,R as FUNCTION_METRICS_INDEX_TABLE,L as FUNCTION_METRICS_MAX_PATHS,m as FUNCTION_METRICS_READ_LIMIT,x as FUNCTION_METRICS_SCANS_TABLE,B as FUNCTION_METRICS_TABLE,G as ISSUE_SEVERITIES,X as ISSUE_STATE_TABLE,P as ISSUE_STATUSES,j as LogBuffer,ne as MIN_ADMIN_TOKEN_LENGTH,Me as MIN_AUTH_SECRET_LENGTH,z as MetricBuffer,Te as REQUEST_LOG_TABLE,Ce as SpanBuffer,oe as appendRequestLogEntry,ue as buildSecurityAudit,A as createDatabaseTally,S as createMetrics,I as createSpanCollector,i as createTracedFetch,n as createTracer,M as dispatchRootSpan,ae as emitLogEvent,se as emitRequestLogEvent,s as ensureAuthMetricsTables,F as ensureFunctionMetricsTables,Ee as ensureRequestLogTable,q as explainIssue,fe as findDanglingReferences,Ne as foldTraces,C as formatTally,N as instrumentDatabase,l as mergeScanAttribution,v as parseExplainIssueArgs,_e as parseLogArgs,E as readAuthMetrics,ce as readErrorIssues,g as readFunctionMetricBuckets,O as readFunctionMetricIndexHits,H as readFunctionMetricScans,y as readFunctionMetrics,b as readFunctionMetricsTotals,W as readMetricHistory,$ as readQueryInsights,ee as readQueryMetrics,Se as readRequestLog,_ as recordAuthEvent,D as recordFunctionMetric,Y as recordMetricHistory,re as recordQueryMetric,Ie as redactArgs,de as resolveTraceAnchor,k as upsertIssueState};
1
+ import{AUTH_METRICS_BUCKETS_TABLE as t,AUTH_METRICS_BUCKET_MS as T,AUTH_METRICS_BUCKET_RETENTION as o,AUTH_METRICS_TABLE as a,ensureAuthMetricsTables as s,readAuthMetrics as E,recordAuthEvent as _}from"./packem_shared/AUTH_METRICS_BUCKETS_TABLE-DGMchLuo.mjs";import{createMetrics as S,createSpanCollector as I,createTracedFetch as i,createTracer as n,dispatchRootSpan as M}from"./packem_shared/createMetrics-CTHH5h5E.mjs";import{createDatabaseTally as A,formatTally as C,instrumentDatabase as N}from"./packem_shared/createDatabaseTally-B3Cl-VMH.mjs";import{FUNCTION_METRICS_BUCKETS_TABLE as f,FUNCTION_METRICS_BUCKET_MS as U,FUNCTION_METRICS_BUCKET_RETENTION as d,FUNCTION_METRICS_INDEX_TABLE as R,FUNCTION_METRICS_MAX_PATHS as L,FUNCTION_METRICS_READ_LIMIT as m,FUNCTION_METRICS_SCANS_TABLE as x,FUNCTION_METRICS_TABLE as B,ensureFunctionMetricsTables as F,mergeScanAttribution as l,readFunctionMetricBuckets as g,readFunctionMetricIndexHits as O,readFunctionMetricScans as H,readFunctionMetrics as y,readFunctionMetricsTotals as b,recordFunctionMetric as D}from"./packem_shared/FUNCTION_METRICS_BUCKETS_TABLE-SKpGN7hQ.mjs";import{DEFAULT_EXPLAIN_ISSUE_MODEL as K,explainIssue as q,parseExplainIssueArgs as v}from"./packem_shared/DEFAULT_EXPLAIN_ISSUE_MODEL-BGGX6k5D.mjs";import{ISSUE_SEVERITIES as G,ISSUE_STATE_TABLE as X,ISSUE_STATUSES as P,upsertIssueState as k}from"./packem_shared/ISSUE_SEVERITIES-gLC4VEPQ.mjs";import{LogBuffer as j}from"./packem_shared/LogBuffer-bIvCelI-.mjs";import{M as z}from"./packem_shared/metric-buffer-BGdHQs8k.mjs";import{readMetricHistory as W,recordMetricHistory as Y}from"./packem_shared/readMetricHistory-CbWL3Qhh.mjs";import{readQueryInsights as $,readQueryMetrics as ee,recordQueryMetric as re}from"./packem_shared/readQueryInsights-Ev3XWiWk.mjs";import{R as Te,a as oe,e as ae,b as se,c as Ee,p as _e,r as ce,d as Se,f as Ie}from"./packem_shared/request-log-Dp7JeJec.mjs";import{MIN_ADMIN_TOKEN_LENGTH as ne,MIN_AUTH_SECRET_LENGTH as Me,buildSecurityAudit as ue}from"./packem_shared/MIN_ADMIN_TOKEN_LENGTH-CidkqOQ1.mjs";import{SpanBuffer as Ce,foldTraces as Ne}from"./packem_shared/SpanBuffer-zjqCAuGp.mjs";import{findDanglingReferences as fe}from"./packem_shared/findDanglingReferences-Dxl42LBT.mjs";import{r as de}from"./packem_shared/trace-context-CpFltS-q.mjs";export{t as AUTH_METRICS_BUCKETS_TABLE,T as AUTH_METRICS_BUCKET_MS,o as AUTH_METRICS_BUCKET_RETENTION,a as AUTH_METRICS_TABLE,K as DEFAULT_EXPLAIN_ISSUE_MODEL,f as FUNCTION_METRICS_BUCKETS_TABLE,U as FUNCTION_METRICS_BUCKET_MS,d as FUNCTION_METRICS_BUCKET_RETENTION,R as FUNCTION_METRICS_INDEX_TABLE,L as FUNCTION_METRICS_MAX_PATHS,m as FUNCTION_METRICS_READ_LIMIT,x as FUNCTION_METRICS_SCANS_TABLE,B as FUNCTION_METRICS_TABLE,G as ISSUE_SEVERITIES,X as ISSUE_STATE_TABLE,P as ISSUE_STATUSES,j as LogBuffer,ne as MIN_ADMIN_TOKEN_LENGTH,Me as MIN_AUTH_SECRET_LENGTH,z as MetricBuffer,Te as REQUEST_LOG_TABLE,Ce as SpanBuffer,oe as appendRequestLogEntry,ue as buildSecurityAudit,A as createDatabaseTally,S as createMetrics,I as createSpanCollector,i as createTracedFetch,n as createTracer,M as dispatchRootSpan,ae as emitLogEvent,se as emitRequestLogEvent,s as ensureAuthMetricsTables,F as ensureFunctionMetricsTables,Ee as ensureRequestLogTable,q as explainIssue,fe as findDanglingReferences,Ne as foldTraces,C as formatTally,N as instrumentDatabase,l as mergeScanAttribution,v as parseExplainIssueArgs,_e as parseLogArgs,E as readAuthMetrics,ce as readErrorIssues,g as readFunctionMetricBuckets,O as readFunctionMetricIndexHits,H as readFunctionMetricScans,y as readFunctionMetrics,b as readFunctionMetricsTotals,W as readMetricHistory,$ as readQueryInsights,ee as readQueryMetrics,Se as readRequestLog,_ as recordAuthEvent,D as recordFunctionMetric,Y as recordMetricHistory,re as recordQueryMetric,Ie as redactArgs,de as resolveTraceAnchor,k as upsertIssueState};
@@ -0,0 +1 @@
1
+ class m{buffer=[];capacity;constructor(r=500){this.capacity=r>0?Math.trunc(r):500}get size(){return this.buffer.length}clear(){this.buffer.length=0}entries(){return[...this.buffer]}hasTrace(r){return this.buffer.some(o=>o.traceId===r)}push(r){this.buffer.push(r),this.buffer.length>this.capacity&&this.buffer.shift()}}const I=50,l=d=>{const r=new Map;for(const o of d){const c=r.get(o.traceId);c===void 0?r.set(o.traceId,[o]):c.push(o)}return r},T=(d,r)=>{const o=d.find(a=>a.dispatch===!0);if(o!==void 0)return o;const c=d.toSorted((a,t)=>a.startTs-t.startTs);return c.find(a=>!r.has(a.parentSpanId))??c[0]},b=(d,r)=>{const o=new Map([[d.spanId,0]]);return c=>{const a=[],t=new Set;let e=c,n=0;for(;;){const i=o.get(e.spanId);if(i!==void 0){n=i;break}if(t.has(e.spanId))break;t.add(e.spanId),a.push(e);const f=r.get(e.parentSpanId);if(f===void 0)break;e=f}for(const[i,f]of a.toReversed().entries())o.set(f.spanId,n+i+1);return o.get(c.spanId)??n}},v=(d,r)=>{const o=new Map(d.map(t=>[t.spanId,t.depth])),c=new Map,a=[];for(const t of d){if(t.spanId===r){a.push(t);continue}const e=o.get(t.parentSpanId)===t.depth-1?t.parentSpanId:r,n=c.get(e);n===void 0?c.set(e,[t]):n.push(t)}for(const t of c.values())t.sort((e,n)=>e.offsetMs-n.offsetMs);return{childrenOf:c,roots:a}},g=(d,r)=>{const{childrenOf:o,roots:c}=v(d,r),a=[],t=new Set,e=c.toReversed();for(;e.length>0;){const n=e.pop();if(t.has(n))continue;t.add(n),a.push(n);const i=o.get(n.spanId);if(i!==void 0)for(const f of i.toReversed())e.push(f)}if(a.length!==d.length)for(const n of d)t.has(n)||a.push(n);return a},M=(d,r=I)=>{const o=l(d),c=[...o.entries()].map(([t,e])=>({group:e,startTs:Math.min(...e.map(n=>n.startTs)),traceId:t})).toSorted((t,e)=>e.startTs-t.startTs).slice(0,r),a=[];for(const{group:t,traceId:e}of c){const n=new Map(t.map(s=>[s.spanId,s])),i=T(t,n);if(i===void 0)continue;const f=b(i,n),{startTs:h}=i,u=Math.max(...t.map(s=>s.startTs+s.durationMs)),p=t.map(s=>({...s.attributes===void 0?{}:{attributes:s.attributes},depth:f(s),durationMs:s.durationMs,...s.error===void 0?{}:{error:s.error},...s.events===void 0?{}:{events:s.events},...s.kind===void 0?{}:{kind:s.kind},name:s.name,offsetMs:Math.max(0,s.startTs-h),ok:s.ok,parentSpanId:s.parentSpanId,spanId:s.spanId}));a.push({durationMs:u-h,functionPath:i.functionPath,ok:t.every(s=>s.ok),rootName:i.name,...i.shardKey===void 0?{}:{shardKey:i.shardKey},spans:g(p,i.spanId),startTs:h,traceId:e})}return{total:o.size,traces:a.toSorted((t,e)=>e.startTs-t.startTs)}};export{I as DEFAULT_TRACE_LIMIT,m as SpanBuffer,M as foldTraces};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/observability",
3
- "version": "1.0.0-alpha.29",
3
+ "version": "1.0.0-alpha.30",
4
4
  "description": "Host-neutral telemetry storage and read models for Lunora, backing the Studio's Logs, Traces, Metrics and Issues views",
5
5
  "keywords": [
6
6
  "lunora",
@@ -45,7 +45,7 @@
45
45
  "dependencies": {
46
46
  "@lunora/errors": "1.0.0-alpha.22",
47
47
  "@lunora/fingerprint": "1.0.0-alpha.7",
48
- "@lunora/shard-engine": "1.0.0-alpha.29",
48
+ "@lunora/shard-engine": "1.0.0-alpha.30",
49
49
  "@visulima/redact": "4.0.0"
50
50
  },
51
51
  "engines": {
@@ -1 +0,0 @@
1
- class m{buffer=[];capacity;constructor(e=500){this.capacity=e>0?Math.trunc(e):500}get size(){return this.buffer.length}clear(){this.buffer.length=0}entries(){return[...this.buffer]}hasTrace(e){return this.buffer.some(r=>r.traceId===e)}push(e){this.buffer.push(e),this.buffer.length>this.capacity&&this.buffer.shift()}}const I=50,b=d=>{const e=new Map;for(const r of d){const c=e.get(r.traceId);c===void 0?e.set(r.traceId,[r]):c.push(r)}return e},v=(d,e)=>{const r=d.find(a=>a.dispatch===!0);if(r!==void 0)return r;const c=d.toSorted((a,s)=>a.startTs-s.startTs);return c.find(a=>!e.has(a.parentSpanId))??c[0]},l=(d,e)=>{const r=new Map([[d.spanId,0]]);return c=>{const a=[],s=new Set;let n=c,i=0;for(;;){const o=r.get(n.spanId);if(o!==void 0){i=o;break}if(s.has(n.spanId))break;s.add(n.spanId),a.push(n);const f=e.get(n.parentSpanId);if(f===void 0)break;n=f}for(const[o,f]of a.toReversed().entries())r.set(f.spanId,i+o+1);return r.get(c.spanId)??i}},M=(d,e=I)=>{const r=b(d),c=[...r.entries()].map(([s,n])=>({group:n,startTs:Math.min(...n.map(i=>i.startTs)),traceId:s})).toSorted((s,n)=>n.startTs-s.startTs).slice(0,e),a=[];for(const{group:s,traceId:n}of c){const i=new Map(s.map(t=>[t.spanId,t])),o=v(s,i);if(o===void 0)continue;const f=l(o,i),{startTs:u}=o,p=Math.max(...s.map(t=>t.startTs+t.durationMs)),T=s.map(t=>({...t.attributes===void 0?{}:{attributes:t.attributes},depth:f(t),durationMs:t.durationMs,...t.error===void 0?{}:{error:t.error},...t.events===void 0?{}:{events:t.events},...t.kind===void 0?{}:{kind:t.kind},name:t.name,offsetMs:Math.max(0,t.startTs-u),ok:t.ok,parentSpanId:t.parentSpanId,spanId:t.spanId})).toSorted((t,h)=>t.offsetMs-h.offsetMs||t.depth-h.depth);a.push({durationMs:p-u,functionPath:o.functionPath,ok:s.every(t=>t.ok),rootName:o.name,...o.shardKey===void 0?{}:{shardKey:o.shardKey},spans:T,startTs:u,traceId:n})}return{total:r.size,traces:a.toSorted((s,n)=>n.startTs-s.startTs)}};export{I as DEFAULT_TRACE_LIMIT,m as SpanBuffer,M as foldTraces};