@use-tusk/drift-node-sdk 0.1.29 → 0.1.31

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/dist/index.cjs CHANGED
@@ -6214,7 +6214,7 @@ var JsonSchema$Type = class extends import_commonjs$7.MessageType {
6214
6214
  const JsonSchema = new JsonSchema$Type();
6215
6215
 
6216
6216
  //#endregion
6217
- //#region node_modules/@use-tusk/drift-schemas/dist/span-CXrr1reB.js
6217
+ //#region node_modules/@use-tusk/drift-schemas/dist/span-Cklxe7uf.js
6218
6218
  var import_commonjs$6 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
6219
6219
  /**
6220
6220
  * Package type classification enum
@@ -6572,6 +6572,13 @@ var Span$Type = class extends import_commonjs$6.MessageType {
6572
6572
  kind: "scalar",
6573
6573
  opt: true,
6574
6574
  T: 9
6575
+ },
6576
+ {
6577
+ no: 25,
6578
+ name: "id",
6579
+ kind: "scalar",
6580
+ opt: true,
6581
+ T: 9
6575
6582
  }
6576
6583
  ]);
6577
6584
  }
@@ -6672,6 +6679,9 @@ var Span$Type = class extends import_commonjs$6.MessageType {
6672
6679
  case 24:
6673
6680
  message.environment = reader.string();
6674
6681
  break;
6682
+ case 25:
6683
+ message.id = reader.string();
6684
+ break;
6675
6685
  default:
6676
6686
  let u = options.readUnknownField;
6677
6687
  if (u === "throw") throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
@@ -6706,6 +6716,7 @@ var Span$Type = class extends import_commonjs$6.MessageType {
6706
6716
  if (message.isRootSpan !== false) writer.tag(22, import_commonjs$6.WireType.Varint).bool(message.isRootSpan);
6707
6717
  if (message.metadata) Struct.internalBinaryWrite(message.metadata, writer.tag(23, import_commonjs$6.WireType.LengthDelimited).fork(), options).join();
6708
6718
  if (message.environment !== void 0) writer.tag(24, import_commonjs$6.WireType.LengthDelimited).string(message.environment);
6719
+ if (message.id !== void 0) writer.tag(25, import_commonjs$6.WireType.LengthDelimited).string(message.id);
6709
6720
  let u = options.writeUnknownFields;
6710
6721
  if (u !== false) (u == true ? import_commonjs$6.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
6711
6722
  return writer;
@@ -7808,7 +7819,7 @@ var SpanUtils = class SpanUtils {
7808
7819
  }
7809
7820
  }
7810
7821
  const span = tracer.startSpan(options.name, {
7811
- kind: options.kind || import_src$35.SpanKind.CLIENT,
7822
+ kind: options.kind ?? import_src$35.SpanKind.CLIENT,
7812
7823
  attributes: options.attributes || {}
7813
7824
  }, parentContext);
7814
7825
  const spanContext = span.spanContext();
@@ -10236,7 +10247,7 @@ var require_commonjs$1 = /* @__PURE__ */ __commonJS({ "node_modules/@protobuf-ts
10236
10247
  }) });
10237
10248
 
10238
10249
  //#endregion
10239
- //#region node_modules/@use-tusk/drift-schemas/dist/span_export_service-RmRqNxn1.js
10250
+ //#region node_modules/@use-tusk/drift-schemas/dist/span_export_service-BjPTFjCJ.js
10240
10251
  var import_commonjs$4 = /* @__PURE__ */ __toESM(require_commonjs$1(), 1);
10241
10252
  var import_commonjs$5 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
