veryfront 0.1.246 → 0.1.248

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 (160) hide show
  1. package/esm/cli/mcp/tools/project-tools.d.ts +1 -1
  2. package/esm/cli/mcp/tools/scaffold-tools.d.ts +2 -2
  3. package/esm/cli/shared/server-startup.d.ts.map +1 -1
  4. package/esm/cli/shared/server-startup.js +8 -0
  5. package/esm/deno.d.ts +0 -9
  6. package/esm/deno.js +5 -12
  7. package/esm/src/agent/durable.d.ts +67 -0
  8. package/esm/src/agent/durable.d.ts.map +1 -1
  9. package/esm/src/agent/durable.js +134 -0
  10. package/esm/src/agent/index.d.ts +1 -1
  11. package/esm/src/agent/index.d.ts.map +1 -1
  12. package/esm/src/agent/index.js +1 -1
  13. package/esm/src/embedding/upload-loader.d.ts +2 -2
  14. package/esm/src/embedding/upload-loader.d.ts.map +1 -1
  15. package/esm/src/embedding/upload-loader.js +11 -48
  16. package/esm/src/errors/middleware/cli-error-boundary.js +1 -1
  17. package/esm/src/errors/middleware/http-error-boundary.js +1 -1
  18. package/esm/src/errors/tracing.d.ts +3 -3
  19. package/esm/src/errors/tracing.d.ts.map +1 -1
  20. package/esm/src/errors/tracing.js +3 -3
  21. package/esm/src/extensions/interfaces/index.d.ts +2 -2
  22. package/esm/src/extensions/interfaces/index.d.ts.map +1 -1
  23. package/esm/src/extensions/interfaces/node-compat.d.ts +68 -10
  24. package/esm/src/extensions/interfaces/node-compat.d.ts.map +1 -1
  25. package/esm/src/extensions/interfaces/tracing-exporter.d.ts +35 -1
  26. package/esm/src/extensions/interfaces/tracing-exporter.d.ts.map +1 -1
  27. package/esm/src/integrations/schema.d.ts +10 -10
  28. package/esm/src/mcp/index.d.ts +7 -2
  29. package/esm/src/mcp/index.d.ts.map +1 -1
  30. package/esm/src/mcp/index.js +7 -2
  31. package/esm/src/mcp/schemas/index.d.ts +1 -1
  32. package/esm/src/mcp/schemas/index.d.ts.map +1 -1
  33. package/esm/src/mcp/schemas/index.js +1 -1
  34. package/esm/src/mcp/schemas/mcp.schema.d.ts +13 -7
  35. package/esm/src/mcp/schemas/mcp.schema.d.ts.map +1 -1
  36. package/esm/src/mcp/schemas/mcp.schema.js +17 -7
  37. package/esm/src/mcp/server.d.ts +13 -0
  38. package/esm/src/mcp/server.d.ts.map +1 -1
  39. package/esm/src/mcp/server.js +43 -6
  40. package/esm/src/observability/auto-instrument/http-instrumentation.js +1 -1
  41. package/esm/src/observability/auto-instrument/react-instrumentation.js +1 -1
  42. package/esm/src/observability/instruments/build-instruments.d.ts +1 -1
  43. package/esm/src/observability/instruments/build-instruments.d.ts.map +1 -1
  44. package/esm/src/observability/instruments/cache-instruments.d.ts +1 -1
  45. package/esm/src/observability/instruments/cache-instruments.d.ts.map +1 -1
  46. package/esm/src/observability/instruments/data-instruments.d.ts +1 -1
  47. package/esm/src/observability/instruments/data-instruments.d.ts.map +1 -1
  48. package/esm/src/observability/instruments/error-instruments.d.ts +1 -1
  49. package/esm/src/observability/instruments/error-instruments.d.ts.map +1 -1
  50. package/esm/src/observability/instruments/http-instruments.d.ts +1 -1
  51. package/esm/src/observability/instruments/http-instruments.d.ts.map +1 -1
  52. package/esm/src/observability/instruments/instruments-factory.d.ts +1 -1
  53. package/esm/src/observability/instruments/instruments-factory.d.ts.map +1 -1
  54. package/esm/src/observability/instruments/memory-instruments.d.ts +1 -1
  55. package/esm/src/observability/instruments/memory-instruments.d.ts.map +1 -1
  56. package/esm/src/observability/instruments/render-instruments.d.ts +1 -1
  57. package/esm/src/observability/instruments/render-instruments.d.ts.map +1 -1
  58. package/esm/src/observability/instruments/rsc-instruments.d.ts +1 -1
  59. package/esm/src/observability/instruments/rsc-instruments.d.ts.map +1 -1
  60. package/esm/src/observability/metrics/manager.d.ts.map +1 -1
  61. package/esm/src/observability/metrics/manager.js +10 -2
  62. package/esm/src/observability/metrics/types.d.ts +1 -1
  63. package/esm/src/observability/metrics/types.d.ts.map +1 -1
  64. package/esm/src/observability/simple-metrics/otel-instruments.d.ts.map +1 -1
  65. package/esm/src/observability/simple-metrics/otel-instruments.js +7 -2
  66. package/esm/src/observability/simple-metrics/types.d.ts +1 -1
  67. package/esm/src/observability/simple-metrics/types.d.ts.map +1 -1
  68. package/esm/src/observability/tracing/api-shim.d.ts +177 -0
  69. package/esm/src/observability/tracing/api-shim.d.ts.map +1 -0
  70. package/esm/src/observability/tracing/api-shim.js +234 -0
  71. package/esm/src/observability/tracing/manager.d.ts.map +1 -1
  72. package/esm/src/observability/tracing/manager.js +29 -4
  73. package/esm/src/observability/tracing/otlp-setup.d.ts +12 -8
  74. package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
  75. package/esm/src/observability/tracing/otlp-setup.js +59 -136
  76. package/esm/src/observability/tracing/types.d.ts +1 -1
  77. package/esm/src/observability/tracing/types.d.ts.map +1 -1
  78. package/esm/src/platform/compat/kv/factory.d.ts.map +1 -1
  79. package/esm/src/platform/compat/kv/factory.js +15 -6
  80. package/esm/src/platform/compat/opaque-deps.d.ts +6 -5
  81. package/esm/src/platform/compat/opaque-deps.d.ts.map +1 -1
  82. package/esm/src/platform/compat/opaque-deps.js +13 -37
  83. package/esm/src/proxy/tracing.d.ts +7 -2
  84. package/esm/src/proxy/tracing.d.ts.map +1 -1
  85. package/esm/src/proxy/tracing.js +31 -96
  86. package/esm/src/rendering/rsc/client-module-strategy.d.ts.map +1 -1
  87. package/esm/src/rendering/rsc/client-module-strategy.js +9 -1
  88. package/esm/src/server/bootstrap.d.ts.map +1 -1
  89. package/esm/src/server/bootstrap.js +27 -1
  90. package/esm/src/server/context/request-context.d.ts.map +1 -1
  91. package/esm/src/server/context/request-context.js +7 -4
  92. package/esm/src/server/dev-server/middleware.js +1 -1
  93. package/esm/src/server/handlers/dev/files/dev-file.handler.d.ts.map +1 -1
  94. package/esm/src/server/handlers/dev/files/dev-file.handler.js +4 -14
  95. package/esm/src/server/services/rendering/ssr.service.d.ts.map +1 -1
  96. package/esm/src/server/services/rendering/ssr.service.js +4 -1
  97. package/esm/src/server/services/rsc/endpoints/rsc-bundles.generated.js +1 -1
  98. package/esm/src/utils/version-constant.d.ts +1 -1
  99. package/esm/src/utils/version-constant.js +1 -1
  100. package/esm/src/workflow/claude-code/workspace-sync.d.ts +17 -2
  101. package/esm/src/workflow/claude-code/workspace-sync.d.ts.map +1 -1
  102. package/esm/src/workflow/claude-code/workspace-sync.js +106 -19
  103. package/esm/src/workflow/schemas/workflow.schema.d.ts +3 -3
  104. package/package.json +1 -9
  105. package/src/cli/shared/server-startup.ts +8 -0
  106. package/src/deno.js +5 -12
  107. package/src/src/agent/durable.ts +237 -0
  108. package/src/src/agent/index.ts +4 -0
  109. package/src/src/cache/backends/factory.ts +1 -1
  110. package/src/src/cache/backends/redis.ts +1 -1
  111. package/src/src/cache/keys/utils.ts +1 -1
  112. package/src/src/cache/registry.ts +1 -1
  113. package/src/src/data/static-paths-fetcher.ts +1 -1
  114. package/src/src/embedding/upload-loader.ts +14 -63
  115. package/src/src/errors/middleware/cli-error-boundary.ts +1 -1
  116. package/src/src/errors/middleware/http-error-boundary.ts +1 -1
  117. package/src/src/errors/tracing.ts +4 -4
  118. package/src/src/extensions/interfaces/index.ts +7 -2
  119. package/src/src/extensions/interfaces/node-compat.ts +74 -10
  120. package/src/src/extensions/interfaces/tracing-exporter.ts +36 -1
  121. package/src/src/mcp/index.ts +7 -2
  122. package/src/src/mcp/schemas/index.ts +1 -0
  123. package/src/src/mcp/schemas/mcp.schema.ts +20 -7
  124. package/src/src/mcp/server.ts +60 -6
  125. package/src/src/observability/auto-instrument/http-instrumentation.ts +1 -1
  126. package/src/src/observability/auto-instrument/react-instrumentation.ts +1 -1
  127. package/src/src/observability/auto-instrument/wrappers.ts +1 -1
  128. package/src/src/observability/instruments/build-instruments.ts +1 -1
  129. package/src/src/observability/instruments/cache-instruments.ts +6 -1
  130. package/src/src/observability/instruments/data-instruments.ts +1 -1
  131. package/src/src/observability/instruments/error-instruments.ts +1 -1
  132. package/src/src/observability/instruments/http-instruments.ts +6 -1
  133. package/src/src/observability/instruments/instruments-factory.ts +1 -1
  134. package/src/src/observability/instruments/memory-instruments.ts +5 -1
  135. package/src/src/observability/instruments/render-instruments.ts +1 -1
  136. package/src/src/observability/instruments/rsc-instruments.ts +1 -1
  137. package/src/src/observability/metrics/manager.ts +11 -3
  138. package/src/src/observability/metrics/types.ts +7 -1
  139. package/src/src/observability/simple-metrics/otel-instruments.ts +7 -2
  140. package/src/src/observability/simple-metrics/types.ts +1 -1
  141. package/src/src/observability/tracing/api-shim.ts +409 -0
  142. package/src/src/observability/tracing/manager.ts +29 -4
  143. package/src/src/observability/tracing/otlp-setup.ts +76 -168
  144. package/src/src/observability/tracing/types.ts +1 -1
  145. package/src/src/platform/compat/kv/factory.ts +18 -7
  146. package/src/src/platform/compat/opaque-deps.ts +16 -44
  147. package/src/src/proxy/tracing.ts +43 -117
  148. package/src/src/rendering/rsc/client-module-strategy.ts +9 -1
  149. package/src/src/server/bootstrap.ts +38 -1
  150. package/src/src/server/context/request-context.ts +10 -7
  151. package/src/src/server/dev-server/middleware.ts +1 -1
  152. package/src/src/server/handlers/dev/files/dev-file.handler.ts +4 -22
  153. package/src/src/server/services/rendering/ssr.service.ts +4 -1
  154. package/src/src/server/services/rsc/endpoints/rsc-bundles.generated.ts +1 -1
  155. package/src/src/utils/version-constant.ts +1 -1
  156. package/src/src/workflow/claude-code/workspace-sync.ts +109 -20
  157. package/esm/src/utils/logger/trace-bridge.d.ts +0 -11
  158. package/esm/src/utils/logger/trace-bridge.d.ts.map +0 -1
  159. package/esm/src/utils/logger/trace-bridge.js +0 -12
  160. package/src/src/utils/logger/trace-bridge.ts +0 -14
