@datalayer/core 1.1.45 → 1.1.46

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.
@@ -73,8 +73,26 @@ export type IDatalayerCoreConfig = {
73
73
  mcpServersUrl: string;
74
74
  /**
75
75
  * OTEL (OpenTelemetry) API URL.
76
+ *
77
+ * This is the endpoint runtimes/agents export telemetry to. In the browser
78
+ * it is also the default endpoint used to *consume* (query) telemetry, unless
79
+ * {@link otelInUrl} is provided.
76
80
  */
77
81
  otelUrl: string;
82
+ /**
83
+ * OTEL (OpenTelemetry) *consume* (read/query) API URL override.
84
+ *
85
+ * When set, the UI reads telemetry (metrics, traces, logs) from this URL
86
+ * instead of {@link otelUrl}. When empty/undefined, {@link otelUrl} is used.
87
+ *
88
+ * Primary use case: local development. When runtimes run in the cloud and
89
+ * export their telemetry to the production OTEL service, a local UI must fetch
90
+ * telemetry from production rather than from the local OTEL endpoint. Set this
91
+ * to e.g. `https://prod1.datalayer.run` while `otelUrl` stays local.
92
+ *
93
+ * Fed by the `DATALAYER_OTEL_IN_URL` environment variable at build/deploy time.
94
+ */
95
+ otelInUrl?: string;
78
96
  /**
79
97
  * Growth API URL.
80
98
  */
@@ -16,7 +16,7 @@
16
16
  * const { data: spans } = await client.fetchTraces({ limit: 50 });
17
17
  * ```
18
18
  */
19
- import { coreStore } from '../../state/substates/CoreState.js';
19
+ import { getOtelConsumeUrl } from '../../state/substates/CoreState.js';
20
20
  import { resolveOtelAuth } from '../auth.js';
21
21
  // ── Fetch helper ────────────────────────────────────────────────────────────
22
22
  async function otelFetch(url, token, userUid, options) {
@@ -125,8 +125,7 @@ export class OtelClient {
125
125
  token;
126
126
  userUid;
127
127
  constructor(options) {
128
- this.baseUrl =
129
- options.baseUrl ?? coreStore.getState().configuration.otelUrl;
128
+ this.baseUrl = options.baseUrl ?? getOtelConsumeUrl();
130
129
  const auth = resolveOtelAuth(options.token, options.userUid);
131
130
  this.token = auth.token;
132
131
  this.userUid = auth.userUid;
@@ -8,7 +8,7 @@
8
8
  * @module otel/hooks
9
9
  */
10
10
  import { useCallback, useEffect, useRef, useState } from 'react';
11
- import { coreStore } from '../../state/substates/CoreState.js';
11
+ import { getOtelConsumeUrl } from '../../state/substates/CoreState.js';
12
12
  import { buildOtelWebSocketUrl, resolveOtelAuth } from '../auth.js';
13
13
  // ── Global 401 handler ──────────────────────────────────────────────
14
14
  let _onUnauthorized = null;
@@ -189,7 +189,7 @@ function normalizeMetric(raw) {
189
189
  // ── useOtelTraces ───────────────────────────────────────────────────
190
190
  /** Fetch a list of traces / spans from the OTEL service. */
191
191
  export function useOtelTraces(options) {
192
- const { token, baseUrl = coreStore.getState().configuration.otelUrl, serviceName, limit = 50, autoRefreshMs, } = options;
192
+ const { token, baseUrl = getOtelConsumeUrl(), serviceName, limit = 50, autoRefreshMs, } = options;
193
193
  const [traces, setTraces] = useState([]);
194
194
  const [loading, setLoading] = useState(true);
195
195
  const [error, setError] = useState(null);
@@ -246,7 +246,7 @@ export function useOtelTrace(options) {
246
246
  // ── useOtelLogs ─────────────────────────────────────────────────────
247
247
  /** Fetch log records from the OTEL service. */
248
248
  export function useOtelLogs(options) {
249
- const { token, baseUrl = coreStore.getState().configuration.otelUrl, serviceName, severity, traceId, limit = 100, autoRefreshMs, } = options;
249
+ const { token, baseUrl = getOtelConsumeUrl(), serviceName, severity, traceId, limit = 100, autoRefreshMs, } = options;
250
250
  const [logs, setLogs] = useState([]);
251
251
  const [loading, setLoading] = useState(true);
252
252
  const [error, setError] = useState(null);
@@ -283,7 +283,7 @@ export function useOtelLogs(options) {
283
283
  // ── useOtelMetrics ──────────────────────────────────────────────────
284
284
  /** Fetch metrics from the OTEL service. */
285
285
  export function useOtelMetrics(options) {
286
- const { token, baseUrl = coreStore.getState().configuration.otelUrl, serviceName, metricName, limit = 50, autoRefreshMs, } = options;
286
+ const { token, baseUrl = getOtelConsumeUrl(), serviceName, metricName, limit = 50, autoRefreshMs, } = options;
287
287
  const [metrics, setMetrics] = useState([]);
288
288
  const [loading, setLoading] = useState(true);
289
289
  const [error, setError] = useState(null);
@@ -318,7 +318,7 @@ export function useOtelMetrics(options) {
318
318
  // ── useOtelServices ─────────────────────────────────────────────────
319
319
  /** Fetch list of observed service names. */
320
320
  export function useOtelServices(options) {
321
- const { token, baseUrl = coreStore.getState().configuration.otelUrl } = options;
321
+ const { token, baseUrl = getOtelConsumeUrl() } = options;
322
322
  const [services, setServices] = useState([]);
323
323
  const [loading, setLoading] = useState(true);
324
324
  useEffect(() => {
@@ -437,7 +437,7 @@ export function useOtelQuery(options) {
437
437
  * @returns `{ connected, error, close }` – reactive connection state.
438
438
  */
439
439
  export function useOtelWebSocket(options) {
440
- const { baseUrl = coreStore.getState().configuration.otelUrl, token, userUid, autoReconnect = true, reconnectDelayMs = 3000, callbacks, } = options;
440
+ const { baseUrl = getOtelConsumeUrl(), token, userUid, autoReconnect = true, reconnectDelayMs = 3000, callbacks, } = options;
441
441
  const [connected, setConnected] = useState(false);
442
442
  const [error, setError] = useState(null);
443
443
  const wsRef = useRef(null);
@@ -15,7 +15,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
15
15
  import { useState, useCallback, useMemo, useEffect, useRef, } from 'react';
16
16
  import { Box, Text, Button, Label } from '@primer/react';
17
17
  import { GitBranchIcon, ClockIcon } from '@primer/octicons-react';
18
- import { coreStore } from '../../state/substates/CoreState.js';
18
+ import { getOtelConsumeUrl } from '../../state/substates/CoreState.js';
19
19
  import { useOtelTraces, useOtelTrace, useOtelLogs, useOtelMetrics, useOtelServices, useOtelWebSocket, } from '../hooks/index.js';
20
20
  import { OtelSearchBar } from './OtelSearchBar.js';
21
21
  import { OtelTimelineRangeSlider } from './OtelTimelineRangeSlider.js';
@@ -51,7 +51,7 @@ function buildHistogram(timestamps, start, end, buckets) {
51
51
  }));
52
52
  }
53
53
  // ── OtelLive ────────────────────────────────────────────────────────
54
- export const OtelLive = ({ baseUrl = coreStore.getState().configuration.otelUrl, wsBaseUrl, token, autoRefreshMs = 5000, defaultSignal = 'traces', limit = 200, onSignalRef, }) => {
54
+ export const OtelLive = ({ baseUrl = getOtelConsumeUrl(), wsBaseUrl, token, autoRefreshMs = 5000, defaultSignal = 'traces', limit = 200, onSignalRef, }) => {
55
55
  // ── state ──
56
56
  const [signal, setSignalState] = useState(() => {
57
57
  try {
@@ -22,4 +22,15 @@ export type DatalayerCoreState = {
22
22
  export declare const coreStore: import("zustand").StoreApi<DatalayerCoreState>;
23
23
  export declare function useCoreStore(): DatalayerCoreState;
24
24
  export declare function useCoreStore<T>(selector: (state: DatalayerCoreState) => T): T;
25
+ /**
26
+ * Resolve the OTEL base URL used to *consume* (read/query) telemetry.
27
+ *
28
+ * Prefers `otelInUrl` when set, otherwise falls back to `otelUrl`. This allows
29
+ * local development to fetch telemetry from a remote (e.g. production) OTEL
30
+ * service even when the local runtime exports telemetry to a different endpoint.
31
+ *
32
+ * Mirrors the `DATALAYER_OTEL_IN_URL` (consume) / `DATALAYER_OTEL_URL` (export)
33
+ * split on the backend/build side.
34
+ */
35
+ export declare const getOtelConsumeUrl: () => string;
25
36
  export default useCoreStore;
@@ -24,6 +24,10 @@ let initialConfiguration = {
24
24
  aiInferenceUrl: 'https://prod1.datalayer.run',
25
25
  mcpServersUrl: 'https://prod1.datalayer.run',
26
26
  otelUrl: 'https://prod1.datalayer.run',
27
+ // Defaults to prod so telemetry is consumed from the production OTEL service
28
+ // even when runtimes export elsewhere (see `getOtelConsumeUrl` and the
29
+ // `DATALAYER_OTEL_IN_URL` env var). Override to '' to consume from `otelUrl`.
30
+ otelInUrl: 'https://prod1.datalayer.run',
27
31
  growthUrl: 'https://prod1.datalayer.run',
28
32
  inboundsUrl: 'https://prod1.datalayer.run',
29
33
  successUrl: 'https://prod1.datalayer.run',
@@ -97,4 +101,18 @@ export const coreStore = createStore((set, get) => ({
97
101
  export function useCoreStore(selector) {
98
102
  return useStore(coreStore, selector);
99
103
  }
104
+ /**
105
+ * Resolve the OTEL base URL used to *consume* (read/query) telemetry.
106
+ *
107
+ * Prefers `otelInUrl` when set, otherwise falls back to `otelUrl`. This allows
108
+ * local development to fetch telemetry from a remote (e.g. production) OTEL
109
+ * service even when the local runtime exports telemetry to a different endpoint.
110
+ *
111
+ * Mirrors the `DATALAYER_OTEL_IN_URL` (consume) / `DATALAYER_OTEL_URL` (export)
112
+ * split on the backend/build side.
113
+ */
114
+ export const getOtelConsumeUrl = () => {
115
+ const cfg = coreStore.getState().configuration;
116
+ return cfg.otelInUrl || cfg.otelUrl;
117
+ };
100
118
  export default useCoreStore;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/core",
3
- "version": "1.1.45",
3
+ "version": "1.1.46",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",