10242
10253
  var ExportSpansRequest$Type = class extends import_commonjs$5.MessageType {
@@ -15775,7 +15786,7 @@ var TdMysql2ConnectionMock = class extends events.EventEmitter {
15775
15786
  }
15776
15787
  query(...args) {
15777
15788
  logger.debug(`[TdMysql2ConnectionMock] Mock connection query intercepted in REPLAY mode`);
15778
- const stackTrace = captureStackTrace(["TdMysql2ConnectionMock"]);
15789
+ const stackTrace = captureStackTrace(["TdMysql2ConnectionMock", "Mysql2Instrumentation"]);
15779
15790
  const queryConfig = this.mysql2Instrumentation.parseQueryArgs(args);
15780
15791
  if (!queryConfig || !queryConfig.sql) {
15781
15792
  logger.debug(`[TdMysql2ConnectionMock] Could not parse mock connection query, returning empty result`);
@@ -15790,16 +15801,16 @@ var TdMysql2ConnectionMock = class extends events.EventEmitter {
15790
15801
  return Promise.resolve([emptyResult.rows, emptyResult.fields]);
15791
15802
  }
15792
15803
  const inputValue = createMockInputValue({
15793
- sql: queryConfig.sql,
15804
+ sql: this.mysql2Instrumentation.normalizeSqlForMockMatching(queryConfig.sql),
15794
15805
  values: queryConfig.values || [],
15795
15806
  clientType: this.clientType
15796
15807
  });
15797
- if (this.spanInfo) return this.mysql2Instrumentation.handleReplayQuery(queryConfig, inputValue, this.spanInfo, stackTrace);
15808
+ if (this.spanInfo) return this.mysql2Instrumentation.handleReplayQuery(queryConfig, inputValue, this.spanInfo, "query", stackTrace);
15798
15809
  else return this.mysql2Instrumentation.handleNoOpReplayQuery(queryConfig);
15799
15810
  }
15800
15811
  execute(...args) {
15801
15812
  logger.debug(`[TdMysql2ConnectionMock] Mock connection execute intercepted in REPLAY mode`);
15802
- const stackTrace = captureStackTrace(["TdMysql2ConnectionMock"]);
15813
+ const stackTrace = captureStackTrace(["TdMysql2ConnectionMock", "Mysql2Instrumentation"]);
15803
15814
  const queryConfig = this.mysql2Instrumentation.parseQueryArgs(args);
15804
15815
  if (!queryConfig || !queryConfig.sql) {
15805
15816
  logger.debug(`[TdMysql2ConnectionMock] Could not parse mock connection execute, returning empty result`);
@@ -15814,11 +15825,11 @@ var TdMysql2ConnectionMock = class extends events.EventEmitter {
15814
15825
  return Promise.resolve([emptyResult.rows, emptyResult.fields]);
15815
15826
  }
15816
15827
  const inputValue = createMockInputValue({
15817
- sql: queryConfig.sql,
15828
+ sql: this.mysql2Instrumentation.normalizeSqlForMockMatching(queryConfig.sql),
15818
15829
  values: queryConfig.values || [],
15819
15830
  clientType: this.clientType
15820
15831
  });
15821
- if (this.spanInfo) return this.mysql2Instrumentation.handleReplayQuery(queryConfig, inputValue, this.spanInfo, stackTrace);
15832
+ if (this.spanInfo) return this.mysql2Instrumentation.handleReplayQuery(queryConfig, inputValue, this.spanInfo, "execute", stackTrace);
15822
15833
  else return this.mysql2Instrumentation.handleNoOpReplayQuery(queryConfig);
15823
15834
  }
15824
15835
  release() {
@@ -16153,6 +16164,8 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16153
16164
  constructor(config = {}) {
16154
16165
  super("mysql2", config);
16155
16166
  this.INSTRUMENTATION_NAME = "Mysql2Instrumentation";
16167
+ this.CONTEXT_BOUND_CONNECTION = Symbol("mysql2-context-bound-connection");
16168
+ this.CONTEXT_BOUND_PARENT_CONTEXT = Symbol("mysql2-bound-parent-context");
16156
16169
  this.mode = config.mode || TuskDriftMode.DISABLED;
16157
16170
  this.queryMock = new TdMysql2QueryMock();
16158
16171
  }
@@ -16382,7 +16395,7 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16382
16395
  return originalQuery.apply(this, args);
16383
16396
  }
16384
16397
  const inputValue = {
16385
- sql: queryConfig.sql,
16398
+ sql: self.normalizeSqlForMockMatching(queryConfig.sql),
16386
16399
  values: queryConfig.values || [],
16387
16400
  clientType
16388
16401
  };
@@ -16449,7 +16462,7 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
16449
16462
  return originalExecute.apply(this, args);
16450
16463
  }
16451
16464
  const inputValue = {
16452
- sql: queryConfig.sql,
16465
+ sql: self.normalizeSqlForMockMatching(queryConfig.sql),
16453
16466
  values: queryConfig.values || [],
16454
16467
  clientType
16455
16468
  };
@@ -17045,6 +17058,14 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
17045
17058
  }
17046
17059
  return null;
17047
17060
  }
