@tetrascience-npm/tetrascience-react-ui 1.0.0-beta.134.1 → 1.0.0-beta.136.1

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 (53) hide show
  1. package/dist/components/ui/text.d.ts +63 -0
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.css +1 -1
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +263 -260
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.tailwind.css +1 -1
  8. package/dist/telemetry/context.cjs +2 -0
  9. package/dist/telemetry/context.cjs.map +1 -0
  10. package/dist/telemetry/context.d.ts +6 -0
  11. package/dist/telemetry/context.js +6 -0
  12. package/dist/telemetry/context.js.map +1 -0
  13. package/dist/telemetry/error-boundary.cjs +2 -0
  14. package/dist/telemetry/error-boundary.cjs.map +1 -0
  15. package/dist/telemetry/error-boundary.d.ts +39 -0
  16. package/dist/telemetry/error-boundary.js +33 -0
  17. package/dist/telemetry/error-boundary.js.map +1 -0
  18. package/dist/telemetry/events.cjs +2 -0
  19. package/dist/telemetry/events.cjs.map +1 -0
  20. package/dist/telemetry/events.d.ts +15 -0
  21. package/dist/telemetry/events.js +13 -0
  22. package/dist/telemetry/events.js.map +1 -0
  23. package/dist/telemetry/facade.cjs +2 -0
  24. package/dist/telemetry/facade.cjs.map +1 -0
  25. package/dist/telemetry/facade.d.ts +15 -0
  26. package/dist/telemetry/facade.js +86 -0
  27. package/dist/telemetry/facade.js.map +1 -0
  28. package/dist/telemetry/global-handlers.cjs +2 -0
  29. package/dist/telemetry/global-handlers.cjs.map +1 -0
  30. package/dist/telemetry/global-handlers.d.ts +25 -0
  31. package/dist/telemetry/global-handlers.js +31 -0
  32. package/dist/telemetry/global-handlers.js.map +1 -0
  33. package/dist/telemetry/index.d.ts +27 -0
  34. package/dist/telemetry/telemetry-provider.cjs +2 -0
  35. package/dist/telemetry/telemetry-provider.cjs.map +1 -0
  36. package/dist/telemetry/telemetry-provider.d.ts +36 -0
  37. package/dist/telemetry/telemetry-provider.js +65 -0
  38. package/dist/telemetry/telemetry-provider.js.map +1 -0
  39. package/dist/telemetry/types.d.ts +140 -0
  40. package/dist/telemetry/use-tetra-events.cjs +2 -0
  41. package/dist/telemetry/use-tetra-events.cjs.map +1 -0
  42. package/dist/telemetry/use-tetra-events.d.ts +19 -0
  43. package/dist/telemetry/use-tetra-events.js +55 -0
  44. package/dist/telemetry/use-tetra-events.js.map +1 -0
  45. package/dist/telemetry.cjs +2 -0
  46. package/dist/telemetry.cjs.map +1 -0
  47. package/dist/telemetry.js +24 -0
  48. package/dist/telemetry.js.map +1 -0
  49. package/dist/ui/text.cjs +2 -0
  50. package/dist/ui/text.cjs.map +1 -0
  51. package/dist/ui/text.js +88 -0
  52. package/dist/ui/text.js.map +1 -0
  53. package/package.json +19 -2
