@xeonr/telemetry-web 0.0.0-stage → 0.1.0

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.
Files changed (50) hide show
  1. package/README.md +168 -2
  2. package/dist/classify.d.ts +48 -0
  3. package/dist/classify.d.ts.map +1 -0
  4. package/dist/classify.js +117 -0
  5. package/dist/classify.js.map +1 -0
  6. package/dist/client.d.ts +135 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +511 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/connect.d.ts +11 -0
  11. package/dist/connect.d.ts.map +1 -0
  12. package/dist/connect.js +44 -0
  13. package/dist/connect.js.map +1 -0
  14. package/dist/env.d.ts +68 -0
  15. package/dist/env.d.ts.map +1 -0
  16. package/dist/env.js +97 -0
  17. package/dist/env.js.map +1 -0
  18. package/dist/index.d.ts +34 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +89 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/otlp.d.ts +124 -0
  23. package/dist/otlp.d.ts.map +1 -0
  24. package/dist/otlp.js +105 -0
  25. package/dist/otlp.js.map +1 -0
  26. package/dist/queue.d.ts +92 -0
  27. package/dist/queue.d.ts.map +1 -0
  28. package/dist/queue.js +355 -0
  29. package/dist/queue.js.map +1 -0
  30. package/dist/react.d.ts +34 -0
  31. package/dist/react.d.ts.map +1 -0
  32. package/dist/react.js +46 -0
  33. package/dist/react.js.map +1 -0
  34. package/dist/stack.d.ts +23 -0
  35. package/dist/stack.d.ts.map +1 -0
  36. package/dist/stack.js +52 -0
  37. package/dist/stack.js.map +1 -0
  38. package/dist/trace.d.ts +10 -0
  39. package/dist/trace.d.ts.map +1 -0
  40. package/dist/trace.js +46 -0
  41. package/dist/trace.js.map +1 -0
  42. package/dist/vitals.d.ts +20 -0
  43. package/dist/vitals.d.ts.map +1 -0
  44. package/dist/vitals.js +151 -0
  45. package/dist/vitals.js.map +1 -0
  46. package/dist/vite.d.ts +41 -0
  47. package/dist/vite.d.ts.map +1 -0
  48. package/dist/vite.js +171 -0
  49. package/dist/vite.js.map +1 -0
  50. package/package.json +59 -3
