@xylabs/telemetry 5.0.79 → 5.0.81

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/README.md CHANGED
@@ -21,6 +21,10 @@ Base functionality used throughout XY Labs TypeScript/JavaScript libraries
21
21
 
22
22
  ***
23
23
 
24
+ ## Interfaces
25
+
26
+ - [SpanConfig](#interfaces/SpanConfig)
27
+
24
28
  ## Functions
25
29
 
26
30
  - [cloneContextWithoutSpan](#functions/cloneContextWithoutSpan)
@@ -28,6 +32,7 @@ Base functionality used throughout XY Labs TypeScript/JavaScript libraries
28
32
  - [spanRoot](#functions/spanRoot)
29
33
  - [spanAsync](#functions/spanAsync)
30
34
  - [spanRootAsync](#functions/spanRootAsync)
35
+ - [timeBudget](#functions/timeBudget)
31
36
 
32
37
  ### functions
33
38
 
@@ -38,7 +43,7 @@ Base functionality used throughout XY Labs TypeScript/JavaScript libraries
38
43
  ***
39
44
 
40
45
  ```ts
41
- function cloneContextWithoutSpan(activeCtx, configKeys): Context;
46
+ function cloneContextWithoutSpan(activeCtx, configKeys?): Context;
42
47
  ```
43
48
 
44
49
  ## Parameters
@@ -47,7 +52,7 @@ function cloneContextWithoutSpan(activeCtx, configKeys): Context;
47
52
 
48
53
  `Context`
49
54
 
50
- ### configKeys
55
+ ### configKeys?
51
56
 
52
57
  `symbol`[] = `[]`
53
58
 
@@ -102,7 +107,7 @@ function span<T>(
102
107
  function spanAsync<T>(
103
108
  name,
104
109
  fn,
105
- tracer?): Promise<T>;
110
+ __namedParameters?): Promise<T>;
106
111
  ```
107
112
 
108
113
  ## Type Parameters
@@ -121,9 +126,9 @@ tracer?): Promise<T>;
121
126
 
122
127
  () => `Promise`\<`T`\>
123
128
 
124
- ### tracer?
129
+ ### \_\_namedParameters?
125
130
 
126
- `Tracer`
131
+ [`SpanConfig`](#../interfaces/SpanConfig) = `{}`
127
132
 
128
133
  ## Returns
129
134
 
@@ -176,7 +181,7 @@ function spanRoot<T>(
176
181
  function spanRootAsync<T>(
177
182
  name,
178
183
  fn,
179
- tracer?): Promise<T>;
184
+ __namedParameters?): Promise<T>;
180
185
  ```
181
186
 
182
187
  ## Type Parameters
@@ -195,14 +200,93 @@ tracer?): Promise<T>;
195
200
 
196
201
  () => `Promise`\<`T`\>
197
202
 
198
- ### tracer?
203
+ ### \_\_namedParameters?
199
204
 
200
- `Tracer`
205
+ [`SpanConfig`](#../interfaces/SpanConfig) = `{}`
201
206
 
202
207
  ## Returns
203
208
 
204
209
  `Promise`\<`T`\>
205
210
 
211
+ ### <a id="timeBudget"></a>timeBudget
212
+
213
+ [**@xylabs/telemetry**](#../README)
214
+
215
+ ***
216
+
217
+ ```ts
218
+ function timeBudget<TResult>(
219
+ name,
220
+ logger,
221
+ func,
222
+ budget,
223
+ status?): Promise<TResult>;
224
+ ```
225
+
226
+ ## Type Parameters
227
+
228
+ ### TResult
229
+
230
+ `TResult`
231
+
232
+ ## Parameters
233
+
234
+ ### name
235
+
236
+ `string`
237
+
238
+ ### logger
239
+
240
+ `Logger` | `undefined`
241
+
242
+ ### func
243
+
244
+ () => `Promise`\<`TResult`\>
245
+
246
+ ### budget
247
+
248
+ `number`
249
+
250
+ ### status?
251
+
252
+ `boolean` = `false`
253
+
254
+ ## Returns
255
+
256
+ `Promise`\<`TResult`\>
257
+
258
+ ### interfaces
259
+
260
+ ### <a id="SpanConfig"></a>SpanConfig
261
+
262
+ [**@xylabs/telemetry**](#../README)
263
+
264
+ ***
265
+
266
+ ## Properties
267
+
268
+ ### logger?
269
+
270
+ ```ts
271
+ optional logger: Logger | null;
272
+ ```
273
+
274
+ ***
275
+
276
+ ### timeBudgetLimit?
277
+
278
+ ```ts
279
+ optional timeBudgetLimit: number;
280
+ ```
281
+
282
+ ***
283
+
284
+ ### tracer?
285
+
286
+ ```ts
287
+ optional tracer: Tracer;
288
+ ```
289
+
206
290
 
207
291
  Part of [sdk-js](https://www.npmjs.com/package/@xyo-network/sdk-js)
208
292
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xylabs/telemetry",
3
- "version": "5.0.79",
3
+ "version": "5.0.81",
4
4
  "description": "Base functionality used throughout XY Labs TypeScript/JavaScript libraries",
5
5
  "keywords": [
6
6
  "hex",
@@ -29,30 +29,28 @@
29
29
  "exports": {
30
30
  ".": {
31
31
  "types": "./dist/neutral/index.d.ts",
32
- "source": "./src/index.ts",
33
32
  "default": "./dist/neutral/index.mjs"
34
33
  },
35
34
  "./package.json": "./package.json"
36
35
  },
37
36
  "module": "./dist/neutral/index.mjs",
38
- "source": "./src/index.ts",
39
37
  "types": "./dist/neutral/index.d.ts",
40
38
  "files": [
41
39
  "dist",
42
- "src",
43
40
  "!**/*.bench.*",
44
41
  "!**/*.spec.*",
45
42
  "!**/*.test.*"
46
43
  ],
47
44
  "dependencies": {
48
45
  "@opentelemetry/api": "^1.9.0",
49
- "@xylabs/logger": "~5.0.79",
50
- "@xylabs/typeof": "~5.0.79"
46
+ "@xylabs/logger": "~5.0.81",
47
+ "@xylabs/typeof": "~5.0.81"
51
48
  },
52
49
  "devDependencies": {
53
- "@xylabs/ts-scripts-yarn3": "~7.3.2",
54
- "@xylabs/tsconfig": "~7.3.2",
55
- "typescript": "~5.9.3"
50
+ "@xylabs/ts-scripts-yarn3": "~7.4.11",
51
+ "@xylabs/tsconfig": "~7.4.11",
52
+ "typescript": "~5.9.3",
53
+ "vitest": "~4.0.18"
56
54
  },
57
55
  "engines": {
58
56
  "node": ">=18"
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './span.ts'
2
- export * from './timeBudget.ts'
package/src/span.ts DELETED
@@ -1,160 +0,0 @@
1
- import type {
2
- Context,
3
- Tracer,
4
- } from '@opentelemetry/api'
5
- import {
6
- context, propagation, ROOT_CONTEXT, SpanStatusCode, trace as TRACE_API,
7
- } from '@opentelemetry/api'
8
- import type { Logger } from '@xylabs/logger'
9
- import { isDefined } from '@xylabs/typeof'
10
-
11
- import { timeBudget } from './timeBudget.ts'
12
-
13
- export interface SpanConfig {
14
- logger?: Logger | null
15
- timeBudgetLimit?: number
16
- tracer?: Tracer
17
- }
18
-
19
- export function cloneContextWithoutSpan(activeCtx: Context, configKeys: symbol[] = []): Context {
20
- // Start from root to ensure no span is propagated
21
- let newCtx = ROOT_CONTEXT
22
-
23
- // Copy baggage
24
- const baggage = propagation.getBaggage(activeCtx)
25
- if (baggage) {
26
- newCtx = propagation.setBaggage(newCtx, baggage)
27
- }
28
-
29
- // Copy custom config keys
30
- for (const key of configKeys) {
31
- const value = activeCtx.getValue(key)
32
- if (value !== undefined) {
33
- newCtx = newCtx.setValue(key, value)
34
- }
35
- }
36
-
37
- return newCtx
38
- }
39
-
40
- export function span<T>(name: string, fn: () => T, tracer?: Tracer): T {
41
- const activeTracer = tracer ?? TRACE_API.getTracer(name)
42
- if (isDefined(activeTracer)) {
43
- const span = activeTracer.startSpan(name)
44
- return context.with(TRACE_API.setSpan(context.active(), span), () => {
45
- try {
46
- const result = fn()
47
- span.setStatus({ code: SpanStatusCode.OK })
48
- return result
49
- } catch (ex) {
50
- const error = ex as Error
51
- span.recordException(error)
52
- span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
53
- throw ex
54
- } finally {
55
- span.end()
56
- }
57
- })
58
- } else {
59
- return fn()
60
- }
61
- }
62
-
63
- export function spanRoot<T>(name: string, fn: () => T, tracer?: Tracer): T {
64
- const activeTracer = tracer ?? TRACE_API.getTracer(name)
65
- if (isDefined(activeTracer)) {
66
- // Get current active context for configuration
67
- const activeContext = context.active()
68
-
69
- // Create a new context with no active span
70
- const noSpanContext = cloneContextWithoutSpan(activeContext)
71
-
72
- // Create a new span in the context without an active span
73
- const span = activeTracer.startSpan(name, {}, noSpanContext)
74
-
75
- // Use the active context but replace its span with our new root span
76
- return context.with(TRACE_API.setSpan(noSpanContext, span), () => {
77
- try {
78
- const result = fn()
79
- span.setStatus({ code: SpanStatusCode.OK })
80
- return result
81
- } catch (ex) {
82
- const error = ex as Error
83
- span.recordException(error)
84
- span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
85
- throw ex
86
- } finally {
87
- span.end()
88
- }
89
- })
90
- } else {
91
- return fn()
92
- }
93
- }
94
-
95
- export async function spanAsync<T>(
96
- name: string,
97
- fn: () => Promise<T>,
98
- {
99
- timeBudgetLimit, logger, tracer,
100
- }: SpanConfig = {},
101
- ): Promise<T> {
102
- const activeTracer = tracer ?? TRACE_API.getTracer(name)
103
- const funcToRun = isDefined(timeBudgetLimit) ? () => timeBudget(name, logger ?? console, fn, timeBudgetLimit) : fn
104
- if (isDefined(activeTracer)) {
105
- const span = activeTracer.startSpan(name)
106
- return await context.with(TRACE_API.setSpan(context.active(), span), async () => {
107
- try {
108
- const result = await funcToRun()
109
- span.setStatus({ code: SpanStatusCode.OK })
110
- return result
111
- } catch (ex) {
112
- const error = ex as Error
113
- span.recordException(error)
114
- span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
115
- throw ex
116
- } finally {
117
- span.end()
118
- }
119
- })
120
- } else {
121
- return await funcToRun()
122
- }
123
- }
124
-
125
- export async function spanRootAsync<T>(
126
- name: string,
127
- fn: () => Promise<T>,
128
- {
129
- timeBudgetLimit, logger, tracer,
130
- }: SpanConfig = {},
131
- ): Promise<T> {
132
- const funcToRun = isDefined(timeBudgetLimit) ? () => timeBudget(name, logger ?? console, fn, timeBudgetLimit) : fn
133
- const activeTracer = tracer ?? TRACE_API.getTracer(name)
134
- if (isDefined(activeTracer)) {
135
- const activeContext = context.active()
136
-
137
- const noSpanContext = cloneContextWithoutSpan(activeContext)
138
-
139
- // Create a new span in the context without an active span
140
- const span = activeTracer.startSpan(name, {}, noSpanContext)
141
-
142
- // Use the active context but replace its span with our new root span
143
- return await context.with(TRACE_API.setSpan(noSpanContext, span), async () => {
144
- try {
145
- const result = await funcToRun()
146
- span.setStatus({ code: SpanStatusCode.OK })
147
- return result
148
- } catch (ex) {
149
- const error = ex as Error
150
- span.recordException(error)
151
- span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })
152
- throw ex
153
- } finally {
154
- span.end()
155
- }
156
- })
157
- } else {
158
- return await funcToRun()
159
- }
160
- }
package/src/timeBudget.ts DELETED
@@ -1,30 +0,0 @@
1
- import type { Logger } from '@xylabs/logger'
2
-
3
- export async function timeBudget<TResult>(
4
- name: string,
5
- logger: Logger | undefined,
6
- func: () => Promise<TResult>,
7
- budget: number,
8
- status = false,
9
- ): Promise<TResult> {
10
- const start = Date.now()
11
- const timer = status
12
- ? setInterval(() => {
13
- const duration = Date.now() - start
14
- if ((budget > 0) && (duration > budget)) {
15
- logger?.warn(`Function [${name}] execution is exceeding budget: ${duration}ms > ${budget}ms`)
16
- }
17
- }, Math.max(100, budget))
18
- : undefined
19
-
20
- const result = await func()
21
- const duration = Date.now() - start
22
-
23
- if (!timer && (budget > 0) && (duration > budget)) {
24
- logger?.warn(`Function [${name}] execution exceeded budget: ${duration}ms > ${budget}ms`)
25
- }
26
- if (timer) {
27
- clearInterval(timer)
28
- }
29
- return result
30
- }