@@ -1,24 +1,34 @@
1
1
  /**************************
2
- * OpenTelemetry OTLP Setup for Grafana Cloud
2
+ * OpenTelemetry OTLP Setup
3
+ *
4
+ * Thin wrapper that delegates to the `ext-opentelemetry` extension via the
5
+ * `TracingExporter` contract. When the extension is not installed, all span
6
+ * operations silently no-op.
3
7
  *
4
- * Configures the OTLP exporter to send traces to Grafana Cloud.
5
8
  * Reads configuration from environment variables:
6
9
  * - OTEL_TRACES_ENABLED: "true" to enable tracing
7
10
  * - OTEL_SERVICE_NAME: Service name for traces
8
- * - OTEL_EXPORTER_OTLP_ENDPOINT: OTLP endpoint (e.g., https://otlp-gateway-prod-eu-west-2.grafana.net/otlp)
9
- * - OTEL_EXPORTER_OTLP_HEADERS: Auth headers (e.g., Authorization=Basic ...)
11
+ * - OTEL_EXPORTER_OTLP_ENDPOINT: OTLP endpoint
12
+ * - OTEL_EXPORTER_OTLP_HEADERS: Auth headers
10
13
  **************************/
11
14
 
12
15
  import { getOtelTracingConfig } from "../../config/env.js";