17061
+ normalizeSqlForMockMatching(sql) {
17062
+ if (!sql) return sql;
17063
+ const trimmed = sql.trim();
17064
+ if (/^savepoint\s+trx\d+\s*;?$/i.test(trimmed)) return trimmed.replace(/^(savepoint\s+)trx\d+(\s*;?)$/i, "$1trx$2");
17065
+ if (/^release\s+savepoint\s+trx\d+\s*;?$/i.test(trimmed)) return trimmed.replace(/^(release\s+savepoint\s+)trx\d+(\s*;?)$/i, "$1trx$2");
17066
+ if (/^rollback\s+to\s+savepoint\s+trx\d+\s*;?$/i.test(trimmed)) return trimmed.replace(/^(rollback\s+to\s+savepoint\s+)trx\d+(\s*;?)$/i, "$1trx$2");
17067
+ return sql;
17068
+ }
17048
17069
  _handleRecordQueryInSpan(spanInfo, originalQuery, queryConfig, args, context$6) {
17049
17070
  const hasCallback = !!queryConfig.callback;
17050
17071
  const invokeOriginal = (invokeArgs) => {
@@ -17128,8 +17149,10 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
17128
17149
  return this.queryMock.handleNoOpReplayQuery(queryConfig);
17129
17150
  }
17130
17151
  _handleRecordPoolGetConnectionInSpan(spanInfo, originalGetConnection, callback, context$6) {
17152
+ const parentContext = import_src$22.context.active();
17131
17153
  if (callback) {
17132
17154
  const wrappedCallback = (error, connection) => {
17155
+ const scopedConnection = connection ? this._bindConnectionMethodsToContext(connection, parentContext) : connection;
17133
17156
  if (error) {
17134
17157
  logger.debug(`[Mysql2Instrumentation] MySQL2 Pool getConnection error: ${error.message} (${SpanUtils.getTraceInfo()})`);
17135
17158
  try {
@@ -17145,44 +17168,71 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
17145
17168
  try {
17146
17169
  SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
17147
17170
  connected: true,
17148
- hasConnection: !!connection
17171
+ hasConnection: !!scopedConnection
17149
17172
  } });
17150
17173
  SpanUtils.endSpan(spanInfo.span, { code: import_src$22.SpanStatusCode.OK });
17151
17174
  } catch (error$1) {
17152
17175
  logger.error(`[Mysql2Instrumentation] error processing getConnection response:`, error$1);
17153
17176
  }
17154
17177
  }
17155
- return callback(error, connection);
17178
+ return import_src$22.context.with(parentContext, () => callback(error, scopedConnection));
17156
17179
  };
17157
- return originalGetConnection.call(context$6, wrappedCallback);
17158
- } else return originalGetConnection.call(context$6).then((connection) => {
17159
- logger.debug(`[Mysql2Instrumentation] MySQL2 Pool getConnection completed successfully (${SpanUtils.getTraceInfo()})`);
17160
- try {
17161
- SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
17162
- connected: true,
17163
- hasConnection: !!connection
17164
- } });
17165
- SpanUtils.endSpan(spanInfo.span, { code: import_src$22.SpanStatusCode.OK });
17166
- } catch (error) {
17167
- logger.error(`[Mysql2Instrumentation] error processing getConnection response:`, error);
17168
- }
17169
- return connection;
17180
+ return import_src$22.context.with(parentContext, () => originalGetConnection.call(context$6, wrappedCallback));
17181
+ } else return import_src$22.context.with(parentContext, () => originalGetConnection.call(context$6)).then((connection) => {
17182
+ const scopedConnection = this._bindConnectionMethodsToContext(connection, parentContext);
17183
+ return import_src$22.context.with(parentContext, () => {
17184
+ logger.debug(`[Mysql2Instrumentation] MySQL2 Pool getConnection completed successfully (${SpanUtils.getTraceInfo()})`);
17185
+ try {
17186
+ SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: {
17187
+ connected: true,
17188
+ hasConnection: !!scopedConnection
17189
+ } });
17190
+ SpanUtils.endSpan(spanInfo.span, { code: import_src$22.SpanStatusCode.OK });
17191
+ } catch (error) {
17192
+ logger.error(`[Mysql2Instrumentation] error processing getConnection response:`, error);
17193
+ }
17194
+ return scopedConnection;
17195
+ });
17170
17196
  }).catch((error) => {
17171
- logger.debug(`[Mysql2Instrumentation] MySQL2 Pool getConnection error: ${error.message} (${SpanUtils.getTraceInfo()})`);
17172
- try {
17173
- SpanUtils.endSpan(spanInfo.span, {
17174
- code: import_src$22.SpanStatusCode.ERROR,
17175
- message: error.message
17176
- });
17177
- } catch (error$1) {
17178
- logger.error(`[Mysql2Instrumentation] error ending span:`, error$1);
17179
- }
17180
- throw error;
17197
+ return import_src$22.context.with(parentContext, () => {
17198
+ logger.debug(`[Mysql2Instrumentation] MySQL2 Pool getConnection error: ${error.message} (${SpanUtils.getTraceInfo()})`);
17199
+ try {
17200
+ SpanUtils.endSpan(spanInfo.span, {
17201
+ code: import_src$22.SpanStatusCode.ERROR,
17202
+ message: error.message
17203
+ });
17204
+ } catch (error$1) {
17205
+ logger.error(`[Mysql2Instrumentation] error ending span:`, error$1);
17206
+ }
17207
+ throw error;
17208
+ });
17181
17209
  });