@@ -0,0 +1,140 @@
1
+ import { LogRecordProcessor } from '@opentelemetry/sdk-logs';
2
+ import { RequestTrackingLogger } from '@tetrascience-npm/request';
3
+ import { ArtifactType, MetricsOptions, StartSpanOptions, Telemetry, TelemetryArtifact, TelemetryTracingOptions, TetraSpan, TrackErrorContext } from '@tetrascience-npm/request/telemetry';
4
+ import { ReactNode } from 'react';
5
+ /** Props for {@link TelemetryProvider}. */
6
+ export interface TelemetryProviderProps {
7
+ /**
8
+ * Artifact identity from the host mount props (`hostProps.artifact`).
9
+ * Fields missing here fall back to {@link TelemetryProviderProps.manifest}.
10
+ */
11
+ artifact?: Partial<TelemetryArtifact>;
12
+ /**
13
+ * Manifest fallback for standalone dev, e.g. `import manifest from './manifest.json'`.
14
+ * Used field-by-field wherever `artifact` is incomplete.
15
+ */
16
+ manifest?: Partial<TelemetryArtifact>;
17
+ /**
18
+ * What KIND of artifact is mounting this — `"data-app"` unless stated.
19
+ *
20
+ * The core distro refuses to guess this (it serves data apps and connectors
21
+ * alike, and mislabelling one as the other is worse than emitting no kind at
22
+ * all). This kit can: it is React bindings for a browser mount, and on this
23
+ * platform that is a data app. The default is a DECLARATION by a component
24
+ * only data apps mount, not a fallback for producers that do not know what
25
+ * they are — and anything else mounting it says so here.
26
+ *
27
+ * `artifact.type` / `manifest.type` win over this when present.
28
+ */
29
+ artifactType?: ArtifactType;
30
+ /**
31
+ * Org slug hint. Producer-asserted only — the gateway stamps the
32
+ * authenticated org server-side and that value wins (SW-2319).
33
+ */
34
+ orgSlug?: string;
35
+ /**
36
+ * Resolve the current user's auth token for the `ts-auth-token` header.
37
+ *
38
+ * REQUIRED for a browser data app to deliver anything. The gateway reads
39
+ * credentials from headers only, and its CORS config (`origin: ['*']`, no
40
+ * `credentials`) means a browser cannot send a session cookie — so without
41
+ * this every batch 401s and the app emits into the void.
42
+ *
43
+ * Called on every export, so pass a function that reads the host's CURRENT
44
+ * token rather than a captured string: a data app outlives any single
45
+ * short-lived token.
46
+ */
47
+ getAuthToken?: () => string | undefined | Promise<string | undefined>;
48
+ /** OTLP/HTTP logs URL override. Default: the core's endpoint resolution. */
49
+ logsUrl?: string;
50
+ /**
51
+ * Master switch. Default: `window.env.TELEMETRY_ENABLED` when the host
52
+ * provides it, otherwise `true`. When disabled the context client is a
53
+ * no-op — no OTel provider, no exporter, no network, no buffers.
54
+ */
55
+ enabled?: boolean;
56
+ /**
57
+ * Route records to the stock console exporter in addition to OTLP, so
58
+ * authors see the exact pre-gateway payload. Default:
59
+ * `window.env.TELEMETRY_DEBUG` when the host provides it, otherwise `false`.
60
+ */
61
+ debug?: boolean;
62
+ /** Log record processors override (tests, custom pipelines). */
63
+ processors?: LogRecordProcessor[];
64
+ /**
65
+ * Distributed tracing (SW-2478). Off unless `tracing.enabled` is true —
66
+ * tracing adds a second exporter and a per-span network cost, so an app
67
+ * opts in rather than acquiring it by upgrading the library.
68
+ */
69
+ tracing?: TelemetryTracingOptions;
70
+ /**
71
+ * OTel metrics (SW-2478). Off unless `metrics.enabled` is true, for the same
72
+ * reason tracing is: a metrics reader is a recurring timer and a recurring
73
+ * export.
74
+ *
75
+ * Forwarded here rather than left to the core's defaults because apps build
76
+ * their client through THIS provider — an option the provider does not pass
77
+ * through is one no React data app can ever set, which is how
78
+ * `gauge()`/`histogram()` came to be callable but permanently inert.
79
+ */
80
+ metrics?: MetricsOptions;
81
+ /**
82
+ * Cap on how long `flush()` and `shutdown()` wait for the exporter, in ms.
83
+ * Forwarded to the core, which defaults to 5000. Worth setting when the
84
+ * host unmounts on a route change and cannot afford a 5s teardown.
85
+ */
86
+ flushTimeoutMillis?: number;
87
+ /** Logger for setup failures and stripped attributes. */
88
+ logger?: RequestTrackingLogger;
89
+ children?: ReactNode;
90
+ }
91
+ /** Bound emitters returned by {@link useTetraEvents}. */
92
+ export interface TetraEvents {
93
+ /** Record a product event (`App[:Page][:Object]:Action`). */
94
+ trackEvent(name: string, attributes?: Record<string, unknown>, body?: unknown): void;
95
+ /** Record an error event with `exception.*` attributes. */
96
+ trackError(error: unknown, context?: TrackErrorContext): void;
97
+ /**
98
+ * Start a span (SW-2478). No-op unless the provider was given
99
+ * `tracing.enabled`. The caller must `end()` it — prefer `withSpan`.
100
+ */
101
+ startSpan(name: string, options?: StartSpanOptions): TetraSpan;
102
+ /**
103
+ * Run `fn` inside a span, ending it when the work settles (promises
104
+ * included) and on the error path. Errors are recorded and re-thrown.
105
+ */
106
+ withSpan<T>(name: string, fn: (span: TetraSpan) => T, options?: StartSpanOptions): T;
107
+ /**
108
+ * Add to a running total that only ever goes up (SW-2478). No-op unless the
109
+ * provider was given `metrics.enabled`.
110
+ *
111
+ * The core client and the Python distro have both exposed this from the
112
+ * start; the React bindings did not, so a data app could reach `gauge`,
113
+ * `histogram` and `upDownCounter` but not the most basic instrument of the
114
+ * four. Found by the bindings' own e2e — `events.counter is not a function`.
115
+ */
116
+ counter(name: string, delta?: number, attributes?: Record<string, unknown>): void;
117
+ /**
118
+ * Record the current value of something (SW-2478). No-op unless the
119
+ * provider was given `metrics.enabled`.
120
+ *
121
+ * Unlike {@link TetraEvents.trackEvent}, this carries a VALUE — counting is
122
+ * one-record-one-increment and cannot express "the reading right now".
123
+ */
124
+ gauge(name: string, value: number, attributes?: Record<string, unknown>): void;
125
+ /** Record a distribution sample — a duration, a size. Same opt-in as `gauge`. */
126
+ histogram(name: string, value: number, attributes?: Record<string, unknown>): void;
127
+ /** Add to a running total that can go both ways. Same opt-in as `gauge`. */
128
+ upDownCounter(name: string, delta: number, attributes?: Record<string, unknown>): void;
129
+ }
130
+ /**
131
+ * The context client: a stable façade whose underlying per-instance client is
132
+ * attached by {@link TelemetryProvider} in an effect. Identity is stable for
133
+ * the provider's lifetime, so hook callbacks never change identity.
134
+ */
135
+ export type TelemetryFacade = Telemetry & {
136
+ /** @internal */
137
+ attach(client: Telemetry): void;
138
+ /** @internal */
139
+ detach(client: Telemetry): void;
140
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react"),d=require("./context.cjs"),k=require("./facade.cjs");let a=!1;function E(){a||(a=!0,!(typeof process<"u"&&process.env?.NODE_ENV==="production")&&console.warn("[telemetry] useTetraEvents() called outside <TelemetryProvider> — events are dropped."))}function m(){a=!1}function p(){const e=s.useContext(d.TelemetryContext);return e||E(),e??k.NOOP_TELEMETRY}function b(){const e=p(),o=s.useCallback((t,n,r)=>{e.trackEvent(t,n,r)},[e]),c=s.useCallback((t,n)=>{e.trackError(t,n)},[e]),u=s.useCallback((t,n)=>e.startSpan(t,n),[e]),l=s.useCallback((t,n,r)=>e.counter(t,n,r),[e]),i=s.useCallback((t,n,r)=>e.gauge(t,n,r),[e]),C=s.useCallback((t,n,r)=>e.histogram(t,n,r),[e]),T=s.useCallback((t,n,r)=>e.upDownCounter(t,n,r),[e]),f=s.useCallback((t,n,r)=>e.withSpan(t,n,r),[e]);return s.useMemo(()=>({trackEvent:o,trackError:c,startSpan:u,withSpan:f,counter:l,gauge:i,histogram:C,upDownCounter:T}),[o,c,u,f,l,i,C,T])}exports.__resetTelemetryWarningForTests=m;exports.useTelemetryClient=p;exports.useTetraEvents=b;
2
+ //# sourceMappingURL=use-tetra-events.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tetra-events.cjs","sources":["../../src/telemetry/use-tetra-events.ts"],"sourcesContent":["import { useCallback, useContext, useMemo } from \"react\";\n\nimport { TelemetryContext } from \"./context\";\nimport { NOOP_TELEMETRY } from \"./facade\";\n\nimport type { TetraEvents } from \"./types\";\nimport type { StartSpanOptions, Telemetry, TetraSpan, TrackErrorContext } from \"@tetrascience-npm/request/telemetry\";\n\nlet warned = false;\n\n/**\n * Outside a provider the hook no-ops with one development warning rather than\n * throwing. Rationale: the core's contract is that telemetry never throws into\n * application code — a missing provider is an instrumentation defect, and\n * crashing a customer's app over it inverts the risk. The warning (dev only,\n * once per module instance) keeps the mistake visible during development and\n * is asserted in tests.\n */\nfunction warnOnce(): void {\n if (warned) return;\n warned = true;\n if (typeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\") return;\n\n console.warn(\"[telemetry] useTetraEvents() called outside <TelemetryProvider> — events are dropped.\");\n}\n\n/** @internal test seam: reset the once-per-module warning latch. */\nexport function __resetTelemetryWarningForTests(): void {\n warned = false;\n}\n\n/** Access the raw context client — e.g. to wire {@link installGlobalErrorHandlers}. */\nexport function useTelemetryClient(): Telemetry {\n const client = useContext(TelemetryContext);\n if (!client) warnOnce();\n return client ?? NOOP_TELEMETRY;\n}\n\n/**\n * The app-facing emitters, bound to the provider's client.\n *\n * Identities are stable for the provider's lifetime (the context value is a\n * stable façade), so these are safe as effect dependencies.\n *\n * @example\n * ```tsx\n * const {trackEvent} = useTetraEvents();\n * trackEvent('Sandbox:Chat:Submit', {model});\n * ```\n */\nexport function useTetraEvents(): TetraEvents {\n const client = useTelemetryClient();\n\n const trackEvent = useCallback(\n (name: string, attributes?: Record<string, unknown>, body?: unknown) => {\n client.trackEvent(name, attributes, body);\n },\n [client],\n );\n\n const trackError = useCallback(\n (error: unknown, context?: TrackErrorContext) => {\n client.trackError(error, context);\n },\n [client],\n );\n\n // SW-2478. Every method here delegates to the core rather than\n // re-implementing anything, so React and non-React consumers cannot drift.\n const startSpan = useCallback(\n (name: string, options?: StartSpanOptions) => client.startSpan(name, options),\n [client],\n );\n\n // SW-2478 metrics. Same delegation rule as startSpan: the\n // instrument caching, the value guards and the publishable-name warning all\n // live in the core client, so re-implementing any of it here would give\n // React apps different behaviour from Node ones for the same call.\n const counter = useCallback(\n (name: string, delta?: number, attributes?: Record<string, unknown>) => client.counter(name, delta, attributes),\n [client],\n );\n\n const gauge = useCallback(\n (name: string, value: number, attributes?: Record<string, unknown>) => client.gauge(name, value, attributes),\n [client],\n );\n\n const histogram = useCallback(\n (name: string, value: number, attributes?: Record<string, unknown>) => client.histogram(name, value, attributes),\n [client],\n );\n\n const upDownCounter = useCallback(\n (name: string, delta: number, attributes?: Record<string, unknown>) =>\n client.upDownCounter(name, delta, attributes),\n [client],\n );\n\n const withSpan = useCallback(\n <T>(name: string, fn: (span: TetraSpan) => T, options?: StartSpanOptions) => client.withSpan(name, fn, options),\n [client],\n );\n\n return useMemo(\n () => ({ trackEvent, trackError, startSpan, withSpan, counter, gauge, histogram, upDownCounter }),\n [trackEvent, trackError, startSpan, withSpan, counter, gauge, histogram, upDownCounter],\n );\n}\n"],"names":["warned","warnOnce","__resetTelemetryWarningForTests","useTelemetryClient","client","useContext","TelemetryContext","NOOP_TELEMETRY","useTetraEvents","trackEvent","useCallback","name","attributes","body","trackError","error","context","startSpan","options","counter","delta","gauge","value","histogram","upDownCounter","withSpan","fn","useMemo"],"mappings":"8JAQA,IAAIA,EAAS,GAUb,SAASC,GAAiB,CACpBD,IACJA,EAAS,GACL,SAAO,QAAY,KAAe,QAAQ,KAAK,WAAa,eAEhE,QAAQ,KAAK,uFAAuF,EACtG,CAGO,SAASE,GAAwC,CACtDF,EAAS,EACX,CAGO,SAASG,GAAgC,CAC9C,MAAMC,EAASC,EAAAA,WAAWC,kBAAgB,EAC1C,OAAKF,GAAQH,EAAA,EACNG,GAAUG,EAAAA,cACnB,CAcO,SAASC,GAA8B,CAC5C,MAAMJ,EAASD,EAAA,EAETM,EAAaC,EAAAA,YACjB,CAACC,EAAcC,EAAsCC,IAAmB,CACtET,EAAO,WAAWO,EAAMC,EAAYC,CAAI,CAC1C,EACA,CAACT,CAAM,CAAA,EAGHU,EAAaJ,EAAAA,YACjB,CAACK,EAAgBC,IAAgC,CAC/CZ,EAAO,WAAWW,EAAOC,CAAO,CAClC,EACA,CAACZ,CAAM,CAAA,EAKHa,EAAYP,EAAAA,YAChB,CAACC,EAAcO,IAA+Bd,EAAO,UAAUO,EAAMO,CAAO,EAC5E,CAACd,CAAM,CAAA,EAOHe,EAAUT,EAAAA,YACd,CAACC,EAAcS,EAAgBR,IAAyCR,EAAO,QAAQO,EAAMS,EAAOR,CAAU,EAC9G,CAACR,CAAM,CAAA,EAGHiB,EAAQX,EAAAA,YACZ,CAACC,EAAcW,EAAeV,IAAyCR,EAAO,MAAMO,EAAMW,EAAOV,CAAU,EAC3G,CAACR,CAAM,CAAA,EAGHmB,EAAYb,EAAAA,YAChB,CAACC,EAAcW,EAAeV,IAAyCR,EAAO,UAAUO,EAAMW,EAAOV,CAAU,EAC/G,CAACR,CAAM,CAAA,EAGHoB,EAAgBd,EAAAA,YACpB,CAACC,EAAcS,EAAeR,IAC5BR,EAAO,cAAcO,EAAMS,EAAOR,CAAU,EAC9C,CAACR,CAAM,CAAA,EAGHqB,EAAWf,EAAAA,YACf,CAAIC,EAAce,EAA4BR,IAA+Bd,EAAO,SAASO,EAAMe,EAAIR,CAAO,EAC9G,CAACd,CAAM,CAAA,EAGT,OAAOuB,EAAAA,QACL,KAAO,CAAE,WAAAlB,EAAY,WAAAK,EAAY,UAAAG,EAAW,SAAAQ,EAAU,QAAAN,EAAS,MAAAE,EAAO,UAAAE,EAAW,cAAAC,IACjF,CAACf,EAAYK,EAAYG,EAAWQ,EAAUN,EAASE,EAAOE,EAAWC,CAAa,CAAA,CAE1F"}
@@ -0,0 +1,19 @@
1
+ import { TetraEvents } from './types';
2
+ import { Telemetry } from '@tetrascience-npm/request/telemetry';
3
+ /** @internal test seam: reset the once-per-module warning latch. */
4
+ export declare function __resetTelemetryWarningForTests(): void;
5
+ /** Access the raw context client — e.g. to wire {@link installGlobalErrorHandlers}. */
6
+ export declare function useTelemetryClient(): Telemetry;
7
+ /**
8
+ * The app-facing emitters, bound to the provider's client.
9
+ *
10
+ * Identities are stable for the provider's lifetime (the context value is a
11
+ * stable façade), so these are safe as effect dependencies.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * const {trackEvent} = useTetraEvents();
16
+ * trackEvent('Sandbox:Chat:Submit', {model});
17
+ * ```
18
+ */
19
+ export declare function useTetraEvents(): TetraEvents;
@@ -0,0 +1,55 @@
1
+ import { useContext as E, useCallback as o, useMemo as d } from "react";
2
+ import { TelemetryContext as T } from "./context.js";
3
+ import { NOOP_TELEMETRY as g } from "./facade.js";
4
+ let s = !1;
5
+ function v() {
6
+ s || (s = !0, !(typeof process < "u" && process.env?.NODE_ENV === "production") && console.warn("[telemetry] useTetraEvents() called outside <TelemetryProvider> — events are dropped."));
7
+ }
8
+ function h() {
9
+ s = !1;
10
+ }
11
+ function w() {
12
+ const e = E(T);
13
+ return e || v(), e ?? g;
14
+ }
15
+ function O() {
16
+ const e = w(), c = o(
17
+ (t, r, n) => {
18
+ e.trackEvent(t, r, n);
19
+ },
20
+ [e]
21
+ ), a = o(
22
+ (t, r) => {
23
+ e.trackError(t, r);
24
+ },
25
+ [e]
26
+ ), u = o(
27
+ (t, r) => e.startSpan(t, r),
28
+ [e]
29
+ ), i = o(
30
+ (t, r, n) => e.counter(t, r, n),
31
+ [e]
32
+ ), l = o(
33
+ (t, r, n) => e.gauge(t, r, n),
34
+ [e]
35
+ ), p = o(
36
+ (t, r, n) => e.histogram(t, r, n),
37
+ [e]
38
+ ), f = o(
39
+ (t, r, n) => e.upDownCounter(t, r, n),
40
+ [e]
41
+ ), m = o(
42
+ (t, r, n) => e.withSpan(t, r, n),
43
+ [e]
44
+ );
45
+ return d(
46
+ () => ({ trackEvent: c, trackError: a, startSpan: u, withSpan: m, counter: i, gauge: l, histogram: p, upDownCounter: f }),
47
+ [c, a, u, m, i, l, p, f]
48
+ );
49
+ }
50
+ export {
51
+ h as __resetTelemetryWarningForTests,
52
+ w as useTelemetryClient,
53
+ O as useTetraEvents
54
+ };
55
+ //# sourceMappingURL=use-tetra-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tetra-events.js","sources":["../../src/telemetry/use-tetra-events.ts"],"sourcesContent":["import { useCallback, useContext, useMemo } from \"react\";\n\nimport { TelemetryContext } from \"./context\";\nimport { NOOP_TELEMETRY } from \"./facade\";\n\nimport type { TetraEvents } from \"./types\";\nimport type { StartSpanOptions, Telemetry, TetraSpan, TrackErrorContext } from \"@tetrascience-npm/request/telemetry\";\n\nlet warned = false;\n\n/**\n * Outside a provider the hook no-ops with one development warning rather than\n * throwing. Rationale: the core's contract is that telemetry never throws into\n * application code — a missing provider is an instrumentation defect, and\n * crashing a customer's app over it inverts the risk. The warning (dev only,\n * once per module instance) keeps the mistake visible during development and\n * is asserted in tests.\n */\nfunction warnOnce(): void {\n if (warned) return;\n warned = true;\n if (typeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\") return;\n\n console.warn(\"[telemetry] useTetraEvents() called outside <TelemetryProvider> — events are dropped.\");\n}\n\n/** @internal test seam: reset the once-per-module warning latch. */\nexport function __resetTelemetryWarningForTests(): void {\n warned = false;\n}\n\n/** Access the raw context client — e.g. to wire {@link installGlobalErrorHandlers}. */\nexport function useTelemetryClient(): Telemetry {\n const client = useContext(TelemetryContext);\n if (!client) warnOnce();\n return client ?? NOOP_TELEMETRY;\n}\n\n/**\n * The app-facing emitters, bound to the provider's client.\n *\n * Identities are stable for the provider's lifetime (the context value is a\n * stable façade), so these are safe as effect dependencies.\n *\n * @example\n * ```tsx\n * const {trackEvent} = useTetraEvents();\n * trackEvent('Sandbox:Chat:Submit', {model});\n * ```\n */\nexport function useTetraEvents(): TetraEvents {\n const client = useTelemetryClient();\n\n const trackEvent = useCallback(\n (name: string, attributes?: Record<string, unknown>, body?: unknown) => {\n client.trackEvent(name, attributes, body);\n },\n [client],\n );\n\n const trackError = useCallback(\n (error: unknown, context?: TrackErrorContext) => {\n client.trackError(error, context);\n },\n [client],\n );\n\n // SW-2478. Every method here delegates to the core rather than\n // re-implementing anything, so React and non-React consumers cannot drift.\n const startSpan = useCallback(\n (name: string, options?: StartSpanOptions) => client.startSpan(name, options),\n [client],\n );\n\n // SW-2478 metrics. Same delegation rule as startSpan: the\n // instrument caching, the value guards and the publishable-name warning all\n // live in the core client, so re-implementing any of it here would give\n // React apps different behaviour from Node ones for the same call.\n const counter = useCallback(\n (name: string, delta?: number, attributes?: Record<string, unknown>) => client.counter(name, delta, attributes),\n [client],\n );\n\n const gauge = useCallback(\n (name: string, value: number, attributes?: Record<string, unknown>) => client.gauge(name, value, attributes),\n [client],\n );\n\n const histogram = useCallback(\n (name: string, value: number, attributes?: Record<string, unknown>) => client.histogram(name, value, attributes),\n [client],\n );\n\n const upDownCounter = useCallback(\n (name: string, delta: number, attributes?: Record<string, unknown>) =>\n client.upDownCounter(name, delta, attributes),\n [client],\n );\n\n const withSpan = useCallback(\n <T>(name: string, fn: (span: TetraSpan) => T, options?: StartSpanOptions) => client.withSpan(name, fn, options),\n [client],\n );\n\n return useMemo(\n () => ({ trackEvent, trackError, startSpan, withSpan, counter, gauge, histogram, upDownCounter }),\n [trackEvent, trackError, startSpan, withSpan, counter, gauge, histogram, upDownCounter],\n );\n}\n"],"names":["warned","warnOnce","__resetTelemetryWarningForTests","useTelemetryClient","client","useContext","TelemetryContext","NOOP_TELEMETRY","useTetraEvents","trackEvent","useCallback","name","attributes","body","trackError","error","context","startSpan","options","counter","delta","gauge","value","histogram","upDownCounter","withSpan","fn","useMemo"],"mappings":";;;AAQA,IAAIA,IAAS;AAUb,SAASC,IAAiB;AACxB,EAAID,MACJA,IAAS,IACL,SAAO,UAAY,OAAe,QAAQ,KAAK,aAAa,iBAEhE,QAAQ,KAAK,uFAAuF;AACtG;AAGO,SAASE,IAAwC;AACtD,EAAAF,IAAS;AACX;AAGO,SAASG,IAAgC;AAC9C,QAAMC,IAASC,EAAWC,CAAgB;AAC1C,SAAKF,KAAQH,EAAA,GACNG,KAAUG;AACnB;AAcO,SAASC,IAA8B;AAC5C,QAAMJ,IAASD,EAAA,GAETM,IAAaC;AAAA,IACjB,CAACC,GAAcC,GAAsCC,MAAmB;AACtE,MAAAT,EAAO,WAAWO,GAAMC,GAAYC,CAAI;AAAA,IAC1C;AAAA,IACA,CAACT,CAAM;AAAA,EAAA,GAGHU,IAAaJ;AAAA,IACjB,CAACK,GAAgBC,MAAgC;AAC/C,MAAAZ,EAAO,WAAWW,GAAOC,CAAO;AAAA,IAClC;AAAA,IACA,CAACZ,CAAM;AAAA,EAAA,GAKHa,IAAYP;AAAA,IAChB,CAACC,GAAcO,MAA+Bd,EAAO,UAAUO,GAAMO,CAAO;AAAA,IAC5E,CAACd,CAAM;AAAA,EAAA,GAOHe,IAAUT;AAAA,IACd,CAACC,GAAcS,GAAgBR,MAAyCR,EAAO,QAAQO,GAAMS,GAAOR,CAAU;AAAA,IAC9G,CAACR,CAAM;AAAA,EAAA,GAGHiB,IAAQX;AAAA,IACZ,CAACC,GAAcW,GAAeV,MAAyCR,EAAO,MAAMO,GAAMW,GAAOV,CAAU;AAAA,IAC3G,CAACR,CAAM;AAAA,EAAA,GAGHmB,IAAYb;AAAA,IAChB,CAACC,GAAcW,GAAeV,MAAyCR,EAAO,UAAUO,GAAMW,GAAOV,CAAU;AAAA,IAC/G,CAACR,CAAM;AAAA,EAAA,GAGHoB,IAAgBd;AAAA,IACpB,CAACC,GAAcS,GAAeR,MAC5BR,EAAO,cAAcO,GAAMS,GAAOR,CAAU;AAAA,IAC9C,CAACR,CAAM;AAAA,EAAA,GAGHqB,IAAWf;AAAA,IACf,CAAIC,GAAce,GAA4BR,MAA+Bd,EAAO,SAASO,GAAMe,GAAIR,CAAO;AAAA,IAC9G,CAACd,CAAM;AAAA,EAAA;AAGT,SAAOuB;AAAA,IACL,OAAO,EAAE,YAAAlB,GAAY,YAAAK,GAAY,WAAAG,GAAW,UAAAQ,GAAU,SAAAN,GAAS,OAAAE,GAAO,WAAAE,GAAW,eAAAC;IACjF,CAACf,GAAYK,GAAYG,GAAWQ,GAAUN,GAASE,GAAOE,GAAWC,CAAa;AAAA,EAAA;AAE1F;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./telemetry/events.cjs"),n=require("./telemetry/context.cjs"),a=require("./telemetry/facade.cjs"),r=require("./telemetry/telemetry-provider.cjs"),t=require("./telemetry/use-tetra-events.cjs"),s=require("./telemetry/error-boundary.cjs"),T=require("./telemetry/global-handlers.cjs"),l=require("@tetrascience-npm/request/telemetry");exports.MAX_COMPONENT_STACK_LENGTH=o.MAX_COMPONENT_STACK_LENGTH;exports.TelemetryEvent=o.TelemetryEvent;exports.TelemetryContext=n.TelemetryContext;exports.NOOP_TELEMETRY=a.NOOP_TELEMETRY;exports.createTelemetryFacade=a.createTelemetryFacade;exports.TelemetryProvider=r.TelemetryProvider;exports.readHostFlag=r.readHostFlag;exports.resolveArtifact=r.resolveArtifact;exports.__resetTelemetryWarningForTests=t.__resetTelemetryWarningForTests;exports.useTelemetryClient=t.useTelemetryClient;exports.useTetraEvents=t.useTetraEvents;exports.TSErrorBoundary=s.TSErrorBoundary;exports.installGlobalErrorHandlers=T.installGlobalErrorHandlers;Object.keys(l).forEach(e=>{e!=="default"&&!Object.prototype.hasOwnProperty.call(exports,e)&&Object.defineProperty(exports,e,{enumerable:!0,get:()=>l[e]})});
2
+ //# sourceMappingURL=telemetry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { MAX_COMPONENT_STACK_LENGTH as t, TelemetryEvent as o } from "./telemetry/events.js";
2
+ import { TelemetryContext as m } from "./telemetry/context.js";
3
+ import { NOOP_TELEMETRY as a, createTelemetryFacade as s } from "./telemetry/facade.js";
4
+ import { TelemetryProvider as n, readHostFlag as x, resolveArtifact as E } from "./telemetry/telemetry-provider.js";
5
+ import { __resetTelemetryWarningForTests as y, useTelemetryClient as _, useTetraEvents as d } from "./telemetry/use-tetra-events.js";
6
+ import { TSErrorBoundary as v } from "./telemetry/error-boundary.js";
7
+ import { installGlobalErrorHandlers as N } from "./telemetry/global-handlers.js";
8
+ export * from "@tetrascience-npm/request/telemetry";
9
+ export {
10
+ t as MAX_COMPONENT_STACK_LENGTH,
11
+ a as NOOP_TELEMETRY,
12
+ v as TSErrorBoundary,
13
+ m as TelemetryContext,
14
+ o as TelemetryEvent,
15
+ n as TelemetryProvider,
16
+ y as __resetTelemetryWarningForTests,
17
+ s as createTelemetryFacade,
18
+ N as installGlobalErrorHandlers,
19
+ x as readHostFlag,
20
+ E as resolveArtifact,
21
+ _ as useTelemetryClient,
22
+ d as useTetraEvents
23
+ };
24
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),b=require("class-variance-authority"),i=require("../lib/utils.cjs"),r=b.cva("",{variants:{variant:{display:"gap-2.5 text-3xl font-bold tracking-tight","title-lg":"gap-2.5 text-2xl font-bold tracking-tight",title:"gap-2 text-xl font-semibold","title-sm":"gap-2 text-lg font-semibold","title-xs":"gap-1.5 text-base font-semibold",body:"gap-1.5 text-sm",label:"gap-1.5 text-sm font-medium",caption:"gap-1 text-xs",overline:"gap-1 text-2xs font-semibold tracking-widest uppercase"},state:{default:"",muted:"text-muted-foreground",active:"text-primary",positive:"text-positive",warning:"text-warning",destructive:"text-destructive"}},defaultVariants:{variant:"body",state:"default"}}),f={display:"h1","title-lg":"h1",title:"h2","title-sm":"h3","title-xs":"h4",body:"p",label:"span",caption:"span",overline:"span"};function v({className:x,variant:d="body",state:c="default",as:m,icon:e,truncate:n=!1,children:l,...p}){const a=d??"body",t=m??f[a],u=t,o=!!e||n,g=t==="span"||t==="strong"||t==="em"||t==="small"||t==="label"?"inline-flex":"flex";return s.jsxs(u,{"data-slot":"text","data-variant":a,className:i.cn(r({variant:a,state:c}),o&&i.cn(g,"max-w-full items-baseline"),x),...p,children:[e?s.jsx(e,{"aria-hidden":"true",className:"size-[1em] shrink-0 translate-y-[0.14em]"}):null,o?s.jsx("span",{className:i.cn("min-w-0",n&&"truncate"),children:l}):l]})}exports.Text=v;exports.textVariants=r;
2
+ //# sourceMappingURL=text.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.cjs","sources":["../../src/components/ui/text.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Elements `Text` is allowed to render.\n *\n * `as` controls semantics and the document outline; `variant` controls the\n * visual scale. The two are deliberately independent — a `title-lg` can be an\n * `h2` on a page that already owns its `h1`, and a `caption` can be a `dd`.\n * Coupling them is the failure mode that keeps shadcn from shipping a\n * typography component at all (consumers reach for `h1` to mean \"big\").\n */\ntype TextElement =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"p\"\n | \"span\"\n | \"div\"\n | \"label\"\n | \"legend\"\n | \"figcaption\"\n | \"figure\"\n | \"dt\"\n | \"dd\"\n | \"li\"\n | \"strong\"\n | \"em\"\n | \"small\"\n | \"summary\"\n | \"address\";\n\n/**\n * Every variant maps onto Tailwind's own size/weight/tracking tokens plus the\n * kit's `text-2xs` — no new scale is introduced here (see DESIGN.md §Typography\n * and `Foundations/Typography`). Line heights are deliberately left to\n * Tailwind's size-paired defaults rather than overridden.\n *\n * The `gap-*` in each variant is inert until an `icon` or `truncate` switches\n * the root to a flex box; keeping it on the variant is what makes the\n * icon/text gap scale with the type step.\n */\nconst textVariants = cva(\"\", {\n variants: {\n variant: {\n display: \"gap-2.5 text-3xl font-bold tracking-tight\",\n \"title-lg\": \"gap-2.5 text-2xl font-bold tracking-tight\",\n title: \"gap-2 text-xl font-semibold\",\n \"title-sm\": \"gap-2 text-lg font-semibold\",\n \"title-xs\": \"gap-1.5 text-base font-semibold\",\n body: \"gap-1.5 text-sm\",\n label: \"gap-1.5 text-sm font-medium\",\n caption: \"gap-1 text-xs\",\n overline: \"gap-1 text-2xs font-semibold tracking-widest uppercase\",\n },\n state: {\n // `default` intentionally sets no colour so `Text` inherits from its\n // container — setting `text-foreground` here would fight every consumer\n // that colours a subtree.\n default: \"\",\n muted: \"text-muted-foreground\",\n // Semantic states follow the kit's colour contract (DESIGN.md): blue =\n // action, green = success, orange = caution, red = error. `warning` is\n // the kit-wide name for the caution slot (Badge/Alert/Banner all use it).\n //\n // Contrast against `--background`, measured in both themes:\n // active 7.66 / 11.12 · positive 4.83 / 8.02 · destructive 4.82 / 10.07\n // all clear AA 4.5 for body text. `warning` is the exception at\n // 4.44 / 8.41 — it clears AA in dark mode but lands just under in light,\n // because `--warning` was tuned to 4.6:1 on pure white while the kit's\n // actual surface is a tinted off-white. That shortfall lives in the token,\n // not here; see SW-2581.\n active: \"text-primary\",\n positive: \"text-positive\",\n warning: \"text-warning\",\n destructive: \"text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"body\",\n state: \"default\",\n },\n});\n\ntype TextVariant = NonNullable<NonNullable<VariantProps<typeof textVariants>>[\"variant\"]>;\n\n/** Sensible default element per variant. Always overridable via `as`. */\nconst DEFAULT_ELEMENT: Record<TextVariant, TextElement> = {\n display: \"h1\",\n \"title-lg\": \"h1\",\n title: \"h2\",\n \"title-sm\": \"h3\",\n \"title-xs\": \"h4\",\n body: \"p\",\n label: \"span\",\n caption: \"span\",\n overline: \"span\",\n};\n\n/**\n * Props are based on `HTMLAttributes<HTMLElement>` rather than the kit's usual\n * `ComponentProps<\"tag\">`, because every handler and the `ref` on a concrete\n * tag is parameterised by that one element type — which cannot hold once `as`\n * is polymorphic. `HTMLElement` is the widest type that stays assignable to all\n * of them. No `ref` is forwarded; the kit is migrating off `forwardRef`.\n */\ninterface TextProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof textVariants> {\n /**\n * Semantic element to render. Defaults per `variant` (see `DEFAULT_ELEMENT`).\n * Set it explicitly whenever the document outline and the visual scale\n * disagree — which is most of the time on a real page.\n */\n as?: TextElement;\n /**\n * Decorative leading glyph. Rendered `aria-hidden`, sized in `em` so it\n * scales with the variant, and nudged down to sit on the cap height rather\n * than centred on the line box.\n *\n * The contract is decorative-only: the accessible name of a heading must be\n * its text. If the glyph carries meaning, keep it outside `Text` (or give\n * `Text` an explicit `aria-label`) — the component will not invent one.\n */\n icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>;\n /**\n * Truncate to a single line with an ellipsis. Switches the root to a flex\n * box — `flex` for block elements, `inline-flex` for inline ones such as\n * `span` — so the parent has to bound the width for it to engage, e.g.\n * `<div className=\"flex\"><Text truncate … /></div>` with the sibling marked\n * `shrink-0`.\n */\n truncate?: boolean;\n}\n\nfunction Text({\n className,\n variant = \"body\",\n state = \"default\",\n as,\n icon: Icon,\n truncate = false,\n children,\n ...props\n}: TextProps) {\n const resolvedVariant: TextVariant = variant ?? \"body\";\n const resolvedElement: TextElement = as ?? DEFAULT_ELEMENT[resolvedVariant];\n const Comp: React.ElementType = resolvedElement;\n\n // An icon or a truncating label needs a flex root and a wrapper it can\n // shrink; plain text keeps the bare element so inline flow is untouched.\n const isComposite = Boolean(Icon) || truncate;\n\n const compositeDisplay =\n resolvedElement === \"span\" ||\n resolvedElement === \"strong\" ||\n resolvedElement === \"em\" ||\n resolvedElement === \"small\" ||\n resolvedElement === \"label\"\n ? \"inline-flex\"\n : \"flex\";\n\n return (\n <Comp\n data-slot=\"text\"\n data-variant={resolvedVariant}\n className={cn(\n textVariants({ variant: resolvedVariant, state }),\n isComposite && cn(compositeDisplay, \"max-w-full items-baseline\"),\n className,\n )}\n {...props}\n >\n {Icon ? <Icon aria-hidden=\"true\" className=\"size-[1em] shrink-0 translate-y-[0.14em]\" /> : null}\n {isComposite ? <span className={cn(\"min-w-0\", truncate && \"truncate\")}>{children}</span> : children}\n </Comp>\n );\n}\n\nexport { Text, textVariants };\nexport type { TextProps, TextElement, TextVariant };\n"],"names":["textVariants","cva","DEFAULT_ELEMENT","Text","className","variant","state","as","Icon","truncate","children","props","resolvedVariant","resolvedElement","Comp","isComposite","compositeDisplay","jsxs","cn","jsx"],"mappings":"yLA+CMA,EAAeC,EAAAA,IAAI,GAAI,CAC3B,SAAU,CACR,QAAS,CACP,QAAS,4CACT,WAAY,4CACZ,MAAO,8BACP,WAAY,8BACZ,WAAY,kCACZ,KAAM,kBACN,MAAO,8BACP,QAAS,gBACT,SAAU,wDAAA,EAEZ,MAAO,CAIL,QAAS,GACT,MAAO,wBAYP,OAAQ,eACR,SAAU,gBACV,QAAS,eACT,YAAa,kBAAA,CACf,EAEF,gBAAiB,CACf,QAAS,OACT,MAAO,SAAA,CAEX,CAAC,EAKKC,EAAoD,CACxD,QAAS,KACT,WAAY,KACZ,MAAO,KACP,WAAY,KACZ,WAAY,KACZ,KAAM,IACN,MAAO,OACP,QAAS,OACT,SAAU,MACZ,EAoCA,SAASC,EAAK,CACZ,UAAAC,EACA,QAAAC,EAAU,OACV,MAAAC,EAAQ,UACR,GAAAC,EACA,KAAMC,EACN,SAAAC,EAAW,GACX,SAAAC,EACA,GAAGC,CACL,EAAc,CACZ,MAAMC,EAA+BP,GAAW,OAC1CQ,EAA+BN,GAAML,EAAgBU,CAAe,EACpEE,EAA0BD,EAI1BE,EAAc,EAAQP,GAASC,EAE/BO,EACJH,IAAoB,QACpBA,IAAoB,UACpBA,IAAoB,MACpBA,IAAoB,SACpBA,IAAoB,QAChB,cACA,OAEN,OACEI,EAAAA,KAACH,EAAA,CACC,YAAU,OACV,eAAcF,EACd,UAAWM,EAAAA,GACTlB,EAAa,CAAE,QAASY,EAAiB,MAAAN,EAAO,EAChDS,GAAeG,EAAAA,GAAGF,EAAkB,2BAA2B,EAC/DZ,CAAA,EAED,GAAGO,EAEH,SAAA,CAAAH,QAAQA,EAAA,CAAK,cAAY,OAAO,UAAU,2CAA2C,EAAK,KAC1FO,EAAcI,EAAAA,IAAC,OAAA,CAAK,UAAWD,EAAAA,GAAG,UAAWT,GAAY,UAAU,EAAI,SAAAC,CAAA,CAAS,EAAUA,CAAA,CAAA,CAAA,CAGjG"}
@@ -0,0 +1,88 @@
1
+ import { jsxs as f, jsx as o } from "react/jsx-runtime";
2
+ import { cva as b } from "class-variance-authority";
3
+ import { cn as s } from "../lib/utils.js";
4
+ const u = b("", {
5
+ variants: {
6
+ variant: {
7
+ display: "gap-2.5 text-3xl font-bold tracking-tight",
8
+ "title-lg": "gap-2.5 text-2xl font-bold tracking-tight",
9
+ title: "gap-2 text-xl font-semibold",
10
+ "title-sm": "gap-2 text-lg font-semibold",
11
+ "title-xs": "gap-1.5 text-base font-semibold",
12
+ body: "gap-1.5 text-sm",
13
+ label: "gap-1.5 text-sm font-medium",
14
+ caption: "gap-1 text-xs",
15
+ overline: "gap-1 text-2xs font-semibold tracking-widest uppercase"
16
+ },
17
+ state: {
18
+ // `default` intentionally sets no colour so `Text` inherits from its
19
+ // container — setting `text-foreground` here would fight every consumer
20
+ // that colours a subtree.
21
+ default: "",
22
+ muted: "text-muted-foreground",
23
+ // Semantic states follow the kit's colour contract (DESIGN.md): blue =
24
+ // action, green = success, orange = caution, red = error. `warning` is
25
+ // the kit-wide name for the caution slot (Badge/Alert/Banner all use it).
26
+ //
27
+ // Contrast against `--background`, measured in both themes:
28
+ // active 7.66 / 11.12 · positive 4.83 / 8.02 · destructive 4.82 / 10.07
29
+ // all clear AA 4.5 for body text. `warning` is the exception at
30
+ // 4.44 / 8.41 — it clears AA in dark mode but lands just under in light,
31
+ // because `--warning` was tuned to 4.6:1 on pure white while the kit's
32
+ // actual surface is a tinted off-white. That shortfall lives in the token,
33
+ // not here; see SW-2581.
34
+ active: "text-primary",
35
+ positive: "text-positive",
36
+ warning: "text-warning",
37
+ destructive: "text-destructive"
38
+ }
39
+ },
40
+ defaultVariants: {
41
+ variant: "body",
42
+ state: "default"
43
+ }
44
+ }), v = {
45
+ display: "h1",
46
+ "title-lg": "h1",
47
+ title: "h2",
48
+ "title-sm": "h3",
49
+ "title-xs": "h4",
50
+ body: "p",
51
+ label: "span",
52
+ caption: "span",
53
+ overline: "span"
54
+ };
55
+ function E({
56
+ className: r,
57
+ variant: m = "body",
58
+ state: p = "default",
59
+ as: d,
60
+ icon: e,
61
+ truncate: i = !1,
62
+ children: l,
63
+ ...x
64
+ }) {
65
+ const a = m ?? "body", t = d ?? v[a], c = t, n = !!e || i, g = t === "span" || t === "strong" || t === "em" || t === "small" || t === "label" ? "inline-flex" : "flex";
66
+ return /* @__PURE__ */ f(
67
+ c,
68
+ {
69
+ "data-slot": "text",
70
+ "data-variant": a,
71
+ className: s(
72
+ u({ variant: a, state: p }),
73
+ n && s(g, "max-w-full items-baseline"),
74
+ r
75
+ ),
76
+ ...x,
77
+ children: [
78
+ e ? /* @__PURE__ */ o(e, { "aria-hidden": "true", className: "size-[1em] shrink-0 translate-y-[0.14em]" }) : null,
79
+ n ? /* @__PURE__ */ o("span", { className: s("min-w-0", i && "truncate"), children: l }) : l
80
+ ]
81
+ }
82
+ );
83
+ }
84
+ export {
85
+ E as Text,
86
+ u as textVariants
87
+ };
88
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sources":["../../src/components/ui/text.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * Elements `Text` is allowed to render.\n *\n * `as` controls semantics and the document outline; `variant` controls the\n * visual scale. The two are deliberately independent — a `title-lg` can be an\n * `h2` on a page that already owns its `h1`, and a `caption` can be a `dd`.\n * Coupling them is the failure mode that keeps shadcn from shipping a\n * typography component at all (consumers reach for `h1` to mean \"big\").\n */\ntype TextElement =\n | \"h1\"\n | \"h2\"\n | \"h3\"\n | \"h4\"\n | \"h5\"\n | \"h6\"\n | \"p\"\n | \"span\"\n | \"div\"\n | \"label\"\n | \"legend\"\n | \"figcaption\"\n | \"figure\"\n | \"dt\"\n | \"dd\"\n | \"li\"\n | \"strong\"\n | \"em\"\n | \"small\"\n | \"summary\"\n | \"address\";\n\n/**\n * Every variant maps onto Tailwind's own size/weight/tracking tokens plus the\n * kit's `text-2xs` — no new scale is introduced here (see DESIGN.md §Typography\n * and `Foundations/Typography`). Line heights are deliberately left to\n * Tailwind's size-paired defaults rather than overridden.\n *\n * The `gap-*` in each variant is inert until an `icon` or `truncate` switches\n * the root to a flex box; keeping it on the variant is what makes the\n * icon/text gap scale with the type step.\n */\nconst textVariants = cva(\"\", {\n variants: {\n variant: {\n display: \"gap-2.5 text-3xl font-bold tracking-tight\",\n \"title-lg\": \"gap-2.5 text-2xl font-bold tracking-tight\",\n title: \"gap-2 text-xl font-semibold\",\n \"title-sm\": \"gap-2 text-lg font-semibold\",\n \"title-xs\": \"gap-1.5 text-base font-semibold\",\n body: \"gap-1.5 text-sm\",\n label: \"gap-1.5 text-sm font-medium\",\n caption: \"gap-1 text-xs\",\n overline: \"gap-1 text-2xs font-semibold tracking-widest uppercase\",\n },\n state: {\n // `default` intentionally sets no colour so `Text` inherits from its\n // container — setting `text-foreground` here would fight every consumer\n // that colours a subtree.\n default: \"\",\n muted: \"text-muted-foreground\",\n // Semantic states follow the kit's colour contract (DESIGN.md): blue =\n // action, green = success, orange = caution, red = error. `warning` is\n // the kit-wide name for the caution slot (Badge/Alert/Banner all use it).\n //\n // Contrast against `--background`, measured in both themes:\n // active 7.66 / 11.12 · positive 4.83 / 8.02 · destructive 4.82 / 10.07\n // all clear AA 4.5 for body text. `warning` is the exception at\n // 4.44 / 8.41 — it clears AA in dark mode but lands just under in light,\n // because `--warning` was tuned to 4.6:1 on pure white while the kit's\n // actual surface is a tinted off-white. That shortfall lives in the token,\n // not here; see SW-2581.\n active: \"text-primary\",\n positive: \"text-positive\",\n warning: \"text-warning\",\n destructive: \"text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"body\",\n state: \"default\",\n },\n});\n\ntype TextVariant = NonNullable<NonNullable<VariantProps<typeof textVariants>>[\"variant\"]>;\n\n/** Sensible default element per variant. Always overridable via `as`. */\nconst DEFAULT_ELEMENT: Record<TextVariant, TextElement> = {\n display: \"h1\",\n \"title-lg\": \"h1\",\n title: \"h2\",\n \"title-sm\": \"h3\",\n \"title-xs\": \"h4\",\n body: \"p\",\n label: \"span\",\n caption: \"span\",\n overline: \"span\",\n};\n\n/**\n * Props are based on `HTMLAttributes<HTMLElement>` rather than the kit's usual\n * `ComponentProps<\"tag\">`, because every handler and the `ref` on a concrete\n * tag is parameterised by that one element type — which cannot hold once `as`\n * is polymorphic. `HTMLElement` is the widest type that stays assignable to all\n * of them. No `ref` is forwarded; the kit is migrating off `forwardRef`.\n */\ninterface TextProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof textVariants> {\n /**\n * Semantic element to render. Defaults per `variant` (see `DEFAULT_ELEMENT`).\n * Set it explicitly whenever the document outline and the visual scale\n * disagree — which is most of the time on a real page.\n */\n as?: TextElement;\n /**\n * Decorative leading glyph. Rendered `aria-hidden`, sized in `em` so it\n * scales with the variant, and nudged down to sit on the cap height rather\n * than centred on the line box.\n *\n * The contract is decorative-only: the accessible name of a heading must be\n * its text. If the glyph carries meaning, keep it outside `Text` (or give\n * `Text` an explicit `aria-label`) — the component will not invent one.\n */\n icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>;\n /**\n * Truncate to a single line with an ellipsis. Switches the root to a flex\n * box — `flex` for block elements, `inline-flex` for inline ones such as\n * `span` — so the parent has to bound the width for it to engage, e.g.\n * `<div className=\"flex\"><Text truncate … /></div>` with the sibling marked\n * `shrink-0`.\n */\n truncate?: boolean;\n}\n\nfunction Text({\n className,\n variant = \"body\",\n state = \"default\",\n as,\n icon: Icon,\n truncate = false,\n children,\n ...props\n}: TextProps) {\n const resolvedVariant: TextVariant = variant ?? \"body\";\n const resolvedElement: TextElement = as ?? DEFAULT_ELEMENT[resolvedVariant];\n const Comp: React.ElementType = resolvedElement;\n\n // An icon or a truncating label needs a flex root and a wrapper it can\n // shrink; plain text keeps the bare element so inline flow is untouched.\n const isComposite = Boolean(Icon) || truncate;\n\n const compositeDisplay =\n resolvedElement === \"span\" ||\n resolvedElement === \"strong\" ||\n resolvedElement === \"em\" ||\n resolvedElement === \"small\" ||\n resolvedElement === \"label\"\n ? \"inline-flex\"\n : \"flex\";\n\n return (\n <Comp\n data-slot=\"text\"\n data-variant={resolvedVariant}\n className={cn(\n textVariants({ variant: resolvedVariant, state }),\n isComposite && cn(compositeDisplay, \"max-w-full items-baseline\"),\n className,\n )}\n {...props}\n >\n {Icon ? <Icon aria-hidden=\"true\" className=\"size-[1em] shrink-0 translate-y-[0.14em]\" /> : null}\n {isComposite ? <span className={cn(\"min-w-0\", truncate && \"truncate\")}>{children}</span> : children}\n </Comp>\n );\n}\n\nexport { Text, textVariants };\nexport type { TextProps, TextElement, TextVariant };\n"],"names":["textVariants","cva","DEFAULT_ELEMENT","Text","className","variant","state","as","Icon","truncate","children","props","resolvedVariant","resolvedElement","Comp","isComposite","compositeDisplay","jsxs","cn","jsx"],"mappings":";;;AA+CA,MAAMA,IAAeC,EAAI,IAAI;AAAA,EAC3B,UAAU;AAAA,IACR,SAAS;AAAA,MACP,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,IAAA;AAAA,IAEZ,OAAO;AAAA;AAAA;AAAA;AAAA,MAIL,SAAS;AAAA,MACT,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAYP,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IAAA;AAAA,EACf;AAAA,EAEF,iBAAiB;AAAA,IACf,SAAS;AAAA,IACT,OAAO;AAAA,EAAA;AAEX,CAAC,GAKKC,IAAoD;AAAA,EACxD,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU;AACZ;AAoCA,SAASC,EAAK;AAAA,EACZ,WAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,OAAAC,IAAQ;AAAA,EACR,IAAAC;AAAA,EACA,MAAMC;AAAA,EACN,UAAAC,IAAW;AAAA,EACX,UAAAC;AAAA,EACA,GAAGC;AACL,GAAc;AACZ,QAAMC,IAA+BP,KAAW,QAC1CQ,IAA+BN,KAAML,EAAgBU,CAAe,GACpEE,IAA0BD,GAI1BE,IAAc,EAAQP,KAASC,GAE/BO,IACJH,MAAoB,UACpBA,MAAoB,YACpBA,MAAoB,QACpBA,MAAoB,WACpBA,MAAoB,UAChB,gBACA;AAEN,SACE,gBAAAI;AAAA,IAACH;AAAA,IAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAcF;AAAA,MACd,WAAWM;AAAA,QACTlB,EAAa,EAAE,SAASY,GAAiB,OAAAN,GAAO;AAAA,QAChDS,KAAeG,EAAGF,GAAkB,2BAA2B;AAAA,QAC/DZ;AAAA,MAAA;AAAA,MAED,GAAGO;AAAA,MAEH,UAAA;AAAA,QAAAH,sBAAQA,GAAA,EAAK,eAAY,QAAO,WAAU,4CAA2C,IAAK;AAAA,QAC1FO,IAAc,gBAAAI,EAAC,QAAA,EAAK,WAAWD,EAAG,WAAWT,KAAY,UAAU,GAAI,UAAAC,EAAA,CAAS,IAAUA;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGjG;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tetrascience-npm/tetrascience-react-ui",
3
- "version": "1.0.0-beta.134.1",
3
+ "version": "1.0.0-beta.136.1",
4
4
  "description": "TetraScience React UI",