13
16
  import { serverLogger } from "../../utils/index.js";
14
- import { RUNTIME_VERSION } from "../../utils/version.js";
17
+ import {
18
+ type Context,
19
+ context as shimContext,
20
+ defaultTextMapGetter,
21
+ defaultTextMapSetter,
22
+ getTracer,
23
+ propagation as shimPropagation,
24
+ type Span,
25
+ SpanKind,
26
+ SpanStatusCode,
27
+ trace as shimTrace,
28
+ } from "./api-shim.js";
15
29
 
16
30
  const logger = serverLogger.component("otel");
17
31
 
18
- interface ShutdownableProvider {
19
- shutdown(): Promise<void>;
20
- }
21
-
22
32
  export interface OTLPConfig {
23
33
  serviceName: string;
24
34
  endpoint: string;
@@ -26,12 +36,6 @@ export interface OTLPConfig {
26
36
  enabled: boolean;
27
37
  }
28
38
 
29
- let initialized = false;
30
- let tracerProvider: ShutdownableProvider | null = null;
31
-
32
- let traceApi: typeof import("@opentelemetry/api") | null = null;
33
- let propagationApi: typeof import("@opentelemetry/core") | null = null;
34
-
35
39
  function parseHeaders(headerString: string | undefined): Record<string, string> {
36
40
  if (!headerString) return {};
37
41
 
@@ -61,114 +65,46 @@ function getConfig(): OTLPConfig {
61
65
  };
62
66
  }
63
67
 
64
- async function ensureApis(): Promise<void> {
65
- if (traceApi && propagationApi) return;
66
- traceApi = await import("@opentelemetry/api");
67
- propagationApi = await import("@opentelemetry/core");
68
- }
69
-
70
- function setSpanErrorStatus(span: import("@opentelemetry/api").Span, error: unknown): void {
71
- if (!traceApi) return;
68
+ // ---------------------------------------------------------------------------
69
+ // Legacy initialise / shutdown (now delegated to bootstrap.ts + ext)
70
+ // ---------------------------------------------------------------------------
72
71
 
73
- span.setStatus({
74
- code: traceApi.SpanStatusCode.ERROR,
75
- message: error instanceof Error ? error.message : String(error),
76
- });
77
-
78
- if (error instanceof Error) span.recordException(error);
79
- }
72
+ let initialized = false;
80
73
 
81
74
  export async function initializeOTLP(): Promise<void> {
82
75
  if (initialized) {
83
76
  logger.debug("Already initialized");
84
77
  return;
85
78
  }
86
-
87
- const config = getConfig();
88
-
89
- if (!config.enabled) {
90
- logger.debug("Tracing disabled (OTEL_TRACES_ENABLED != true)");
91
- initialized = true;
92
- return;
93
- }
94
-
95
- if (!config.endpoint) {
96
- logger.warn("No OTEL_EXPORTER_OTLP_ENDPOINT configured, skipping");
97
- initialized = true;
98
- return;
99
- }
100
-
101
- try {
102
- const { BasicTracerProvider, BatchSpanProcessor } = await import(
103
- "@opentelemetry/sdk-trace-base"
104
- );
105
- const { OTLPTraceExporter } = await import("@opentelemetry/exporter-trace-otlp-http");
106
- const { resourceFromAttributes } = await import("@opentelemetry/resources");
107
- const { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } = await import(
108
- "@opentelemetry/semantic-conventions"
109
- );
110
- const { AsyncLocalStorageContextManager } = await import("@opentelemetry/context-async-hooks");
111
-
112
- const resource = resourceFromAttributes({
113
- [ATTR_SERVICE_NAME]: config.serviceName,
114
- [ATTR_SERVICE_VERSION]: RUNTIME_VERSION,
115
- });
116
-
117
- const endpointBase = config.endpoint.replace(/\/$/, "");
118
- const exporter = new OTLPTraceExporter({
119
- url: `${endpointBase}/v1/traces`,
120
- headers: config.headers,
121
- });
122
-
123
- const contextManager = new AsyncLocalStorageContextManager();
124
- contextManager.enable();
125
-
126
- const provider = new BasicTracerProvider({
127
- resource,
128
- spanProcessors: [new BatchSpanProcessor(exporter)],
129
- });
130
-
131
- // In OTel SDK v2, provider.register() is removed.
132
- // Set global tracer provider and context manager via the API directly.
133
- traceApi = await import("@opentelemetry/api");
134
- traceApi.trace.setGlobalTracerProvider(provider);
135
- traceApi.context.setGlobalContextManager(contextManager);
136
-
137
- tracerProvider = provider;
138
-
139
- initialized = true;
140
- logger.info("OpenTelemetry OTLP tracing initialized", {
141
- serviceName: config.serviceName,
142
- endpoint: config.endpoint,
143
- });
144
-
145
- traceApi.trace.getTracer(config.serviceName);
146
- logger.debug("Tracer obtained", { name: config.serviceName });
147
-
148
- // Bridge trace context into the logger so every JSON log entry
149
- // automatically includes traceId/spanId from the active span.
150
- // Imported here (rather than per-entrypoint) so all callers of
151
- // initializeOTLP benefit — CLI serve, production-server, proxy, etc.
152
- await import("../../utils/logger/trace-bridge.js");
153
- } catch (error) {
154
- logger.error("Failed to initialize OTLP tracing", { error });
155
- initialized = true; // Mark as initialized to prevent retries
156
- }
79
+ // Actual provider setup is handled by ext-opentelemetry via bootstrap.
80
+ // This is kept for backward compatibility.
81
+ initialized = true;
82
+ logger.debug("OTLP setup delegated to ext-opentelemetry extension");
157
83
  }
158
84
 
159
85
  export async function shutdownOTLP(): Promise<void> {
160
- if (!tracerProvider) return;
161
-
162
- try {
163
- await tracerProvider.shutdown();
164
- logger.info("Tracer provider shutdown complete");
165
- } catch (error) {
166
- logger.warn("Error during tracer shutdown", { error });
167
- }
86
+ // Actual shutdown is handled by the extension loader teardown.
87
+ logger.debug("OTLP shutdown delegated to ext-opentelemetry extension");
168
88
  }
169
89
 
170
90
  export function isOTLPEnabled(): boolean {
171
- return initialized && tracerProvider !== null;
91
+ return initialized;
92
+ }
93
+
94
+ export async function initializeOTLPWithApis(): Promise<void> {
95
+ await initializeOTLP();
96
+ }
97
+
98
+ // ---------------------------------------------------------------------------
99
+ // Span helpers — delegate to shim (which delegates to SDK if wired)
100
+ // ---------------------------------------------------------------------------
101
+
102
+ function setSpanErrorStatus(span: Span, error: unknown): void {
103
+ span.setStatus({
104
+ code: SpanStatusCode.ERROR,
105
+ message: error instanceof Error ? error.message : String(error),
106
+ });
107
+ if (error instanceof Error) span.recordException(error);
172
108
  }
173
109
 
174
110
  export async function withSpan<T>(
@@ -176,22 +112,21 @@ export async function withSpan<T>(
176
112
  fn: () => Promise<T>,
177
113
  attributes?: Record<string, string | number | boolean>,
178
114
  ): Promise<T> {
179
- if (!traceApi || !isOTLPEnabled()) return fn();
180
-
181
- const tracer = traceApi.trace.getTracer(getConfig().serviceName);
182
- const parentContext = traceApi.context.active();
115
+ const config = getConfig();
116
+ const tracer = getTracer(config.serviceName);
117
+ const parentContext = shimContext.active();
183
118
 
184
119
  const span = tracer.startSpan(
185
120
  name,
186
- { kind: traceApi.SpanKind.INTERNAL, attributes },
121
+ { kind: SpanKind.INTERNAL, attributes },
187
122
  parentContext,
188
123
  );
189
124
 
190
- const spanContext = traceApi.trace.setSpan(parentContext, span);
125
+ const spanContext = shimTrace.setSpan(parentContext, span);
191
126
 
192
127
  try {
193
- const result = await traceApi.context.with(spanContext, fn);
194
- span.setStatus({ code: traceApi.SpanStatusCode.OK });
128
+ const result = await shimContext.with(spanContext, fn);
129
+ span.setStatus({ code: SpanStatusCode.OK });
195
130
  return result;
196
131
  } catch (error) {
197
132
  setSpanErrorStatus(span, error);
@@ -206,20 +141,19 @@ export function withSpanSync<T>(
206
141
  fn: () => T,
207
142
  attributes?: Record<string, string | number | boolean>,
208
143
  ): T {
209
- if (!traceApi || !isOTLPEnabled()) return fn();
210
-
211
- const tracer = traceApi.trace.getTracer(getConfig().serviceName);
212
- const parentContext = traceApi.context.active();
144
+ const config = getConfig();
145
+ const tracer = getTracer(config.serviceName);
146
+ const parentContext = shimContext.active();
213
147
 
214
148
  const span = tracer.startSpan(
215
149
  name,
216
- { kind: traceApi.SpanKind.INTERNAL, attributes },
150
+ { kind: SpanKind.INTERNAL, attributes },
217
151
  parentContext,
218
152
  );
219
153
 
220
154
  try {
221
155
  const result = fn();
222
- span.setStatus({ code: traceApi.SpanStatusCode.OK });
156
+ span.setStatus({ code: SpanStatusCode.OK });
223
157
  return result;
224
158
  } catch (error) {
225
159
  setSpanErrorStatus(span, error);
@@ -229,31 +163,16 @@ export function withSpanSync<T>(
229
163
  }
230
164
  }
231
165
 
232
- export function extractContext(headers: Headers): unknown {
233
- if (!traceApi || !propagationApi) return traceApi?.context?.active();
234
-
166
+ export function extractContext(headers: Headers): Context | undefined {
235
167
  const carrier: Record<string, string> = {};
236
168
  for (const [k, v] of headers) carrier[k.toLowerCase()] = v;
237
169
 
238
- if (!propagationApi.W3CTraceContextPropagator) return traceApi.context.active();
239
-
240
- return new propagationApi.W3CTraceContextPropagator().extract(
241
- traceApi.context.active(),
242
- carrier,
243
- traceApi.defaultTextMapGetter,
244
- );
170
+ return shimPropagation.extract(shimContext.active(), carrier, defaultTextMapGetter);
245
171
  }
246
172
 
247
173
  export function injectContext(headers: Headers): void {
248
- if (!traceApi || !propagationApi) return;
249
-
250
174
  const carrier: Record<string, string> = {};
251
- new propagationApi.W3CTraceContextPropagator().inject(
252
- traceApi.context.active(),
253
- carrier,
254
- traceApi.defaultTextMapSetter,
255
- );
256
-
175
+ shimPropagation.inject(shimContext.active(), carrier, defaultTextMapSetter);
257
176
  for (const [k, v] of Object.entries(carrier)) headers.set(k, v);
258
177
  }
259
178
 
@@ -261,23 +180,22 @@ export function startServerSpan(
261
180
  method: string,
262
181
  path: string,
263
182
  parentContext?: unknown,
264
- ): { span: unknown; context: unknown } | null {
265
- if (!traceApi || !isOTLPEnabled()) return null;
266
-
267
- const tracer = traceApi.trace.getTracer(getConfig().serviceName);
268
- const ctx = (parentContext || traceApi.context.active()) as import("@opentelemetry/api").Context;
183
+ ): { span: Span; context: Context } | null {
184
+ const config = getConfig();
185
+ const tracer = getTracer(config.serviceName);
186
+ const ctx = (parentContext || shimContext.active()) as Context;
269
187
 
270
- const span = tracer.startSpan(`${method} ${path}`, { kind: traceApi.SpanKind.SERVER }, ctx);
188
+ const span = tracer.startSpan(`${method} ${path}`, { kind: SpanKind.SERVER }, ctx);
271
189
  span.setAttribute("http.method", method);
272
190
  span.setAttribute("http.target", path);
273
191
 
274
- return { span, context: traceApi.trace.setSpan(ctx, span) };
192
+ return { span, context: shimTrace.setSpan(ctx, span) };
275
193
  }
276
194
 
277
195
  export function endServerSpan(span: unknown, statusCode: number, error?: Error): void {
278
- if (!span || !traceApi) return;
196
+ if (!span) return;
279
197
 
280
- const otelSpan = span as import("@opentelemetry/api").Span;
198
+ const otelSpan = span as Span;
281
199
  otelSpan.setAttribute("http.status_code", statusCode);
282
200
 
283
201
  if (error) {
@@ -287,12 +205,12 @@ export function endServerSpan(span: unknown, statusCode: number, error?: Error):
287
205
  }
288
206
 
289
207
  if (statusCode >= 400) {
290
- otelSpan.setStatus({ code: traceApi.SpanStatusCode.ERROR });
208
+ otelSpan.setStatus({ code: SpanStatusCode.ERROR });
291
209
  otelSpan.end();
292
210
  return;
293
211
  }
294
212
 
295
- otelSpan.setStatus({ code: traceApi.SpanStatusCode.OK });
213
+ otelSpan.setStatus({ code: SpanStatusCode.OK });
296
214
  otelSpan.end();
297
215
  }
298
216
 
@@ -300,39 +218,29 @@ export function setSpanAttributes(
300
218
  span: unknown,
301
219
  attributes: Record<string, string | number | boolean>,
302
220
  ): void {
303
- if (!span || !traceApi) return;
221
+ if (!span) return;
304
222
 
305
- const otelSpan = span as import("@opentelemetry/api").Span;
223
+ const otelSpan = span as Span;
306
224
  for (const [key, value] of Object.entries(attributes)) otelSpan.setAttribute(key, value);
307
225
  }
308
226
 
309
227
  export function setActiveSpanAttributes(
310
228
  attributes: Record<string, string | number | boolean>,
311
229
  ): void {
312
- if (!traceApi) return;
313
-
314
- const span = traceApi.trace.getSpan(traceApi.context.active());
230
+ const span = shimTrace.getActiveSpan?.();
315
231
  if (!span) return;
316
232
 
317
233
  for (const [key, value] of Object.entries(attributes)) span.setAttribute(key, value);
318
234
  }
319
235
 
320
236
  export async function withContext<T>(spanContext: unknown, fn: () => Promise<T>): Promise<T> {
321
- if (!traceApi) return fn();
322
- return traceApi.context.with(spanContext as import("@opentelemetry/api").Context, fn);
237
+ return shimContext.with(spanContext as Context, fn);
323
238
  }
324
239
 
325
240
  export function getTraceContext(): { traceId?: string; spanId?: string } {
326
- if (!traceApi) return {};
327
-
328
- const span = traceApi.trace.getSpan(traceApi.context.active());
241
+ const span = shimTrace.getActiveSpan?.();
329
242
  if (!span) return {};
330
243
 
331
244
  const ctx = span.spanContext();
332
245
  return { traceId: ctx.traceId, spanId: ctx.spanId };
333
246
  }
334
-
335
- export async function initializeOTLPWithApis(): Promise<void> {
336
- await initializeOTLP();
337
- if (isOTLPEnabled()) await ensureApis();
338
- }
@@ -1,4 +1,4 @@
1
- import type { Context, Span, SpanKind, TextMapPropagator, Tracer } from "@opentelemetry/api";
1
+ import type { Context, Span, SpanKind, TextMapPropagator, Tracer } from "./api-shim.js";
2
2
 
3
3
  export interface TracingConfig {
4
4
  enabled: boolean;
@@ -1,9 +1,11 @@
1
1
  import * as dntShim from "../../../../_dnt.shims.js";
2
+ import { tryResolve } from "../../../extensions/contracts.js";
2
3
  import { serverLogger } from "../../../utils/index.js";
3
4
  import { isDeno } from "../runtime.js";
4
5
  import { MemoryKv } from "./memory-adapter.js";
5
6
  import { SqliteKv } from "./sqlite-adapter.js";
6
- import type { Kv } from "./types.js";
7
+ import type { Kv, SqliteDatabase } from "./types.js";
8
+ import type { NodeCompat } from "../../../extensions/interfaces/node-compat.js";
7
9
 
8
10
  interface GlobalWithDenoKv {
9
11
  Deno?: {
@@ -25,12 +27,21 @@ export async function openKv(path?: string): Promise<Kv> {
25
27
  }
26
28
  }
27
29
 
28
- try {
29
- const Database = (await import("better-sqlite3")).default;
30
- const db = new Database(path ?? ":memory:");
31
- return new SqliteKv(db);
32
- } catch (error) {
33
- serverLogger.debug("SQLite not available, using memory KV:", error);
30
+ const nodeCompat = tryResolve<NodeCompat>("NodeCompat");
31
+ if (nodeCompat?.openSqliteDatabase) {
32
+ try {
33
+ const db = await nodeCompat.openSqliteDatabase(path);
34
+ // NodeCompatSqliteDatabase is structurally identical to SqliteDatabase;
35
+ // cast to satisfy the SqliteKv constructor's nominal type check.
36
+ return new SqliteKv(db as unknown as SqliteDatabase);
37
+ } catch (error) {
38
+ serverLogger.debug("NodeCompat.openSqliteDatabase failed, using memory KV:", error);
39
+ }
40
+ } else {
41
+ serverLogger.debug(
42
+ "NodeCompat extension not registered — SQLite KV unavailable. " +
43
+ "Install @veryfront/ext-node-compat to enable SQLite-backed KV.",
44
+ );
34
45
  }
35
46
 
36
47
  return new MemoryKv();
@@ -17,8 +17,10 @@
17
17
  import * as dntShim from "../../../_dnt.shims.js";
18
18
 
19
19
 
20
- import { isDeno, isDenoCompiled } from "./runtime.js";
20
+ import { tryResolve } from "../../extensions/contracts.js";
21
+ import { isDeno } from "./runtime.js";
21
22
  import { dynamicImport } from "./dynamic-import.js";
23
+ import type { NodeCompat } from "../../extensions/interfaces/node-compat.js";
22
24
 
23
25
  function resolve(pkg: string, version: string): string {
24
26
  return isDeno ? `npm:${pkg}@${version}` : pkg;
@@ -27,14 +29,6 @@ function resolve(pkg: string, version: string): string {
27
29
  // deno-lint-ignore no-explicit-any -- callers assign to their own typed variable; any allows implicit narrowing at each call site
28
30
  type OpaqueModule = any;
29
31
 
30
- type KreuzbergModule = {
31
- initWasm?: () => Promise<void>;
32
- extractBytes: (
33
- data: Uint8Array,
34
- mimeType: string,
35
- ) => Promise<{ content: string }>;
36
- };
37
-
38
32
  /** Lazily import `@huggingface/transformers` (+ onnxruntime, ~500MB). */
39
33
  export function importTransformers(): Promise<OpaqueModule> {
40
34
  return dynamicImport(resolve("@huggingface/transformers", "3.4.2"));
@@ -51,11 +45,12 @@ export function importClaudeAgentSDK(): Promise<OpaqueModule> {
51
45
  /**
52
46
  * Lazily import kreuzberg document extraction.
53
47
  *
54
- * Unlike the other opaque deps above, kreuzberg is a core framework
55
- * dependency that must work in compiled binaries. The Deno path uses
56
- * a regular `import()` (not `dynamicImport`) so `deno compile` can
57
- * trace and embed `@kreuzberg/wasm`. The Node/Bun path uses `dynamicImport`
58
- * to resolve `@kreuzberg/node` from the project's node_modules at runtime.
48
+ * Delegates to the `NodeCompat` extension contract (`@veryfront/ext-node-compat`)
49
+ * when available. Without the extension, throws an actionable error instructing
50
+ * the user to install `ext-node-compat`.
51
+ *
52
+ * Node/Bun path: `@kreuzberg/node` resolved from the project's node_modules at
53
+ * runtime — the extension handles that dynamic import internally.
59
54
  */
60
55
  export async function importKreuzberg(): Promise<{
61
56
  extractBytes: (
@@ -63,35 +58,12 @@ export async function importKreuzberg(): Promise<{
63
58
  mimeType: string,
64
59
  ) => Promise<{ content: string }>;
65
60
  }> {
66
- if (isDeno) {
67
- // Regular import — visible to deno compile, resolved via deno.json import map
68
- const mod = await import("@kreuzberg/wasm") as unknown as KreuzbergModule;
69
- if (isDenoCompiled) {
70
- // Kreuzberg's initWasm() internally uses a computed dynamic import() to
71
- // load the WASM glue module (kreuzberg_wasm.js). deno compile cannot
72
- // trace computed import() paths, so the glue module is absent from the
73
- // binary's embedded module graph. Pre-importing it here populates Deno's
74
- // in-process module cache so the subsequent import() inside initWasm()
75
- // resolves from cache instead of hitting the missing file.
76
- await import("@kreuzberg/wasm/dist/pkg/kreuzberg_wasm.js");
77
- // pdfium.js is not in @kreuzberg/wasm package exports, so we can't use
78
- // an import map entry. Resolve its URL relative to the kreuzberg package
79
- // and pre-import it so initWasm()'s `import("./pdfium.js")` resolves
80
- // from the in-process module cache instead of hanging.
81
- // Wrapped in try/catch because pdfium is only needed for PDF extraction;
82
- // a failure here should not break extraction of other formats (DOCX, etc.).
83
- try {
84
- const kreuzbergUrl = import.meta.resolve("@kreuzberg/wasm");
85
- await import(new URL("./pdfium.js", kreuzbergUrl).href);
86
- } catch {
87
- // expected: pdfium pre-import may fail if the file is missing or
88
- // the package structure changed — PDF extraction will be degraded
89
- // but other formats will still work.
90
- }
91
- }
92
- await mod.initWasm?.();
93
- return mod;
61
+ const nodeCompat = tryResolve<NodeCompat>("NodeCompat");
62
+ if (nodeCompat?.importKreuzberg) {
63
+ return nodeCompat.importKreuzberg();
94
64
  }
95
- // Opaque import — resolved from node_modules at runtime
96
- return dynamicImport("@kreuzberg/node");
65
+ throw new Error(
66
+ "Document extraction requires the NodeCompat extension. " +
67
+ "Install @veryfront/ext-node-compat and add it to your extensions configuration.",
68
+ );
97
69
  }