17182
17210
  }
17211
+ _bindConnectionMethodsToContext(connection, parentContext) {
17212
+ const conn = connection;
17213
+ if (!conn) return connection;
17214
+ conn[this.CONTEXT_BOUND_PARENT_CONTEXT] = parentContext;
17215
+ if (conn[this.CONTEXT_BOUND_CONNECTION]) return connection;
17216
+ for (const method of [
17217
+ "query",
17218
+ "execute",
17219
+ "beginTransaction",
17220
+ "commit",
17221
+ "rollback"
17222
+ ]) {
17223
+ const original = conn[method];
17224
+ if (typeof original !== "function") continue;
17225
+ conn[method] = (...args) => {
17226
+ const boundContext = conn[this.CONTEXT_BOUND_PARENT_CONTEXT] ?? import_src$22.context.active();
17227
+ return import_src$22.context.with(boundContext, () => original.apply(conn, args));
17228
+ };
17229
+ }
17230
+ conn[this.CONTEXT_BOUND_CONNECTION] = true;
17231
+ return connection;
17232
+ }
17183
17233
  handleNoOpReplayGetConnection(callback) {
17184
17234
  logger.debug(`[Mysql2Instrumentation] Background getConnection detected, returning mock connection`);
17185
- const mockConnection = new TdMysql2ConnectionMock(this, "pool");
17235
+ const mockConnection = new TdMysql2ConnectionMock(this, "connection");
17186
17236
  if (callback) {
17187
17237
  process.nextTick(() => callback(null, mockConnection));
17188
17238
  return;
@@ -17191,7 +17241,7 @@ var Mysql2Instrumentation = class extends TdInstrumentationBase {
17191
17241
  }
17192
17242
  _handleReplayPoolGetConnection(spanInfo, callback) {
17193
17243
  logger.debug(`[Mysql2Instrumentation] Replaying MySQL2 Pool getConnection`);
17194
- const mockConnection = new TdMysql2ConnectionMock(this, "pool", spanInfo);
17244
+ const mockConnection = new TdMysql2ConnectionMock(this, "connection", spanInfo);
17195
17245
  if (callback) {
17196
17246
  process.nextTick(() => callback(null, mockConnection));
17197
17247
  return;
@@ -25905,13 +25955,188 @@ var require_src$6 = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/co
25905
25955
  }) });
25906
25956
 
25907
25957
  //#endregion
25908
- //#region src/core/tracing/SpanTransformer.ts
25958
+ //#region src/core/rustCoreBinding.ts
25909
25959
  var import_src$10 = /* @__PURE__ */ __toESM(require_src$6(), 1);
