@livestore/utils-dev 0.0.0-snapshot-5a6440f111a5a7c2441a649866587d5d51e22820.2 → 0.0.0-snapshot-54e706b7e73bd685653cd43e1e34a02c1d8054a2

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,11 +1,12 @@
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, }?: {
7
7
  serviceName?: string;
8
8
  rootSpanName?: string;
9
+ rootSpanAttributes?: Record<string, unknown>;
9
10
  skipLogUrl?: boolean;
10
11
  }) => Layer.Layer<OtelTracer.OtelTracer | Tracer.ParentSpan, never, never>;
11
12
  export declare const logTraceUiUrlForSpan: (printMsg?: (url: string) => string) => (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":"AAGA,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,iEAK1B;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;CAChB,KAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAsExC,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,65 @@
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 { Config, Effect, Layer, OtelTracer } from '@livestore/utils/effect';
4
+ import { OtelLiveDummy } from '@livestore/utils/node';
5
+ import * as otel from '@opentelemetry/api';
3
6
  import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
4
7
  import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
5
8
  import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
6
9
  import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
7
10
  export { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
8
11
  export { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
9
- export const OtelLiveHttp = ({ serviceName, rootSpanName, skipLogUrl, } = {}) => Effect.gen(function* () {
10
- const config = yield* Config.all({
12
+ export const OtelLiveHttp = ({ serviceName, rootSpanName, rootSpanAttributes, skipLogUrl, } = {}) => Effect.gen(function* () {
13
+ const configRes = yield* Config.all({
11
14
  exporterUrl: Config.string('OTEL_EXPORTER_OTLP_ENDPOINT'),
12
15
  serviceName: serviceName
13
16
  ? Config.succeed(serviceName)
14
- : Config.string('OTEL_SERVICE_NAME').pipe(Config.withDefault('overtone-node-utils-default-service')),
17
+ : Config.string('OTEL_SERVICE_NAME').pipe(Config.withDefault('livestore-utils-dev')),
15
18
  rootSpanName: rootSpanName
16
19
  ? Config.succeed(rootSpanName)
17
20
  : Config.string('OTEL_ROOT_SPAN_NAME').pipe(Config.withDefault('RootSpan')),
18
- }).pipe(Effect.tapCauseLogPretty, Effect.orDie);
21
+ }).pipe(Effect.option);
22
+ if (configRes._tag === 'None') {
23
+ const RootSpanLive = Layer.span('DummyRoot', {});
24
+ return RootSpanLive.pipe(Layer.provide(OtelLiveDummy));
25
+ }
26
+ const config = configRes.value;
19
27
  const resource = { serviceName: config.serviceName };
20
- // METRICS
21
- const metricExporter = new OTLPMetricExporter({ url: `${config.exporterUrl}/v1/metrics` });
22
28
  const metricReader = new PeriodicExportingMetricReader({
23
- exporter: metricExporter,
29
+ exporter: new OTLPMetricExporter({ url: `${config.exporterUrl}/v1/metrics` }),
24
30
  exportIntervalMillis: 1000,
25
31
  });
26
- // TRACING
27
32
  const OtelLive = OtelNodeSdk.layer(() => ({
28
33
  resource,
29
34
  metricReader,
30
- spanProcessor: new BatchSpanProcessor(new OTLPTraceExporter({ url: `${config.exporterUrl}/v1/traces`, headers: {} })),
35
+ spanProcessor: new BatchSpanProcessor(new OTLPTraceExporter({ url: `${config.exporterUrl}/v1/traces`, headers: {} }), { scheduledDelayMillis: 50 }),
31
36
  }));
32
37
  const RootSpanLive = Layer.span(config.rootSpanName, {
33
- attributes: { config },
38
+ attributes: { config, ...rootSpanAttributes },
34
39
  onEnd: skipLogUrl ? undefined : (span) => logTraceUiUrlForSpan()(span.span),
35
40
  });
36
- return RootSpanLive.pipe(Layer.provideMerge(OtelLive));
37
- }).pipe(Layer.unwrapEffect);
41
+ const layer = yield* Layer.memoize(RootSpanLive.pipe(Layer.provideMerge(OtelLive)));
42
+ /**
43
+ * Create a span representing the Node.js bootstrap duration.
44
+ */
45
+ yield* Effect.gen(function* () {
46
+ const tracer = yield* OtelTracer.OtelTracer;
47
+ const currentSpan = yield* OtelTracer.currentOtelSpan;
48
+ const nodeTiming = performance.nodeTiming;
49
+ const bootSpan = tracer.startSpan('node-bootstrap', {
50
+ startTime: nodeTiming.nodeStart,
51
+ attributes: {
52
+ 'node.timing.nodeStart': nodeTiming.nodeStart,
53
+ 'node.timing.environment': nodeTiming.environment,
54
+ 'node.timing.bootstrapComplete': nodeTiming.bootstrapComplete,
55
+ 'node.timing.loopStart': nodeTiming.loopStart,
56
+ },
57
+ }, otel.trace.setSpanContext(otel.context.active(), currentSpan.spanContext()));
58
+ // bootSpan.end(nodeTiming.environment)
59
+ bootSpan.end(nodeTiming.nodeStart + nodeTiming.duration);
60
+ }).pipe(Effect.provide(layer), Effect.orDie);
61
+ return layer;
62
+ }).pipe(Layer.unwrapScoped);
38
63
  export const logTraceUiUrlForSpan = (printMsg) => (span) => getTracingBackendUrl(span).pipe(Effect.tap((url) => {
39
64
  if (url === undefined) {
40
65
  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.2",
3
+ "version": "0.0.0-snapshot-54e706b7e73bd685653cd43e1e34a02c1d8054a2",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "./dist/node-vitest/polyfill.js"
@@ -20,17 +20,22 @@
20
20
  }
21
21
  },
22
22
  "dependencies": {
23
- "@effect/opentelemetry": "^0.46.4",
24
- "@effect/vitest": "^0.20.8",
25
- "@opentelemetry/api": "^1.9.0",
23
+ "@effect/opentelemetry": "0.46.4",
24
+ "@effect/vitest": "0.20.8",
25
+ "@opentelemetry/api": "1.9.0",
26
26
  "@opentelemetry/exporter-metrics-otlp-http": "0.200.0",
27
27
  "@opentelemetry/exporter-trace-otlp-http": "0.200.0",
28
- "@opentelemetry/sdk-metrics": "^2.0.0",
29
- "@opentelemetry/sdk-trace-base": "^2.0.0",
30
- "@opentelemetry/sdk-trace-node": "^2.0.0",
31
- "@livestore/utils": "0.0.0-snapshot-5a6440f111a5a7c2441a649866587d5d51e22820.2"
28
+ "@opentelemetry/sdk-metrics": "2.0.0",
29
+ "@opentelemetry/sdk-trace-base": "2.0.0",
30
+ "@opentelemetry/sdk-trace-node": "2.0.0",
31
+ "@livestore/utils": "0.0.0-snapshot-54e706b7e73bd685653cd43e1e34a02c1d8054a2"
32
32
  },
33
33
  "devDependencies": {},
34
+ "files": [
35
+ "package.json",
36
+ "src",
37
+ "dist"
38
+ ],
34
39
  "peerDependencies": {},
35
40
  "publishConfig": {
36
41
  "access": "public"
package/src/node/mod.ts CHANGED
@@ -1,7 +1,10 @@
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 type { Tracer } from '@livestore/utils/effect'
5
+ import { Config, Effect, Layer, OtelTracer } from '@livestore/utils/effect'
6
+ import { OtelLiveDummy } from '@livestore/utils/node'
7
+ import * as otel from '@opentelemetry/api'
5
8
  import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'
6
9
  import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
7
10
  import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'
@@ -13,49 +16,84 @@ export { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'
13
16
  export const OtelLiveHttp = ({
14
17
  serviceName,
15
18
  rootSpanName,
19
+ rootSpanAttributes,
16
20
  skipLogUrl,
17
- }: { serviceName?: string; rootSpanName?: string; skipLogUrl?: boolean } = {}): Layer.Layer<
18
- OtelTracer.OtelTracer | Tracer.ParentSpan,
19
- never,
20
- never
21
- > =>
21
+ }: {
22
+ serviceName?: string
23
+ rootSpanName?: string
24
+ rootSpanAttributes?: Record<string, unknown>
25
+ skipLogUrl?: boolean
26
+ } = {}): Layer.Layer<OtelTracer.OtelTracer | Tracer.ParentSpan, never, never> =>
22
27
  Effect.gen(function* () {
23
- const config = yield* Config.all({
28
+ const configRes = yield* Config.all({
24
29
  exporterUrl: Config.string('OTEL_EXPORTER_OTLP_ENDPOINT'),
25
30
  serviceName: serviceName
26
31
  ? Config.succeed(serviceName)
27
- : Config.string('OTEL_SERVICE_NAME').pipe(Config.withDefault('overtone-node-utils-default-service')),
32
+ : Config.string('OTEL_SERVICE_NAME').pipe(Config.withDefault('livestore-utils-dev')),
28
33
  rootSpanName: rootSpanName
29
34
  ? Config.succeed(rootSpanName)
30
35
  : Config.string('OTEL_ROOT_SPAN_NAME').pipe(Config.withDefault('RootSpan')),
31
- }).pipe(Effect.tapCauseLogPretty, Effect.orDie)
36
+ }).pipe(Effect.option)
32
37
 
33
- const resource = { serviceName: config.serviceName }
38
+ if (configRes._tag === 'None') {
39
+ const RootSpanLive = Layer.span('DummyRoot', {})
40
+ return RootSpanLive.pipe(Layer.provide(OtelLiveDummy))
41
+ }
34
42
 
35
- // METRICS
36
- const metricExporter = new OTLPMetricExporter({ url: `${config.exporterUrl}/v1/metrics` })
43
+ const config = configRes.value
44
+
45
+ const resource = { serviceName: config.serviceName }
37
46
 
38
47
  const metricReader = new PeriodicExportingMetricReader({
39
- exporter: metricExporter,
48
+ exporter: new OTLPMetricExporter({ url: `${config.exporterUrl}/v1/metrics` }),
40
49
  exportIntervalMillis: 1000,
41
50
  })
42
51
 
43
- // TRACING
44
52
  const OtelLive = OtelNodeSdk.layer(() => ({
45
53
  resource,
46
54
  metricReader,
47
55
  spanProcessor: new BatchSpanProcessor(
48
56
  new OTLPTraceExporter({ url: `${config.exporterUrl}/v1/traces`, headers: {} }),
57
+ { scheduledDelayMillis: 50 },
49
58
  ),
50
59
  }))
51
60
 
52
61
  const RootSpanLive = Layer.span(config.rootSpanName, {
53
- attributes: { config },
62
+ attributes: { config, ...rootSpanAttributes },
54
63
  onEnd: skipLogUrl ? undefined : (span: any) => logTraceUiUrlForSpan()(span.span),
55
64
  })
56
65
 
57
- return RootSpanLive.pipe(Layer.provideMerge(OtelLive))
58
- }).pipe(Layer.unwrapEffect) as any
66
+ const layer = yield* Layer.memoize(RootSpanLive.pipe(Layer.provideMerge(OtelLive)))
67
+
68
+ /**
69
+ * Create a span representing the Node.js bootstrap duration.
70
+ */
71
+ yield* Effect.gen(function* () {
72
+ const tracer = yield* OtelTracer.OtelTracer
73
+ const currentSpan = yield* OtelTracer.currentOtelSpan
74
+
75
+ const nodeTiming = performance.nodeTiming
76
+
77
+ const bootSpan = tracer.startSpan(
78
+ 'node-bootstrap',
79
+ {
80
+ startTime: nodeTiming.nodeStart,
81
+ attributes: {
82
+ 'node.timing.nodeStart': nodeTiming.nodeStart,
83
+ 'node.timing.environment': nodeTiming.environment,
84
+ 'node.timing.bootstrapComplete': nodeTiming.bootstrapComplete,
85
+ 'node.timing.loopStart': nodeTiming.loopStart,
86
+ },
87
+ },
88
+ otel.trace.setSpanContext(otel.context.active(), currentSpan.spanContext()),
89
+ )
90
+
91
+ // bootSpan.end(nodeTiming.environment)
92
+ bootSpan.end(nodeTiming.nodeStart + nodeTiming.duration)
93
+ }).pipe(Effect.provide(layer), Effect.orDie)
94
+
95
+ return layer
96
+ }).pipe(Layer.unwrapScoped) as any
59
97
 
60
98
  export const logTraceUiUrlForSpan = (printMsg?: (url: string) => string) => (span: otel.Span) =>
61
99
  getTracingBackendUrl(span).pipe(
package/tsconfig.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "rootDir": "./src",
5
- "outDir": "./dist",
6
- "tsBuildInfoFile": "./dist/.tsbuildinfo.json"
7
- },
8
- "include": ["./src"],
9
- "references": []
10
- }