@livestore/utils-dev 0.0.0-snapshot-5a6440f111a5a7c2441a649866587d5d51e22820.3 → 0.0.0-snapshot-412a36a7e6c9b0e9e237b553fd0522aed285228f

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.
@@ -1,12 +1,14 @@
1
- import type { OtelTracer, Tracer } from '@livestore/utils/effect';
2
- import { Effect, Layer } from '@livestore/utils/effect';
3
- import type * as otel from '@opentelemetry/api';
1
+ import type { Tracer } from '@livestore/utils/effect';
2
+ import { Effect, Layer, OtelTracer } from '@livestore/utils/effect';
3
+ import * as otel from '@opentelemetry/api';
4
4
  export { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
5
5
  export { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
6
- export declare const OtelLiveHttp: ({ serviceName, rootSpanName, skipLogUrl, }?: {
6
+ export declare const OtelLiveHttp: ({ serviceName, rootSpanName, rootSpanAttributes, skipLogUrl, traceNodeBootstrap, }?: {
7
7
  serviceName?: string;
8
8
  rootSpanName?: string;
9
+ rootSpanAttributes?: Record<string, unknown>;
9
10
  skipLogUrl?: boolean;
11
+ traceNodeBootstrap?: boolean;
10
12
  }) => Layer.Layer<OtelTracer.OtelTracer | Tracer.ParentSpan, never, never>;
11
13
  export declare const logTraceUiUrlForSpan: (printMsg?: (url: string) => string) => (span: otel.Span) => Effect.Effect<string | undefined, never, never>;
12
14
  export declare const getTracingBackendUrl: (span: otel.Span) => Effect.Effect<string | undefined, never, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/node/mod.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAU,MAAM,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,KAAK,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAM/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAA;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAA;AAE9E,eAAO,MAAM,YAAY,GAAI,6CAI1B;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,KAAG,KAAK,CAAC,KAAK,CACzF,UAAU,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,EACzC,KAAK,EACL,KAAK,CAsC6B,CAAA;AAEpC,eAAO,MAAM,oBAAoB,GAAI,WAAW,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,MAAM,MAAM,IAAI,CAAC,IAAI,oDAazF,CAAA;AAEH,eAAO,MAAM,oBAAoB,GAAI,MAAM,IAAI,CAAC,IAAI,oDAqBhD,CAAA"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/node/mod.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAU,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAE3E,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAM1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAA;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,2CAA2C,CAAA;AAE9E,eAAO,MAAM,YAAY,GAAI,qFAM1B;IACD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC5C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAA;CACxB,KAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CA2ExC,CAAA;AAEpC,eAAO,MAAM,oBAAoB,GAAI,WAAW,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,MAAM,MAAM,IAAI,CAAC,IAAI,oDAazF,CAAA;AAEH,eAAO,MAAM,oBAAoB,GAAI,MAAM,IAAI,CAAC,IAAI,oDAqBhD,CAAA"}
package/dist/node/mod.js CHANGED
@@ -1,40 +1,70 @@
1
+ import { performance } from 'node:perf_hooks';
1
2
  import * as OtelNodeSdk from '@effect/opentelemetry/NodeSdk';
2
- import { Config, Effect, Layer } from '@livestore/utils/effect';
3
+ import { IS_BUN } from '@livestore/utils';
4
+ import { Config, Effect, Layer, OtelTracer } from '@livestore/utils/effect';
5
+ import { OtelLiveDummy } from '@livestore/utils/node';
6
+ import * as otel from '@opentelemetry/api';
3
7
  import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
4
8
  import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
5
9
  import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
6
10
  import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
7
11
  export { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
8
12
  export { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
9
- export const OtelLiveHttp = ({ serviceName, rootSpanName, skipLogUrl, } = {}) => Effect.gen(function* () {
10
- const config = yield* Config.all({
13
+ export const OtelLiveHttp = ({ serviceName, rootSpanName, rootSpanAttributes, skipLogUrl, traceNodeBootstrap, } = {}) => Effect.gen(function* () {
14
+ const configRes = yield* Config.all({
11
15
  exporterUrl: Config.string('OTEL_EXPORTER_OTLP_ENDPOINT'),
12
16
  serviceName: serviceName
13
17
  ? Config.succeed(serviceName)
14
- : Config.string('OTEL_SERVICE_NAME').pipe(Config.withDefault('overtone-node-utils-default-service')),
18
+ : Config.string('OTEL_SERVICE_NAME').pipe(Config.withDefault('livestore-utils-dev')),
15
19
  rootSpanName: rootSpanName
16
20
  ? Config.succeed(rootSpanName)
17
21
  : Config.string('OTEL_ROOT_SPAN_NAME').pipe(Config.withDefault('RootSpan')),
18
- }).pipe(Effect.tapCauseLogPretty, Effect.orDie);
22
+ }).pipe(Effect.option);
23
+ if (configRes._tag === 'None') {
24
+ const RootSpanLive = Layer.span('DummyRoot', {});
25
+ return RootSpanLive.pipe(Layer.provide(OtelLiveDummy));
26
+ }
27
+ const config = configRes.value;
19
28
  const resource = { serviceName: config.serviceName };
20
- // METRICS
21
- const metricExporter = new OTLPMetricExporter({ url: `${config.exporterUrl}/v1/metrics` });
22
29
  const metricReader = new PeriodicExportingMetricReader({
23
- exporter: metricExporter,
30
+ exporter: new OTLPMetricExporter({ url: `${config.exporterUrl}/v1/metrics` }),
24
31
  exportIntervalMillis: 1000,
25
32
  });
26
- // TRACING
27
33
  const OtelLive = OtelNodeSdk.layer(() => ({
28
34
  resource,
29
35
  metricReader,
30
- spanProcessor: new BatchSpanProcessor(new OTLPTraceExporter({ url: `${config.exporterUrl}/v1/traces`, headers: {} })),
36
+ spanProcessor: new BatchSpanProcessor(new OTLPTraceExporter({ url: `${config.exporterUrl}/v1/traces`, headers: {} }), { scheduledDelayMillis: 50 }),
31
37
  }));
32
38
  const RootSpanLive = Layer.span(config.rootSpanName, {
33
- attributes: { config },
39
+ attributes: { config, ...rootSpanAttributes },
34
40
  onEnd: skipLogUrl ? undefined : (span) => logTraceUiUrlForSpan()(span.span),
35
41
  });
36
- return RootSpanLive.pipe(Layer.provideMerge(OtelLive));
37
- }).pipe(Layer.unwrapEffect);
42
+ const layer = yield* Layer.memoize(RootSpanLive.pipe(Layer.provideMerge(OtelLive)));
43
+ if (traceNodeBootstrap) {
44
+ /**
45
+ * Create a span representing the Node.js bootstrap duration.
46
+ */
47
+ yield* Effect.gen(function* () {
48
+ const tracer = yield* OtelTracer.OtelTracer;
49
+ const currentSpan = yield* OtelTracer.currentOtelSpan;
50
+ const nodeTiming = performance.nodeTiming;
51
+ // TODO get rid of this workaround for Bun once Bun properly supports performance.nodeTiming
52
+ const startTime = IS_BUN ? nodeTiming.startTime : performance.timeOrigin + nodeTiming.nodeStart;
53
+ const bootSpan = tracer.startSpan('node-bootstrap', {
54
+ startTime: nodeTiming.nodeStart,
55
+ attributes: {
56
+ 'node.timing.nodeStart': nodeTiming.nodeStart,
57
+ 'node.timing.environment': nodeTiming.environment,
58
+ 'node.timing.bootstrapComplete': nodeTiming.bootstrapComplete,
59
+ 'node.timing.loopStart': nodeTiming.loopStart,
60
+ 'node.timing.duration': nodeTiming.duration,
61
+ },
62
+ }, otel.trace.setSpanContext(otel.context.active(), currentSpan.spanContext()));
63
+ bootSpan.end(startTime + nodeTiming.duration);
64
+ }).pipe(Effect.provide(layer), Effect.orDie);
65
+ }
66
+ return layer;
67
+ }).pipe(Layer.unwrapScoped);
38
68
  export const logTraceUiUrlForSpan = (printMsg) => (span) => getTracingBackendUrl(span).pipe(Effect.tap((url) => {
39
69
  if (url === undefined) {
40
70
  return Effect.logWarning('No tracing backend url found');
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/node/mod.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/node/mod.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livestore/utils-dev",
3
- "version": "0.0.0-snapshot-5a6440f111a5a7c2441a649866587d5d51e22820.3",
3
+ "version": "0.0.0-snapshot-412a36a7e6c9b0e9e237b553fd0522aed285228f",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "./dist/node-vitest/polyfill.js"
@@ -28,7 +28,7 @@
28
28
  "@opentelemetry/sdk-metrics": "2.0.0",
29
29
  "@opentelemetry/sdk-trace-base": "2.0.0",
30
30
  "@opentelemetry/sdk-trace-node": "2.0.0",
31
- "@livestore/utils": "0.0.0-snapshot-5a6440f111a5a7c2441a649866587d5d51e22820.3"
31
+ "@livestore/utils": "0.0.0-snapshot-412a36a7e6c9b0e9e237b553fd0522aed285228f"
32
32
  },
33
33
  "devDependencies": {},
34
34
  "files": [
package/src/node/mod.ts CHANGED
@@ -1,7 +1,11 @@
1
+ import { performance } from 'node:perf_hooks'
2
+
1
3
  import * as OtelNodeSdk from '@effect/opentelemetry/NodeSdk'
2
- import type { OtelTracer, Tracer } from '@livestore/utils/effect'
3
- import { Config, Effect, Layer } from '@livestore/utils/effect'
4
- import type * as otel from '@opentelemetry/api'
4
+ import { IS_BUN } from '@livestore/utils'
5
+ import type { Tracer } from '@livestore/utils/effect'
6
+ import { Config, Effect, Layer, OtelTracer } from '@livestore/utils/effect'
7
+ import { OtelLiveDummy } from '@livestore/utils/node'
8
+ import * as otel from '@opentelemetry/api'
5
9
  import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'
6
10
  import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
7
11
  import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'
@@ -13,49 +17,91 @@ export { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'
13
17
  export const OtelLiveHttp = ({
14
18
  serviceName,
15
19
  rootSpanName,
20
+ rootSpanAttributes,
16
21
  skipLogUrl,
17
- }: { serviceName?: string; rootSpanName?: string; skipLogUrl?: boolean } = {}): Layer.Layer<
18
- OtelTracer.OtelTracer | Tracer.ParentSpan,
19
- never,
20
- never
21
- > =>
22
+ traceNodeBootstrap,
23
+ }: {
24
+ serviceName?: string
25
+ rootSpanName?: string
26
+ rootSpanAttributes?: Record<string, unknown>
27
+ skipLogUrl?: boolean
28
+ traceNodeBootstrap?: boolean
29
+ } = {}): Layer.Layer<OtelTracer.OtelTracer | Tracer.ParentSpan, never, never> =>
22
30
  Effect.gen(function* () {
23
- const config = yield* Config.all({
31
+ const configRes = yield* Config.all({
24
32
  exporterUrl: Config.string('OTEL_EXPORTER_OTLP_ENDPOINT'),
25
33
  serviceName: serviceName
26
34
  ? Config.succeed(serviceName)
27
- : Config.string('OTEL_SERVICE_NAME').pipe(Config.withDefault('overtone-node-utils-default-service')),
35
+ : Config.string('OTEL_SERVICE_NAME').pipe(Config.withDefault('livestore-utils-dev')),
28
36
  rootSpanName: rootSpanName
29
37
  ? Config.succeed(rootSpanName)
30
38
  : Config.string('OTEL_ROOT_SPAN_NAME').pipe(Config.withDefault('RootSpan')),
31
- }).pipe(Effect.tapCauseLogPretty, Effect.orDie)
39
+ }).pipe(Effect.option)
32
40
 
33
- const resource = { serviceName: config.serviceName }
41
+ if (configRes._tag === 'None') {
42
+ const RootSpanLive = Layer.span('DummyRoot', {})
43
+ return RootSpanLive.pipe(Layer.provide(OtelLiveDummy))
44
+ }
34
45
 
35
- // METRICS
36
- const metricExporter = new OTLPMetricExporter({ url: `${config.exporterUrl}/v1/metrics` })
46
+ const config = configRes.value
47
+
48
+ const resource = { serviceName: config.serviceName }
37
49
 
38
50
  const metricReader = new PeriodicExportingMetricReader({
39
- exporter: metricExporter,
51
+ exporter: new OTLPMetricExporter({ url: `${config.exporterUrl}/v1/metrics` }),
40
52
  exportIntervalMillis: 1000,
41
53
  })
42
54
 
43
- // TRACING
44
55
  const OtelLive = OtelNodeSdk.layer(() => ({
45
56
  resource,
46
57
  metricReader,
47
58
  spanProcessor: new BatchSpanProcessor(
48
59
  new OTLPTraceExporter({ url: `${config.exporterUrl}/v1/traces`, headers: {} }),
60
+ { scheduledDelayMillis: 50 },
49
61
  ),
50
62
  }))
51
63
 
52
64
  const RootSpanLive = Layer.span(config.rootSpanName, {
53
- attributes: { config },
65
+ attributes: { config, ...rootSpanAttributes },
54
66
  onEnd: skipLogUrl ? undefined : (span: any) => logTraceUiUrlForSpan()(span.span),
55
67
  })
56
68
 
57
- return RootSpanLive.pipe(Layer.provideMerge(OtelLive))
58
- }).pipe(Layer.unwrapEffect) as any
69
+ const layer = yield* Layer.memoize(RootSpanLive.pipe(Layer.provideMerge(OtelLive)))
70
+
71
+ if (traceNodeBootstrap) {
72
+ /**
73
+ * Create a span representing the Node.js bootstrap duration.
74
+ */
75
+ yield* Effect.gen(function* () {
76
+ const tracer = yield* OtelTracer.OtelTracer
77
+ const currentSpan = yield* OtelTracer.currentOtelSpan
78
+
79
+ const nodeTiming = performance.nodeTiming
80
+
81
+ // TODO get rid of this workaround for Bun once Bun properly supports performance.nodeTiming
82
+ const startTime = IS_BUN ? nodeTiming.startTime : performance.timeOrigin + nodeTiming.nodeStart
83
+
84
+ const bootSpan = tracer.startSpan(
85
+ 'node-bootstrap',
86
+ {
87
+ startTime: nodeTiming.nodeStart,
88
+ attributes: {
89
+ 'node.timing.nodeStart': nodeTiming.nodeStart,
90
+ 'node.timing.environment': nodeTiming.environment,
91
+ 'node.timing.bootstrapComplete': nodeTiming.bootstrapComplete,
92
+ 'node.timing.loopStart': nodeTiming.loopStart,
93
+ 'node.timing.duration': nodeTiming.duration,
94
+ },
95
+ },
96
+ otel.trace.setSpanContext(otel.context.active(), currentSpan.spanContext()),
97
+ )
98
+
99
+ bootSpan.end(startTime + nodeTiming.duration)
100
+ }).pipe(Effect.provide(layer), Effect.orDie)
101
+ }
102
+
103
+ return layer
104
+ }).pipe(Layer.unwrapScoped) as any
59
105
 
60
106
  export const logTraceUiUrlForSpan = (printMsg?: (url: string) => string) => (span: otel.Span) =>
61
107
  getTracingBackendUrl(span).pipe(