25960
+ let bindingLoadAttempted = false;
25961
+ let binding = null;
25962
+ let bindingLoadError = null;
25963
+ function getRustCoreEnvDecision() {
25964
+ const raw = process.env.TUSK_USE_RUST_CORE;
25965
+ if (!raw) return {
25966
+ enabled: true,
25967
+ reason: "default_on",
25968
+ rawEnv: null
25969
+ };
25970
+ const normalized = raw.trim().toLowerCase();
25971
+ if ([
25972
+ "1",
25973
+ "true",
25974
+ "yes",
25975
+ "on"
25976
+ ].includes(normalized)) return {
25977
+ enabled: true,
25978
+ reason: "env_enabled",
25979
+ rawEnv: raw
25980
+ };
25981
+ if ([
25982
+ "0",
25983
+ "false",
25984
+ "no",
25985
+ "off"
25986
+ ].includes(normalized)) return {
25987
+ enabled: false,
25988
+ reason: "env_disabled",
25989
+ rawEnv: raw
25990
+ };
25991
+ return {
25992
+ enabled: true,
25993
+ reason: "invalid_env_value_defaulted",
25994
+ rawEnv: raw
25995
+ };
25996
+ }
25997
+ function loadBinding() {
25998
+ if (bindingLoadAttempted) return binding;
25999
+ bindingLoadAttempted = true;
26000
+ if (!getRustCoreEnvDecision().enabled) return null;
26001
+ try {
26002
+ binding = require("@use-tusk/drift-core-node");
26003
+ bindingLoadError = null;
26004
+ } catch (error) {
26005
+ binding = null;
26006
+ bindingLoadError = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
26007
+ }
26008
+ return binding;
26009
+ }
26010
+ function getRustCoreStartupStatus() {
26011
+ const decision = getRustCoreEnvDecision();
26012
+ const loaded = decision.enabled ? loadBinding() : null;
26013
+ return {
26014
+ enabled: decision.enabled,
26015
+ reason: decision.reason,
26016
+ rawEnv: decision.rawEnv,
26017
+ bindingLoaded: loaded !== null,
26018
+ bindingError: bindingLoadError
26019
+ };
26020
+ }
26021
+ function toRustSchemaMerges(schemaMerges) {
26022
+ if (!schemaMerges) return;
26023
+ const out = {};
26024
+ for (const [key, value] of Object.entries(schemaMerges)) out[key] = {
26025
+ ...value.encoding !== void 0 ? { encoding: value.encoding } : {},
26026
+ ...value.decodedType !== void 0 ? { decoded_type: value.decodedType } : {},
26027
+ ...value.matchImportance !== void 0 ? { match_importance: value.matchImportance } : {}
26028
+ };
26029
+ return out;
26030
+ }
26031
+ function normalizeSchemaKeys(value) {
26032
+ if (Array.isArray(value)) return value.map(normalizeSchemaKeys);
26033
+ if (!value || typeof value !== "object") return value;
26034
+ const out = {};
26035
+ for (const [k, v] of Object.entries(value)) if (k === "decoded_type") out.decodedType = normalizeSchemaKeys(v);
26036
+ else if (k === "match_importance") out.matchImportance = normalizeSchemaKeys(v);
26037
+ else out[k] = normalizeSchemaKeys(v);
26038
+ return out;
26039
+ }
26040
+ function denormalizeSchemaKeys(value) {
26041
+ if (Array.isArray(value)) return value.map(denormalizeSchemaKeys);
26042
+ if (!value || typeof value !== "object") return value;
26043
+ const out = {};
26044
+ for (const [k, v] of Object.entries(value)) if (k === "decodedType") out.decoded_type = denormalizeSchemaKeys(v);
26045
+ else if (k === "matchImportance") out.match_importance = denormalizeSchemaKeys(v);
26046
+ else out[k] = denormalizeSchemaKeys(v);
26047
+ return out;
26048
+ }
26049
+ function processExportPayloadJsonable(payload, schemaMerges) {
26050
+ const loaded = loadBinding();
26051
+ if (!loaded) return null;
26052
+ try {
26053
+ const payloadJson = JSON.stringify(payload);
26054
+ const rustSchemaMerges = toRustSchemaMerges(schemaMerges);
26055
+ const schemaMergesJson = rustSchemaMerges ? JSON.stringify(rustSchemaMerges) : void 0;
26056
+ const result = loaded.processExportPayload(payloadJson, schemaMergesJson);
26057
+ return {
26058
+ normalizedValue: JSON.parse(result.normalizedJson),
26059
+ decodedValueHash: result.decodedValueHash,
26060
+ decodedSchema: normalizeSchemaKeys(JSON.parse(result.decodedSchemaJson)),
26061
+ decodedSchemaHash: result.decodedSchemaHash
26062
+ };
26063
+ } catch {
26064
+ return null;
26065
+ }
26066
+ }
26067
+ function buildSpanProtoBytes(input) {
26068
+ const loaded = loadBinding();
26069
+ if (!loaded) return null;
26070
+ try {
26071
+ const rustInput = {
26072
+ traceId: input.traceId,
26073
+ spanId: input.spanId,
26074
+ parentSpanId: input.parentSpanId,
26075
+ name: input.name,
26076
+ packageName: input.packageName,
26077
+ instrumentationName: input.instrumentationName,
26078
+ submoduleName: input.submoduleName,
26079
+ packageType: input.packageType,
26080
+ environment: input.environment,
26081
+ kind: input.kind,
26082
+ inputSchemaJson: JSON.stringify(denormalizeSchemaKeys(input.inputSchema)),
26083
+ outputSchemaJson: JSON.stringify(denormalizeSchemaKeys(input.outputSchema)),
26084
+ inputSchemaHash: input.inputSchemaHash,
26085
+ outputSchemaHash: input.outputSchemaHash,
26086
+ inputValueHash: input.inputValueHash,
26087
+ outputValueHash: input.outputValueHash,
26088
+ statusCode: input.statusCode,
26089
+ statusMessage: input.statusMessage,
26090
+ isPreAppStart: input.isPreAppStart,
26091
+ isRootSpan: input.isRootSpan,
26092
+ timestampSeconds: input.timestampSeconds,
26093
+ timestampNanos: input.timestampNanos,
26094
+ durationSeconds: input.durationSeconds,
26095
+ durationNanos: input.durationNanos,
26096
+ metadataJson: input.metadata === void 0 ? void 0 : JSON.stringify(input.metadata),
26097
+ inputValueJson: input.inputValue === void 0 ? void 0 : JSON.stringify(input.inputValue),
26098
+ outputValueJson: input.outputValue === void 0 ? void 0 : JSON.stringify(input.outputValue),
26099
+ inputValueProtoStructBytes: input.inputValueProtoStructBytes,
26100
+ outputValueProtoStructBytes: input.outputValueProtoStructBytes
26101
+ };
26102
+ return loaded.buildSpanProtoBytes(rustInput);
26103
+ } catch {
26104
+ return null;
26105
+ }
26106
+ }
26107
+ function buildExportSpansRequestBytes(observableServiceId, environment, sdkVersion, sdkInstanceId, spanProtoBytesList) {
26108
+ const loaded = loadBinding();
26109
+ if (!loaded) return null;
26110
+ try {
26111
+ return loaded.buildExportSpansRequestBytes(observableServiceId, environment, sdkVersion, sdkInstanceId, spanProtoBytesList);
26112
+ } catch {
26113
+ return null;
26114
+ }
26115
+ }
26116
+
26117
+ //#endregion
26118
+ //#region src/core/tracing/SpanTransformer.ts
25910
26119
  var import_src$11 = /* @__PURE__ */ __toESM(require_src$7(), 1);