package/dist/env.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ export interface StorageLike {
2
+ getItem(key: string): string | null;
3
+ setItem(key: string, value: string): void;
4
+ removeItem(key: string): void;
5
+ }
6
+ export interface Listenable {
7
+ addEventListener(type: string, fn: (ev: unknown) => void, opts?: unknown): void;
8
+ removeEventListener?(type: string, fn: (ev: unknown) => void, opts?: unknown): void;
9
+ }
10
+ export interface NavigatorLike {
11
+ onLine?: boolean | undefined;
12
+ language?: string | undefined;
13
+ userAgent?: string | undefined;
14
+ platform?: string | undefined;
15
+ userAgentData?: {
16
+ brands?: {
17
+ brand: string;
18
+ version: string;
19
+ }[] | undefined;
20
+ mobile?: boolean | undefined;
21
+ platform?: string | undefined;
22
+ } | undefined;
23
+ sendBeacon?: ((url: string, data?: BodyInit | null) => boolean) | undefined;
24
+ }
25
+ export type Timer = ReturnType<typeof setTimeout>;
26
+ export interface Env {
27
+ fetch: typeof fetch | undefined;
28
+ navigator: NavigatorLike | undefined;
29
+ local: StorageLike | null;
30
+ session: StorageLike | null;
31
+ /** Epoch milliseconds, fractional where the platform allows. */
32
+ now(): number;
33
+ /** The page's origin and path; undefined outside a browser. */
34
+ location: {
35
+ origin: string;
36
+ pathname: string;
37
+ hostname: string;
38
+ href: string;
39
+ } | undefined;
40
+ /** window, for error/unhandledrejection/pagehide/online. */
41
+ window: Listenable | undefined;
42
+ /** document, for visibilitychange and the <meta> lookups. */
43
+ document: (Listenable & {
44
+ visibilityState?: string | undefined;
45
+ querySelector?: ((sel: string) => {
46
+ getAttribute(n: string): string | null;
47
+ } | null) | undefined;
48
+ }) | undefined;
49
+ randomBytes(n: number): Uint8Array;
50
+ setTimeout(fn: () => void, ms: number): Timer;
51
+ clearTimeout(t: Timer): void;
52
+ setInterval(fn: () => void, ms: number): Timer;
53
+ clearInterval(t: Timer): void;
54
+ performance: Performance | undefined;
55
+ PerformanceObserver: typeof PerformanceObserver | undefined;
56
+ /** console.warn, once-per-message by the caller; quiet in tests. */
57
+ warn(msg: string): void;
58
+ }
59
+ /** The real browser. Safe to call anywhere; missing pieces come back undefined. */
60
+ export declare function browserEnv(): Env;
61
+ export declare function hex(bytes: Uint8Array): string;
62
+ /** A 16-byte trace id, never all zero. */
63
+ export declare function newTraceId(env: Pick<Env, "randomBytes">): string;
64
+ /** An 8-byte span id, never all zero. */
65
+ export declare function newSpanId(env: Pick<Env, "randomBytes">): string;
66
+ /** The content of `<meta name="…">`, or undefined. */
67
+ export declare function meta(env: Pick<Env, "document">, name: string): string | undefined;
68
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
package/dist/env.js ADDED
@@ -0,0 +1,97 @@
1
+ // Everything the SDK reads from the browser, behind one seam. The browser
2
+ // build reads globalThis; the tests hand in fakes. Every accessor tolerates
3
+ // the thing being absent (SSR, a worker, a privacy mode that throws on
4
+ // storage access), because the one rule is never to throw into the host.
5
+ function storage(get) {
6
+ try {
7
+ const s = get();
8
+ if (!s)
9
+ return null;
10
+ // Some privacy modes hand out a Storage that throws on write.
11
+ const probe = "__xeonr_tw_probe";
12
+ s.setItem(probe, "1");
13
+ s.removeItem(probe);
14
+ return s;
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ }
20
+ function fallbackRandom(n) {
21
+ const b = new Uint8Array(n);
22
+ for (let i = 0; i < n; i++)
23
+ b[i] = Math.floor(Math.random() * 256);
24
+ return b;
25
+ }
26
+ /** The real browser. Safe to call anywhere; missing pieces come back undefined. */
27
+ export function browserEnv() {
28
+ const g = globalThis;
29
+ const perf = typeof g.performance === "object" ? g.performance : undefined;
30
+ const origin = perf && typeof perf.timeOrigin === "number" ? perf.timeOrigin : undefined;
31
+ const loc = typeof g.location === "object" && g.location ? g.location : undefined;
32
+ const cryptoObj = typeof g.crypto === "object" ? g.crypto : undefined;
33
+ // Captured now, before anything (a host's own wrapper, or ours) patches it,
34
+ // so the SDK's own sends never go through a wrapper that reports on them.
35
+ const rawFetch = typeof g.fetch === "function" ? g.fetch.bind(g) : undefined;
36
+ return {
37
+ fetch: rawFetch,
38
+ navigator: typeof g.navigator === "object" ? g.navigator : undefined,
39
+ local: storage(() => g.localStorage),
40
+ session: storage(() => g.sessionStorage),
41
+ now: () => (perf && origin !== undefined ? origin + perf.now() : Date.now()),
42
+ location: loc ? { origin: loc.origin, pathname: loc.pathname, hostname: loc.hostname, href: loc.href } : undefined,
43
+ window: typeof g.addEventListener === "function" && typeof g.document === "object" ? g : undefined,
44
+ document: typeof g.document === "object" && g.document ? g.document : undefined,
45
+ randomBytes: (n) => {
46
+ try {
47
+ if (cryptoObj?.getRandomValues)
48
+ return cryptoObj.getRandomValues(new Uint8Array(n));
49
+ }
50
+ catch {
51
+ /* fall through */
52
+ }
53
+ return fallbackRandom(n);
54
+ },
55
+ setTimeout: (fn, ms) => g.setTimeout(fn, ms),
56
+ clearTimeout: (t) => g.clearTimeout(t),
57
+ setInterval: (fn, ms) => g.setInterval(fn, ms),
58
+ clearInterval: (t) => g.clearInterval(t),
59
+ performance: perf,
60
+ PerformanceObserver: typeof g.PerformanceObserver === "function" ? g.PerformanceObserver : undefined,
61
+ warn: (msg) => {
62
+ try {
63
+ g.console?.warn?.(msg);
64
+ }
65
+ catch {
66
+ /* never */
67
+ }
68
+ },
69
+ };
70
+ }
71
+ export function hex(bytes) {
72
+ let s = "";
73
+ for (const b of bytes)
74
+ s += b.toString(16).padStart(2, "0");
75
+ return s;
76
+ }
77
+ /** A 16-byte trace id, never all zero. */
78
+ export function newTraceId(env) {
79
+ const id = hex(env.randomBytes(16));
80
+ return /^0+$/.test(id) ? newTraceId(env) : id;
81
+ }
82
+ /** An 8-byte span id, never all zero. */
83
+ export function newSpanId(env) {
84
+ const id = hex(env.randomBytes(8));
85
+ return /^0+$/.test(id) ? newSpanId(env) : id;
86
+ }
87
+ /** The content of `<meta name="…">`, or undefined. */
88
+ export function meta(env, name) {
89
+ try {
90
+ const v = env.document?.querySelector?.(`meta[name="${name}"]`)?.getAttribute("content");
91
+ return v ? v : undefined;
92
+ }
93
+ catch {
94
+ return undefined;
95
+ }
96
+ }
97
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { type CaptureContext, type TelemetryClient, type TelemetryOptions } from "./client.ts";
2
+ export { createClient, isLocalDevHost, noopClient, BREADCRUMBS_KEY, DEFAULT_ENDPOINT, SDK_NAME, SDK_VERSION, type Breadcrumb, type CaptureContext, type RequestEnd, type RequestHandle, type RequestStart, type TelemetryClient, type TelemetryOptions, } from "./client.ts";
3
+ export { traceIdFrom, shortTraceId, TRACE_HEADER } from "./trace.ts";
4
+ export { classify, type ErrorClass } from "./classify.ts";
5
+ export type { AttrValue, Attrs } from "./otlp.ts";
6
+ export type { Env } from "./env.ts";
7
+ /**
8
+ * Start telemetry for this page and return the client. Once per page: a
9
+ * second call returns the first client unchanged, so a library (the shell)
10
+ * and the app can both call it without double-reporting.
11
+ */
12
+ export declare function init(opts?: TelemetryOptions): TelemetryClient;
13
+ /** The page's client, or undefined before init. */
14
+ export declare function getClient(): TelemetryClient | undefined;
15
+ /** Forget the page's client (shutting it down). For tests and hot reload. */
16
+ export declare function resetClient(): void;
17
+ /** Report an error through the page's client. A no-op before init. Never throws. */
18
+ export declare function captureException(err: unknown, ctx?: CaptureContext): void;
19
+ /** Tell telemetry the route changed. A no-op before init. */
20
+ export declare function trackRoute(path: string): void;
21
+ type ClientRef = TelemetryClient | (() => TelemetryClient | undefined) | undefined;
22
+ /**
23
+ * A fetch that reports reachability: a request that gets no answer, times
24
+ * out or answers 5xx becomes a `client.request.failed` record, every request
25
+ * a breadcrumb, and a sampled one a CLIENT span (with `traceparent` when the
26
+ * request is same-origin). Behaves exactly like the fetch it wraps otherwise.
27
+ *
28
+ * const api = wrapFetch(); // global fetch, page client
29
+ * await api("/api/thing");
30
+ *
31
+ * The client is looked up per request, so wrapping before `init` is fine.
32
+ */
33
+ export declare function wrapFetch(fetchImpl?: typeof fetch, client?: ClientRef): typeof fetch;
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAA4B,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEzH,OAAO,EACL,YAAY,EACZ,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAIpC;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,IAAI,GAAE,gBAAqB,GAAG,eAAe,CAIjE;AAED,mDAAmD;AACnD,wBAAgB,SAAS,IAAI,eAAe,GAAG,SAAS,CAEvD;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,IAAI,IAAI,CAGlC;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,cAAc,GAAG,IAAI,CAEzE;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED,KAAK,SAAS,GAAG,eAAe,GAAG,CAAC,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;AAOnF;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,KAAK,CA2BpF"}
package/dist/index.js ADDED
@@ -0,0 +1,89 @@
1
+ // @xeonr/telemetry-web — browser telemetry for Xeonr consoles, to Lantern.
2
+ //
3
+ // import { init } from "@xeonr/telemetry-web";
4
+ // init({ service: "functions-ui", product: "functions" });
5
+ //
6
+ // console-shell's ConsoleProvider does this for every console; call it
7
+ // yourself only on a page that does not mount the shell.
8
+ import { createClient, noopClient } from "./client.js";
9
+ export { createClient, isLocalDevHost, noopClient, BREADCRUMBS_KEY, DEFAULT_ENDPOINT, SDK_NAME, SDK_VERSION, } from "./client.js";
10
+ export { traceIdFrom, shortTraceId, TRACE_HEADER } from "./trace.js";
11
+ export { classify } from "./classify.js";
12
+ let current;
13
+ /**
14
+ * Start telemetry for this page and return the client. Once per page: a
15
+ * second call returns the first client unchanged, so a library (the shell)
16
+ * and the app can both call it without double-reporting.
17
+ */
18
+ export function init(opts = {}) {
19
+ if (current)
20
+ return current;
21
+ current = createClient(opts);
22
+ return current;
23
+ }
24
+ /** The page's client, or undefined before init. */
25
+ export function getClient() {
26
+ return current;
27
+ }
28
+ /** Forget the page's client (shutting it down). For tests and hot reload. */
29
+ export function resetClient() {
30
+ current?.shutdown();
31
+ current = undefined;
32
+ }
33
+ /** Report an error through the page's client. A no-op before init. Never throws. */
34
+ export function captureException(err, ctx) {
35
+ current?.captureException(err, ctx);
36
+ }
37
+ /** Tell telemetry the route changed. A no-op before init. */
38
+ export function trackRoute(path) {
39
+ current?.trackRoute(path);
40
+ }
41
+ function resolve(ref) {
42
+ const c = typeof ref === "function" ? ref() : (ref ?? current);
43
+ return c ?? noopClient();
44
+ }
45
+ /**
46
+ * A fetch that reports reachability: a request that gets no answer, times
47
+ * out or answers 5xx becomes a `client.request.failed` record, every request
48
+ * a breadcrumb, and a sampled one a CLIENT span (with `traceparent` when the
49
+ * request is same-origin). Behaves exactly like the fetch it wraps otherwise.
50
+ *
51
+ * const api = wrapFetch(); // global fetch, page client
52
+ * await api("/api/thing");
53
+ *
54
+ * The client is looked up per request, so wrapping before `init` is fine.
55
+ */
56
+ export function wrapFetch(fetchImpl, client) {
57
+ const base = fetchImpl ?? ((...a) => globalThis.fetch(...a));
58
+ const wrapped = async (input, init) => {
59
+ const c = resolve(client);
60
+ if (!c.enabled)
61
+ return base(input, init);
62
+ const isReq = typeof Request === "function" && input instanceof Request;
63
+ const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
64
+ if (c.isOwnUrl(url))
65
+ return base(input, init);
66
+ const method = init?.method ?? (isReq ? input.method : "GET");
67
+ const h = c.beginRequest({ url, method });
68
+ let nextInit = init;
69
+ if (Object.keys(h.headers).length > 0) {
70
+ const headers = new Headers(init?.headers ?? (isReq ? input.headers : undefined));
71
+ for (const [k, v] of Object.entries(h.headers))
72
+ if (!headers.has(k))
73
+ headers.set(k, v);
74
+ nextInit = { ...init, headers };
75
+ }
76
+ let res;
77
+ try {
78
+ res = await base(input, nextInit);
79
+ }
80
+ catch (err) {
81
+ h.end({ error: err });
82
+ throw err;
83
+ }
84
+ h.end({ status: res.status, traceId: res.headers.get("x-trace-id") });
85
+ return res;
86
+ };
87
+ return wrapped;
88
+ }
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/otlp.d.ts ADDED
@@ -0,0 +1,124 @@
1
+ export type AttrValue = string | number | boolean | readonly string[];
2
+ export type Attrs = Record<string, AttrValue | undefined | null>;
3
+ export type AnyValue = {
4
+ stringValue: string;
5
+ } | {
6
+ intValue: string;
7
+ } | {
8
+ doubleValue: number;
9
+ } | {
10
+ boolValue: boolean;
11
+ } | {
12
+ arrayValue: {
13
+ values: {
14
+ stringValue: string;
15
+ }[];
16
+ };
17
+ };
18
+ export interface KeyValue {
19
+ key: string;
20
+ value: AnyValue;
21
+ }
22
+ /** Severity numbers from the OTLP log data model. */
23
+ export declare const SEVERITY: {
24
+ readonly DEBUG: 5;
25
+ readonly INFO: 9;
26
+ readonly WARN: 13;
27
+ readonly ERROR: 17;
28
+ };
29
+ export type SeverityName = keyof typeof SEVERITY;
30
+ /** SPAN_KIND_CLIENT. */
31
+ export declare const SPAN_KIND_CLIENT = 3;
32
+ /** STATUS_CODE_UNSET / OK / ERROR. */
33
+ export declare const STATUS_UNSET = 0;
34
+ export declare const STATUS_ERROR = 2;
35
+ export interface LogRecord {
36
+ timeUnixNano: string;
37
+ observedTimeUnixNano: string;
38
+ severityNumber: number;
39
+ severityText: SeverityName;
40
+ body: {
41
+ stringValue: string;
42
+ };
43
+ attributes: KeyValue[];
44
+ traceId?: string;
45
+ spanId?: string;
46
+ }
47
+ export interface Span {
48
+ traceId: string;
49
+ spanId: string;
50
+ parentSpanId?: string;
51
+ name: string;
52
+ kind: number;
53
+ startTimeUnixNano: string;
54
+ endTimeUnixNano: string;
55
+ attributes: KeyValue[];
56
+ status: {
57
+ code: number;
58
+ message?: string;
59
+ };
60
+ }
61
+ export interface Scope {
62
+ name: string;
63
+ version: string;
64
+ }
65
+ export interface LogsPayload {
66
+ resourceLogs: {
67
+ resource: {
68
+ attributes: KeyValue[];
69
+ };
70
+ scopeLogs: {
71
+ scope: Scope;
72
+ logRecords: LogRecord[];
73
+ }[];
74
+ }[];
75
+ }
76
+ export interface TracesPayload {
77
+ resourceSpans: {
78
+ resource: {
79
+ attributes: KeyValue[];
80
+ };
81
+ scopeSpans: {
82
+ scope: Scope;
83
+ spans: Span[];
84
+ }[];
85
+ }[];
86
+ }
87
+ /**
88
+ * One attribute value in OTLP JSON. Integers are intValue (as a string, per the
89
+ * int64 mapping); other numbers doubleValue; a string list is an arrayValue.
90
+ */
91
+ export declare function anyValue(v: AttrValue): AnyValue;
92
+ /** An attribute map as OTLP's KeyValue list, dropping undefined/null and empty keys. */
93
+ export declare function attributes(a: Attrs): KeyValue[];
94
+ /**
95
+ * Epoch milliseconds (possibly fractional, from performance.timeOrigin +
96
+ * performance.now()) as OTLP's nanosecond string. Goes through whole
97
+ * microseconds so the arithmetic stays inside a double's exact range.
98
+ */
99
+ export declare function nanos(epochMs: number): string;
100
+ /** A W3C trace id, or undefined: lower-cased, dashes removed, never all zero. */
101
+ export declare function normaliseTraceId(raw: string | null | undefined): string | undefined;
102
+ export interface LogInput {
103
+ time: number;
104
+ severity: SeverityName;
105
+ body: string;
106
+ attrs: Attrs;
107
+ traceId?: string | undefined;
108
+ spanId?: string | undefined;
109
+ }
110
+ export declare function logRecord(l: LogInput): LogRecord;
111
+ export interface SpanInput {
112
+ traceId: string;
113
+ spanId: string;
114
+ parentSpanId?: string | undefined;
115
+ name: string;
116
+ start: number;
117
+ end: number;
118
+ attrs: Attrs;
119
+ error?: string | undefined;
120
+ }
121
+ export declare function clientSpan(s: SpanInput): Span;
122
+ export declare function logsPayload(resource: KeyValue[], scope: Scope, records: LogRecord[]): LogsPayload;
123
+ export declare function tracesPayload(resource: KeyValue[], scope: Scope, spans: Span[]): TracesPayload;
124
+ //# sourceMappingURL=otlp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp.d.ts","sourceRoot":"","sources":["../src/otlp.ts"],"names":[],"mappings":"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"}
package/dist/otlp.js ADDED
@@ -0,0 +1,105 @@
1
+ // OTLP/HTTP JSON, by hand. The OpenTelemetry JS SDK is ~60 KiB before it
2
+ // sends a byte, and every console pays for whatever this package weighs, so
3
+ // the two payload shapes Lantern's ingest reads are written out here instead.
4
+ //
5
+ // The encoding is protobuf's canonical JSON mapping of the OTLP protos:
6
+ // 64-bit integers (timestamps, intValue) are decimal strings, ids are lower
7
+ // hex, enums are their numbers. https://opentelemetry.io/docs/specs/otlp/#json-protobuf-encoding
8
+ /** Severity numbers from the OTLP log data model. */
9
+ export const SEVERITY = {
10
+ DEBUG: 5,
11
+ INFO: 9,
12
+ WARN: 13,
13
+ ERROR: 17,
14
+ };
15
+ /** SPAN_KIND_CLIENT. */
16
+ export const SPAN_KIND_CLIENT = 3;
17
+ /** STATUS_CODE_UNSET / OK / ERROR. */
18
+ export const STATUS_UNSET = 0;
19
+ export const STATUS_ERROR = 2;
20
+ /**
21
+ * One attribute value in OTLP JSON. Integers are intValue (as a string, per the
22
+ * int64 mapping); other numbers doubleValue; a string list is an arrayValue.
23
+ */
24
+ export function anyValue(v) {
25
+ if (typeof v !== "string" && typeof v !== "number" && typeof v !== "boolean") {
26
+ return { arrayValue: { values: v.map((x) => ({ stringValue: String(x) })) } };
27
+ }
28
+ if (typeof v === "boolean")
29
+ return { boolValue: v };
30
+ if (typeof v === "number") {
31
+ if (Number.isInteger(v) && Number.isSafeInteger(v))
32
+ return { intValue: String(v) };
33
+ return { doubleValue: Number.isFinite(v) ? v : 0 };
34
+ }
35
+ return { stringValue: v };
36
+ }
37
+ /** An attribute map as OTLP's KeyValue list, dropping undefined/null and empty keys. */
38
+ export function attributes(a) {
39
+ const out = [];
40
+ for (const key of Object.keys(a)) {
41
+ const v = a[key];
42
+ if (v === undefined || v === null || key === "")
43
+ continue;
44
+ out.push({ key, value: anyValue(v) });
45
+ }
46
+ return out;
47
+ }
48
+ /**
49
+ * Epoch milliseconds (possibly fractional, from performance.timeOrigin +
50
+ * performance.now()) as OTLP's nanosecond string. Goes through whole
51
+ * microseconds so the arithmetic stays inside a double's exact range.
52
+ */
53
+ export function nanos(epochMs) {
54
+ const us = Math.round(epochMs * 1000);
55
+ return us <= 0 ? "0" : `${us}000`;
56
+ }
57
+ const HEX32 = /^[0-9a-f]{32}$/;
58
+ const ZERO32 = "0".repeat(32);
59
+ /** A W3C trace id, or undefined: lower-cased, dashes removed, never all zero. */
60
+ export function normaliseTraceId(raw) {
61
+ if (!raw)
62
+ return undefined;
63
+ const id = raw.trim().toLowerCase().replace(/-/g, "");
64
+ return HEX32.test(id) && id !== ZERO32 ? id : undefined;
65
+ }
66
+ export function logRecord(l) {
67
+ const t = nanos(l.time);
68
+ const rec = {
69
+ timeUnixNano: t,
70
+ observedTimeUnixNano: t,
71
+ severityNumber: SEVERITY[l.severity],
72
+ severityText: l.severity,
73
+ body: { stringValue: l.body },
74
+ attributes: attributes(l.attrs),
75
+ };
76
+ const tid = normaliseTraceId(l.traceId);
77
+ if (tid) {
78
+ rec.traceId = tid;
79
+ if (l.spanId && /^[0-9a-f]{16}$/.test(l.spanId))
80
+ rec.spanId = l.spanId;
81
+ }
82
+ return rec;
83
+ }
84
+ export function clientSpan(s) {
85
+ const span = {
86
+ traceId: s.traceId,
87
+ spanId: s.spanId,
88
+ name: s.name,
89
+ kind: SPAN_KIND_CLIENT,
90
+ startTimeUnixNano: nanos(s.start),
91
+ endTimeUnixNano: nanos(Math.max(s.end, s.start)),
92
+ attributes: attributes(s.attrs),
93
+ status: s.error === undefined ? { code: STATUS_UNSET } : { code: STATUS_ERROR, message: s.error },
94
+ };
95
+ if (s.parentSpanId)
96
+ span.parentSpanId = s.parentSpanId;
97
+ return span;
98
+ }
99
+ export function logsPayload(resource, scope, records) {
100
+ return { resourceLogs: [{ resource: { attributes: resource }, scopeLogs: [{ scope, logRecords: records }] }] };
101
+ }
102
+ export function tracesPayload(resource, scope, spans) {
103
+ return { resourceSpans: [{ resource: { attributes: resource }, scopeSpans: [{ scope, spans }] }] };
104
+ }
105
+ //# sourceMappingURL=otlp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp.js","sourceRoot":"","sources":["../src/otlp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import type { Env } from "./env.ts";
2
+ import { type KeyValue, type LogRecord, type Scope, type Span } from "./otlp.ts";
3
+ /** One queued record. Compact keys: these are what sit in localStorage. */
4
+ export interface Item {
5
+ /** "l" log record, "s" span */
6
+ k: "l" | "s";
7
+ /** service.version it was recorded under, so a replay after a deploy keeps its release */
8
+ v: string;
9
+ /** error-or-worse: evicted last */
10
+ e?: 1;
11
+ r: LogRecord | Span;
12
+ }
13
+ interface Stored {
14
+ retryAt: number;
15
+ items: Item[];
16
+ }
17
+ export interface DeliveryOptions {
18
+ endpoint: string;
19
+ service: string;
20
+ scope: Scope;
21
+ /** The resource attributes for records of a given service.version. */
22
+ resource(version: string): KeyValue[];
23
+ flushIntervalMs?: number | undefined;
24
+ maxBatch?: number | undefined;
25
+ maxStored?: number | undefined;
26
+ maxStoredBytes?: number | undefined;
27
+ storageKey?: string | undefined;
28
+ }
29
+ export declare const DEFAULTS: {
30
+ readonly flushIntervalMs: 5000;
31
+ readonly maxBatch: 50;
32
+ readonly maxStored: 200;
33
+ readonly maxStoredBytes: number;
34
+ readonly storageKey: "xeonr.telemetry.buffer";
35
+ /** in memory, before the oldest give way: a render loop must not eat the tab */
36
+ readonly maxMemory: 1000;
37
+ /** records per request */
38
+ readonly maxRequest: 500;
39
+ /** sendBeacon's quota is 64 KiB per page; stay under it per call */
40
+ readonly beaconBytes: number;
41
+ /** fetch keepalive has the same 64 KiB budget */
42
+ readonly keepaliveBytes: number;
43
+ readonly maxBackoffMs: number;
44
+ };
45
+ /** Retry-After as milliseconds: delta-seconds or an HTTP date. */
46
+ export declare function retryAfterMs(h: string | null | undefined, now: number): number | undefined;
47
+ /** Bound a list to `max` items and `maxBytes` of JSON, dropping the oldest non-error records first, then the oldest. */
48
+ export declare function bound(items: Item[], max: number, maxBytes: number): Item[];
49
+ export declare class Delivery {
50
+ private readonly env;
51
+ private readonly o;
52
+ private mem;
53
+ private sending;
54
+ private failures;
55
+ private timer;
56
+ private soon;
57
+ private warned;
58
+ /** Called right before the hide-time send, so last-moment records (web vitals) make it. */
59
+ beforeHide: (() => void) | undefined;
60
+ constructor(env: Env, o: DeliveryOptions);
61
+ /** Timers and page lifecycle listeners, plus a replay of whatever a previous page left behind. */
62
+ start(): void;
63
+ stop(): void;
64
+ get pending(): number;
65
+ push(item: Item): void;
66
+ private schedule;
67
+ private online;
68
+ readStore(): Stored;
69
+ private writeStore;
70
+ /** Keep records for a later attempt. */
71
+ persist(items: Item[], retryAt?: number): void;
72
+ /** Claim stored records for sending, so another tab does not send them too. */
73
+ private takeStored;
74
+ private backoff;
75
+ private url;
76
+ /** The bodies for a set of items: at most one logs and one traces payload, a resource entry per release. */
77
+ bodies(items: Item[]): {
78
+ signal: "logs" | "traces";
79
+ items: Item[];
80
+ body: string;
81
+ }[];
82
+ private post;
83
+ /** Send what is queued (and what an earlier page left behind). Never rejects. */
84
+ flush(): Promise<void>;
85
+ /** The page is going away (or into the background): everything left goes by beacon now. */
86
+ hide(): void;
87
+ flushBeacon(): void;
88
+ /** Items in groups whose payload stays under the beacon's 64 KiB. */
89
+ private chunks;
90
+ }
91
+ export {};
92
+ //# sourceMappingURL=queue.d.ts.map