5
5
  "type": "module",
6
6
  "author": "TetraScience",
@@ -30,6 +30,16 @@
30
30
  "default": "./dist/index.cjs"
31
31
  }
32
32
  },
33
+ "./telemetry": {
34
+ "import": {
35
+ "types": "./dist/telemetry/index.d.ts",
36
+ "default": "./dist/telemetry.js"
37
+ },
38
+ "require": {
39
+ "types": "./dist/telemetry/index.d.ts",
40
+ "default": "./dist/telemetry.cjs"
41
+ }
42
+ },
33
43
  "./server": {
34
44
  "import": {
35
45
  "types": "./dist/server/index.d.ts",
@@ -200,7 +210,9 @@
200
210
  "lint:fix": "eslint . --fix --max-warnings 0",
201
211
  "typecheck": "tsc --noEmit",
202
212
  "format": "prettier --write .",
203
- "format:check": "prettier --check ."
213
+ "format:check": "prettier --check .",
214
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
215
+ "typecheck:e2e": "tsc --noEmit -p tsconfig.e2e.json"
204
216
  },
205
217
  "dependencies": {
206
218
  "@aws-sdk/client-cloudwatch-logs": ">=3.0.0 <4.0.0",
@@ -250,6 +262,7 @@
250
262
  "@rdkit/rdkit": "2025.3.4-1.0.0",
251
263
  "@streamdown/math": "^1.0.2",
252
264
  "@streamdown/mermaid": "^1.0.2",
265
+ "@tetrascience-npm/request": ">=0.4.0",
253
266
  "plotly.js-dist": "^2.35.2",
254
267
  "react": "^19.0.0",
255
268
  "react-dom": "^19.0.0",
@@ -280,6 +293,9 @@
280
293
  },
281
294
  "devDependencies": {
282
295
  "@aws-sdk/client-athena": "^3.975.0",
296
+ "@aws-sdk/client-cloudwatch": "^3.699.0",
297
+ "@aws-sdk/client-cloudwatch-logs": "^3.699.0",
298
+ "@aws-sdk/client-ssm": "^3.699.0",
283
299
  "@commitlint/cli": "^20.5.0",
284
300
  "@commitlint/config-conventional": "^20.5.0",
285
301
  "@databricks/sql": "^1.12.0",
@@ -303,6 +319,7 @@
303
319
  "@streamdown/math": "^1.0.2",
304
320
  "@streamdown/mermaid": "^1.0.2",
305
321
  "@tailwindcss/vite": "^4.2.2",
322
+ "@tetrascience-npm/request": "0.4.0",
306
323
  "@types/eslint-plugin-jsx-a11y": "^6",
307
324
  "@types/jsdom": "^27",
308
325
  "@types/node": "^25.3.3",