25911
26120
  /**
25912
26121
  * Utility class for transforming OpenTelemetry spans to CleanSpanData
25913
26122
  */
25914
26123
  var SpanTransformer = class SpanTransformer {
26124
+ static processPayload(data, schemaMerges) {
26125
+ const rustResult = processExportPayloadJsonable(data, schemaMerges);
26126
+ if (rustResult) return {
26127
+ normalizedValue: rustResult.normalizedValue,
26128
+ schema: rustResult.decodedSchema,
26129
+ decodedValueHash: rustResult.decodedValueHash,
26130
+ decodedSchemaHash: rustResult.decodedSchemaHash
26131
+ };
26132
+ const { schema, decodedValueHash, decodedSchemaHash } = JsonSchemaHelper.generateSchemaAndHash(data, schemaMerges);
26133
+ return {
26134
+ normalizedValue: data,
26135
+ schema,
26136
+ decodedValueHash,
26137
+ decodedSchemaHash
26138
+ };
26139
+ }
25915
26140
  /**
25916
26141
  * Transform OpenTelemetry span to clean JSON format with compile-time type safety
25917
26142
  * Return type is derived from protobuf schema but uses clean JSON.
@@ -25927,7 +26152,7 @@ var SpanTransformer = class SpanTransformer {
25927
26152
  const inputData = JSON.parse(inputValueString);
25928
26153
  const inputSchemaMergesString = attributes[TdSpanAttributes.INPUT_SCHEMA_MERGES];
25929
26154
  const inputSchemaMerges = inputSchemaMergesString ? JSON.parse(inputSchemaMergesString) : void 0;
25930
- const { schema: inputSchema, decodedValueHash: inputValueHash, decodedSchemaHash: inputSchemaHash } = JsonSchemaHelper.generateSchemaAndHash(inputData, inputSchemaMerges);
26155
+ const { normalizedValue: normalizedInputData, schema: inputSchema, decodedValueHash: inputValueHash, decodedSchemaHash: inputSchemaHash } = SpanTransformer.processPayload(inputData, inputSchemaMerges);
25931
26156
  let outputData = {};
25932
26157
  let outputSchema = {
25933
26158
  type: JsonSchemaType.OBJECT,
@@ -25940,8 +26165,8 @@ var SpanTransformer = class SpanTransformer {
25940
26165
  outputData = JSON.parse(outputValueString);
25941
26166
  const outputSchemaMergesString = attributes[TdSpanAttributes.OUTPUT_SCHEMA_MERGES];
25942
26167
  const outputSchemaMerges = outputSchemaMergesString ? JSON.parse(outputSchemaMergesString) : void 0;
25943
- ({schema: outputSchema, decodedValueHash: outputValueHash, decodedSchemaHash: outputSchemaHash} = JsonSchemaHelper.generateSchemaAndHash(outputData, outputSchemaMerges));
25944
- } else ({schema: outputSchema, decodedValueHash: outputValueHash, decodedSchemaHash: outputSchemaHash} = JsonSchemaHelper.generateSchemaAndHash(outputData));
26168
+ ({normalizedValue: outputData, schema: outputSchema, decodedValueHash: outputValueHash, decodedSchemaHash: outputSchemaHash} = SpanTransformer.processPayload(outputData, outputSchemaMerges));
26169
+ } else ({normalizedValue: outputData, schema: outputSchema, decodedValueHash: outputValueHash, decodedSchemaHash: outputSchemaHash} = SpanTransformer.processPayload(outputData));
25945
26170
  let metadata = void 0;
25946
26171
  if (attributes[TdSpanAttributes.METADATA]) metadata = JSON.parse(attributes[TdSpanAttributes.METADATA]);
25947
26172
  let transformMetadata;
@@ -25951,6 +26176,35 @@ var SpanTransformer = class SpanTransformer {
25951
26176
  } catch (error) {
25952
26177
  logger.warn("[SpanTransformer] Failed to parse transform metadata", error);
25953
26178
  }
26179
+ const protoSpanBytes = buildSpanProtoBytes({
26180
+ traceId: span.spanContext().traceId,
26181
+ spanId: span.spanContext().spanId,
26182
+ parentSpanId: span.parentSpanId || "",
26183
+ name: attributes[TdSpanAttributes.NAME] || "",
26184
+ packageName,
26185
+ instrumentationName,
26186
+ submoduleName: submoduleName || "",
26187
+ packageType: attributes[TdSpanAttributes.PACKAGE_TYPE] || PackageType.UNSPECIFIED,
26188
+ environment,
26189
+ kind: span.kind,
26190
+ inputSchema,
26191
+ outputSchema,
26192
+ inputSchemaHash,
26193
+ outputSchemaHash,
26194
+ inputValueHash,
26195
+ outputValueHash,
26196
+ statusCode: span.status.code === 1 ? StatusCode.OK : StatusCode.ERROR,
26197
+ statusMessage: span.status.message || "",
26198
+ isPreAppStart: attributes[TdSpanAttributes.IS_PRE_APP_START] === true,
26199
+ isRootSpan,
26200
+ timestampSeconds: span.startTime[0],
26201
+ timestampNanos: span.startTime[1],
26202
+ durationSeconds: span.duration[0],
26203
+ durationNanos: span.duration[1],
26204
+ metadata,
26205
+ inputValue: normalizedInputData,
26206
+ outputValue: outputData
26207
+ });
25954
26208
  return {
25955
26209
  traceId: span.spanContext().traceId,
25956
26210
  spanId: span.spanContext().spanId,
@@ -25959,9 +26213,9 @@ var SpanTransformer = class SpanTransformer {
25959
26213
  packageName,
25960
26214
  instrumentationName,
25961
26215
  submoduleName: submoduleName || "",
25962
- packageType: attributes[TdSpanAttributes.PACKAGE_TYPE] || void 0,
26216
+ packageType: attributes[TdSpanAttributes.PACKAGE_TYPE] ?? void 0,
25963
26217
  environment,
25964
- inputValue: inputData,
26218
+ inputValue: normalizedInputData,
25965
26219
  outputValue: outputData,
25966
26220
  inputSchema,
25967
26221
  outputSchema,
@@ -25985,7 +26239,8 @@ var SpanTransformer = class SpanTransformer {
25985
26239
  },
25986
26240
  isRootSpan,
25987
26241
  metadata,
25988
- transformMetadata
26242
+ transformMetadata,
26243
+ protoSpanBytes: protoSpanBytes ?? void 0
25989
26244
  };
25990
26245
  }
25991
26246
  /**
@@ -26409,6 +26664,8 @@ const DRIFT_API_PATH = "/api/drift";
26409
26664
  var ApiSpanAdapter = class {
26410
26665
  constructor(config) {
26411
26666
  this.name = "api";
26667
+ this.apiKey = config.apiKey;
26668
+ this.tuskBackendBaseUrl = config.tuskBackendBaseUrl;
26412
26669
  this.observableServiceId = config.observableServiceId;
26413
26670
  this.environment = config.environment;
26414
26671
  this.sdkVersion = config.sdkVersion;
@@ -26424,6 +26681,24 @@ var ApiSpanAdapter = class {
26424
26681
  }
26425
26682
  async exportSpans(spans) {
26426
26683
  try {
26684
+ const rustRequestBytes = buildExportSpansRequestBytes(this.observableServiceId, this.environment || "", this.sdkVersion, this.sdkInstanceId, spans.map((s) => s.protoSpanBytes).filter((s) => Buffer.isBuffer(s)));
26685
+ if (spans.length > 0 && spans.every((s) => Buffer.isBuffer(s.protoSpanBytes)) && rustRequestBytes) {
26686
+ const response$1 = await fetch(`${this.tuskBackendBaseUrl}${DRIFT_API_PATH}/tusk.drift.backend.v1.SpanExportService/ExportSpans`, {
26687
+ method: "POST",
26688
+ headers: {
26689
+ "x-api-key": this.apiKey,
26690
+ "x-td-skip-instrumentation": "true",
26691
+ "Content-Type": "application/protobuf"
26692
+ },
26693
+ body: new Uint8Array(rustRequestBytes)
26694
+ });
26695
+ if (!response$1.ok) throw new Error(`Remote export failed with status ${response$1.status}`);
26696
+ const responseBytes = new Uint8Array(await response$1.arrayBuffer());
26697
+ const parsed = ExportSpansResponse.fromBinary(responseBytes);
26698
+ if (!parsed.success) throw new Error(`Remote export failed: ${parsed.message}`);
26699
+ logger.debug(`Successfully exported ${spans.length} spans to remote endpoint (rust binary path)`);
26700
+ return { code: import_src$8.ExportResultCode.SUCCESS };
26701
+ }
26427
26702
  const protoSpans = spans.map((span) => this.transformSpanToProtobuf(span));
26428
26703
  const request = {
26429
26704
  observableServiceId: this.observableServiceId,
@@ -26453,7 +26728,7 @@ var ApiSpanAdapter = class {
26453
26728
  packageName: cleanSpan.packageName,
26454
26729
  instrumentationName: cleanSpan.instrumentationName,
26455
26730
  submoduleName: cleanSpan.submoduleName,
26456
- packageType: cleanSpan.packageType || PackageType.UNSPECIFIED,
26731
+ packageType: cleanSpan.packageType ?? PackageType.UNSPECIFIED,
26457
26732
  environment: this.environment,
26458
26733
  inputValue: toStruct(cleanSpan.inputValue),
26459
26734
  outputValue: toStruct(cleanSpan.outputValue),
@@ -33735,7 +34010,7 @@ var require_src = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/sdk-
33735
34010
  //#endregion
33736
34011
  //#region package.json
33737
34012
  var import_src$1 = /* @__PURE__ */ __toESM(require_src(), 1);
33738
- var version = "0.1.29";
34013
+ var version = "0.1.31";
33739
34014
 
33740
34015
  //#endregion
33741
34016
  //#region src/version.ts
@@ -33743,7 +34018,7 @@ const SDK_VERSION = version;
33743
34018
  const MIN_CLI_VERSION = "0.1.0";
33744
34019
 
33745
34020
  //#endregion
33746
- //#region node_modules/@use-tusk/drift-schemas/dist/communication-GAvDDkJW.js
34021
+ //#region node_modules/@use-tusk/drift-schemas/dist/communication-DR7GLSjb.js
33747
34022
  var import_commonjs = /* @__PURE__ */ __toESM(require_commonjs$1(), 1);
33748
34023
  var import_commonjs$1 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
33749
34024
  /**
@@ -35624,6 +35899,20 @@ var TuskDriftCore = class TuskDriftCore {
35624
35899
  default: return TuskDriftMode.DISABLED;
35625
35900
  }
35626
35901
  }
35902
+ logRustCoreStartupStatus() {
35903
+ const status = getRustCoreStartupStatus();
35904
+ const envDisplay = status.rawEnv ?? "<unset>";
35905
+ if (status.reason === "invalid_env_value_defaulted") logger.warn(`Invalid TUSK_USE_RUST_CORE value '${envDisplay}'; defaulting to enabled rust core path.`);
35906
+ if (!status.enabled) {
35907
+ logger.info(`Rust core path disabled at startup (env=${envDisplay}, reason=${status.reason}).`);
35908
+ return;
35909
+ }
35910
+ if (status.bindingLoaded) {
35911
+ logger.info(`Rust core path enabled at startup (env=${envDisplay}, reason=${status.reason}).`);
35912
+ return;
35913
+ }
35914
+ logger.warn(`Rust core path requested but binding unavailable; falling back to JavaScript path (env=${envDisplay}, reason=${status.reason}, error=${status.bindingError}).`);
35915
+ }
35627
35916
  validateSamplingRate(value, source) {
35628
35917
  if (typeof value !== "number" || isNaN(value)) {
35629
35918
  logger.warn(`Invalid sampling rate from ${source}: not a number. Ignoring.`);
@@ -35806,6 +36095,7 @@ var TuskDriftCore = class TuskDriftCore {
35806
36095
  logger.debug("SDK disabled via environment variable");
35807
36096
  return;
35808
36097
  }
36098
+ this.logRustCoreStartupStatus();
35809
36099
  logger.debug(`Initializing in ${this.mode} mode`);
35810
36100
  if (!this.initParams.env) {
35811
36101
  const nodeEnv = OriginalGlobalUtils.getOriginalProcessEnvVar("NODE_ENV") || "development";