@glasstrace/sdk 0.13.6 → 0.14.0

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
@@ -14601,7 +14601,8 @@ var init_dist = __esm({
14601
14601
  envVarValues: external_exports.boolean(),
14602
14602
  fullConsoleOutput: external_exports.boolean(),
14603
14603
  importGraph: external_exports.boolean(),
14604
- consoleErrors: external_exports.boolean().optional().default(false)
14604
+ consoleErrors: external_exports.boolean().optional().default(false),
14605
+ errorResponseBodies: external_exports.boolean().optional().default(false)
14605
14606
  });
14606
14607
  SdkCachedConfigSchema = external_exports.object({
14607
14608
  response: external_exports.record(external_exports.string(), external_exports.unknown()),
@@ -14732,6 +14733,8 @@ var init_dist = __esm({
14732
14733
  SOURCE_FILE: "glasstrace.source.file",
14733
14734
  SOURCE_LINE: "glasstrace.source.line",
14734
14735
  SOURCE_MAPPED: "glasstrace.source.mapped",
14736
+ TRPC_PROCEDURE: "glasstrace.trpc.procedure",
14737
+ ERROR_RESPONSE_BODY: "glasstrace.error.response_body",
14735
14738
  // Client-side attributes
14736
14739
  PLATFORM: "glasstrace.platform",
14737
14740
  GESTURE_TYPE: "glasstrace.gesture.type",
@@ -14746,7 +14749,8 @@ var init_dist = __esm({
14746
14749
  envVarValues: false,
14747
14750
  fullConsoleOutput: false,
14748
14751
  importGraph: false,
14749
- consoleErrors: false
14752
+ consoleErrors: false,
14753
+ errorResponseBodies: false
14750
14754
  };
14751
14755
  }
14752
14756
  });
@@ -16614,7 +16618,6 @@ async function uploadSourceMaps(apiKey, endpoint, buildHash, maps) {
16614
16618
  }
16615
16619
  }
16616
16620
  const body = {
16617
- apiKey,
16618
16621
  buildHash,
16619
16622
  files
16620
16623
  };
@@ -16836,6 +16839,7 @@ __export(src_exports, {
16836
16839
  collectSourceMaps: () => collectSourceMaps,
16837
16840
  computeBuildHash: () => computeBuildHash,
16838
16841
  createDiscoveryHandler: () => createDiscoveryHandler,
16842
+ createGlasstraceSpanProcessor: () => createGlasstraceSpanProcessor,
16839
16843
  deriveSessionId: () => deriveSessionId,
16840
16844
  discoverSourceMapFiles: () => discoverSourceMapFiles,
16841
16845
  discoverTestFiles: () => discoverTestFiles,
@@ -16846,8 +16850,10 @@ __export(src_exports, {
16846
16850
  getLinkedAccountId: () => getLinkedAccountId,
16847
16851
  getOrCreateAnonKey: () => getOrCreateAnonKey,
16848
16852
  getOrigin: () => getOrigin,
16853
+ getStatus: () => getStatus,
16849
16854
  isAnonymousMode: () => isAnonymousMode,
16850
16855
  isProductionDisabled: () => isProductionDisabled,
16856
+ isReady: () => isReady,
16851
16857
  loadCachedConfig: () => loadCachedConfig,
16852
16858
  performInit: () => performInit,
16853
16859
  readAnonKey: () => readAnonKey,
@@ -16859,6 +16865,7 @@ __export(src_exports, {
16859
16865
  uploadSourceMaps: () => uploadSourceMaps,
16860
16866
  uploadSourceMapsAuto: () => uploadSourceMapsAuto,
16861
16867
  uploadSourceMapsPresigned: () => uploadSourceMapsPresigned,
16868
+ waitForReady: () => waitForReady,
16862
16869
  withGlasstraceConfig: () => withGlasstraceConfig
16863
16870
  });
16864
16871
  module.exports = __toCommonJS(src_exports);
@@ -17229,7 +17236,6 @@ async function sendInitRequest(config2, anonKey, sdkVersion, importGraph, health
17229
17236
  throw new Error("No API key available for init request");
17230
17237
  }
17231
17238
  const payload = {
17232
- apiKey: effectiveKey,
17233
17239
  sdkVersion
17234
17240
  };
17235
17241
  if (config2.apiKey && anonKey) {
@@ -17466,7 +17472,7 @@ init_cjs_shims();
17466
17472
  var GlasstraceSpanProcessor = class {
17467
17473
  wrappedProcessor;
17468
17474
  /* eslint-disable @typescript-eslint/no-unused-vars -- backward compat signature */
17469
- constructor(wrappedProcessor, _sessionManager, _apiKey, _getConfig, _environment) {
17475
+ constructor(wrappedProcessor, _sessionManager2, _apiKey, _getConfig, _environment) {
17470
17476
  this.wrappedProcessor = wrappedProcessor;
17471
17477
  }
17472
17478
  onStart(span, parentContext) {
@@ -17512,6 +17518,7 @@ var GlasstraceExporter = class {
17512
17518
  this.endpointUrl = options.endpointUrl;
17513
17519
  this.createDelegateFn = options.createDelegate;
17514
17520
  this.verbose = options.verbose ?? false;
17521
+ this[/* @__PURE__ */ Symbol.for("glasstrace.exporter")] = true;
17515
17522
  }
17516
17523
  export(spans, resultCallback) {
17517
17524
  const currentKey = this.getApiKey();
@@ -17609,6 +17616,22 @@ var GlasstraceExporter = class {
17609
17616
  if (route) {
17610
17617
  extra[ATTR.ROUTE] = route;
17611
17618
  }
17619
+ const rawUrl = attrs["http.url"] ?? attrs["url.full"] ?? attrs["http.target"];
17620
+ const trpcUrl = typeof rawUrl === "string" ? rawUrl : void 0;
17621
+ if (trpcUrl) {
17622
+ const trpcMatch = trpcUrl.match(/\/api\/trpc\/([^/?#]+)/);
17623
+ if (trpcMatch) {
17624
+ let procedure;
17625
+ try {
17626
+ procedure = decodeURIComponent(trpcMatch[1]);
17627
+ } catch {
17628
+ procedure = trpcMatch[1];
17629
+ }
17630
+ if (procedure) {
17631
+ extra[ATTR.TRPC_PROCEDURE] = procedure;
17632
+ }
17633
+ }
17634
+ }
17612
17635
  const method = attrs["http.method"] ?? attrs["http.request.method"];
17613
17636
  if (method) {
17614
17637
  extra[ATTR.HTTP_METHOD] = method;
@@ -17683,6 +17706,12 @@ var GlasstraceExporter = class {
17683
17706
  if (typeof errorField === "string") {
17684
17707
  extra[ATTR.ERROR_FIELD] = errorField;
17685
17708
  }
17709
+ if (this.getConfig().errorResponseBodies) {
17710
+ const responseBody = attrs["glasstrace.internal.response_body"];
17711
+ if (typeof responseBody === "string") {
17712
+ extra[ATTR.ERROR_RESPONSE_BODY] = responseBody.slice(0, 500);
17713
+ }
17714
+ }
17686
17715
  const spanAny = span;
17687
17716
  const instrumentationName = spanAny.instrumentationScope?.name ?? spanAny.instrumentationLibrary?.name ?? "";
17688
17717
  const ormProvider = deriveOrmProvider(instrumentationName);
@@ -20684,9 +20713,461 @@ var BasicTracerProvider = class {
20684
20713
  // src/otel-config.ts
20685
20714
  init_esm();
20686
20715
  init_console_capture();
20716
+
20717
+ // src/lifecycle.ts
20718
+ init_cjs_shims();
20719
+ var import_node_events = require("events");
20720
+ var CoreState = {
20721
+ IDLE: "IDLE",
20722
+ REGISTERING: "REGISTERING",
20723
+ KEY_PENDING: "KEY_PENDING",
20724
+ KEY_RESOLVED: "KEY_RESOLVED",
20725
+ ACTIVE: "ACTIVE",
20726
+ ACTIVE_DEGRADED: "ACTIVE_DEGRADED",
20727
+ SHUTTING_DOWN: "SHUTTING_DOWN",
20728
+ SHUTDOWN: "SHUTDOWN",
20729
+ PRODUCTION_DISABLED: "PRODUCTION_DISABLED",
20730
+ REGISTRATION_FAILED: "REGISTRATION_FAILED"
20731
+ };
20732
+ var AuthState = {
20733
+ ANONYMOUS: "ANONYMOUS",
20734
+ AUTHENTICATED: "AUTHENTICATED",
20735
+ CLAIMING: "CLAIMING",
20736
+ CLAIMED: "CLAIMED"
20737
+ };
20738
+ var OtelState = {
20739
+ UNCONFIGURED: "UNCONFIGURED",
20740
+ CONFIGURING: "CONFIGURING",
20741
+ OWNS_PROVIDER: "OWNS_PROVIDER",
20742
+ AUTO_ATTACHED: "AUTO_ATTACHED",
20743
+ PROCESSOR_PRESENT: "PROCESSOR_PRESENT",
20744
+ COEXISTENCE_FAILED: "COEXISTENCE_FAILED"
20745
+ };
20746
+ var VALID_CORE_TRANSITIONS = {
20747
+ [CoreState.IDLE]: [CoreState.REGISTERING, CoreState.REGISTRATION_FAILED, CoreState.SHUTTING_DOWN],
20748
+ [CoreState.REGISTERING]: [
20749
+ CoreState.KEY_PENDING,
20750
+ CoreState.PRODUCTION_DISABLED,
20751
+ CoreState.REGISTRATION_FAILED,
20752
+ CoreState.SHUTTING_DOWN
20753
+ ],
20754
+ [CoreState.KEY_PENDING]: [
20755
+ CoreState.KEY_RESOLVED,
20756
+ CoreState.REGISTRATION_FAILED,
20757
+ CoreState.SHUTTING_DOWN
20758
+ ],
20759
+ [CoreState.KEY_RESOLVED]: [
20760
+ CoreState.ACTIVE,
20761
+ CoreState.ACTIVE_DEGRADED,
20762
+ CoreState.SHUTTING_DOWN
20763
+ ],
20764
+ [CoreState.ACTIVE]: [
20765
+ CoreState.ACTIVE_DEGRADED,
20766
+ CoreState.SHUTTING_DOWN
20767
+ ],
20768
+ [CoreState.ACTIVE_DEGRADED]: [
20769
+ CoreState.ACTIVE,
20770
+ CoreState.SHUTTING_DOWN
20771
+ ],
20772
+ [CoreState.SHUTTING_DOWN]: [CoreState.SHUTDOWN],
20773
+ [CoreState.SHUTDOWN]: [],
20774
+ [CoreState.PRODUCTION_DISABLED]: [],
20775
+ [CoreState.REGISTRATION_FAILED]: []
20776
+ };
20777
+ var VALID_AUTH_TRANSITIONS = {
20778
+ [AuthState.ANONYMOUS]: [AuthState.CLAIMING],
20779
+ [AuthState.AUTHENTICATED]: [AuthState.CLAIMING],
20780
+ [AuthState.CLAIMING]: [AuthState.CLAIMED],
20781
+ [AuthState.CLAIMED]: [AuthState.CLAIMING]
20782
+ };
20783
+ var VALID_OTEL_TRANSITIONS = {
20784
+ [OtelState.UNCONFIGURED]: [OtelState.CONFIGURING],
20785
+ [OtelState.CONFIGURING]: [
20786
+ OtelState.OWNS_PROVIDER,
20787
+ OtelState.AUTO_ATTACHED,
20788
+ OtelState.PROCESSOR_PRESENT,
20789
+ OtelState.COEXISTENCE_FAILED
20790
+ ],
20791
+ [OtelState.OWNS_PROVIDER]: [],
20792
+ [OtelState.AUTO_ATTACHED]: [],
20793
+ [OtelState.PROCESSOR_PRESENT]: [],
20794
+ [OtelState.COEXISTENCE_FAILED]: []
20795
+ };
20796
+ var _coreState = CoreState.IDLE;
20797
+ var _authState = AuthState.ANONYMOUS;
20798
+ var _otelState = OtelState.UNCONFIGURED;
20799
+ var _emitter = new import_node_events.EventEmitter();
20800
+ var _logger = null;
20801
+ var _initialized = false;
20802
+ var _initWarned = false;
20803
+ var _coreReadyEmitted = false;
20804
+ var _authInitialized = false;
20805
+ var _emitting = false;
20806
+ function initLifecycle(options) {
20807
+ if (_initialized) {
20808
+ options.logger("warn", "[glasstrace] initLifecycle() called twice \u2014 ignored.");
20809
+ return;
20810
+ }
20811
+ _logger = options.logger;
20812
+ _initialized = true;
20813
+ }
20814
+ function warnIfNotInitialized() {
20815
+ if (!_initialized && !_initWarned) {
20816
+ _initWarned = true;
20817
+ console.warn(
20818
+ "[glasstrace] Lifecycle state changed before initLifecycle() was called. Logger not available \u2014 errors will be silent."
20819
+ );
20820
+ }
20821
+ }
20822
+ function setCoreState(to) {
20823
+ warnIfNotInitialized();
20824
+ const from = _coreState;
20825
+ if (from === to) return;
20826
+ const valid = VALID_CORE_TRANSITIONS[from];
20827
+ if (!valid.includes(to)) {
20828
+ _logger?.(
20829
+ "warn",
20830
+ `[glasstrace] Invalid core state transition: ${from} \u2192 ${to}. Ignored.`
20831
+ );
20832
+ return;
20833
+ }
20834
+ _coreState = to;
20835
+ if (_emitting) return;
20836
+ _emitting = true;
20837
+ try {
20838
+ emitSafe("core:state_changed", { from, to });
20839
+ const current = _coreState;
20840
+ if (!_coreReadyEmitted && (current === CoreState.ACTIVE || current === CoreState.ACTIVE_DEGRADED)) {
20841
+ _coreReadyEmitted = true;
20842
+ emitSafe("core:ready", {});
20843
+ }
20844
+ if (current === CoreState.SHUTTING_DOWN) {
20845
+ emitSafe("core:shutdown_started", {});
20846
+ }
20847
+ if (current === CoreState.SHUTDOWN) {
20848
+ emitSafe("core:shutdown_completed", {});
20849
+ }
20850
+ } finally {
20851
+ _emitting = false;
20852
+ }
20853
+ }
20854
+ function initAuthState(state) {
20855
+ if (_authInitialized) {
20856
+ _logger?.(
20857
+ "warn",
20858
+ "[glasstrace] initAuthState() called after auth state already initialized. Ignored."
20859
+ );
20860
+ return;
20861
+ }
20862
+ _authInitialized = true;
20863
+ _authState = state;
20864
+ }
20865
+ function setAuthState(to) {
20866
+ warnIfNotInitialized();
20867
+ const from = _authState;
20868
+ if (from === to) return;
20869
+ const valid = VALID_AUTH_TRANSITIONS[from];
20870
+ if (!valid.includes(to)) {
20871
+ _logger?.(
20872
+ "warn",
20873
+ `[glasstrace] Invalid auth state transition: ${from} \u2192 ${to}. Ignored.`
20874
+ );
20875
+ return;
20876
+ }
20877
+ _authState = to;
20878
+ }
20879
+ function setOtelState(to) {
20880
+ warnIfNotInitialized();
20881
+ const from = _otelState;
20882
+ if (from === to) return;
20883
+ const valid = VALID_OTEL_TRANSITIONS[from];
20884
+ if (!valid.includes(to)) {
20885
+ _logger?.(
20886
+ "warn",
20887
+ `[glasstrace] Invalid OTel state transition: ${from} \u2192 ${to}. Ignored.`
20888
+ );
20889
+ return;
20890
+ }
20891
+ _otelState = to;
20892
+ }
20893
+ function getCoreState() {
20894
+ return _coreState;
20895
+ }
20896
+ function getSdkState() {
20897
+ return {
20898
+ core: _coreState,
20899
+ auth: _authState,
20900
+ otel: _otelState
20901
+ };
20902
+ }
20903
+ function onLifecycleEvent(event, listener) {
20904
+ _emitter.on(event, listener);
20905
+ }
20906
+ function emitLifecycleEvent(event, payload) {
20907
+ emitSafe(event, payload);
20908
+ }
20909
+ function offLifecycleEvent(event, listener) {
20910
+ _emitter.off(event, listener);
20911
+ }
20912
+ function emitSafe(event, payload) {
20913
+ const listeners = _emitter.listeners(event);
20914
+ for (const listener of listeners) {
20915
+ try {
20916
+ const result = listener(payload);
20917
+ if (result && typeof result.catch === "function") {
20918
+ result.catch((err) => {
20919
+ _logger?.(
20920
+ "error",
20921
+ `[glasstrace] Async error in lifecycle event listener for "${event}": ${err instanceof Error ? err.message : String(err)}`
20922
+ );
20923
+ });
20924
+ }
20925
+ } catch (err) {
20926
+ _logger?.(
20927
+ "error",
20928
+ `[glasstrace] Error in lifecycle event listener for "${event}": ${err instanceof Error ? err.message : String(err)}`
20929
+ );
20930
+ }
20931
+ }
20932
+ }
20933
+ function isReady() {
20934
+ return _coreState === CoreState.ACTIVE || _coreState === CoreState.ACTIVE_DEGRADED;
20935
+ }
20936
+ function waitForReady(timeoutMs = 3e4) {
20937
+ if (isReady()) {
20938
+ return Promise.resolve();
20939
+ }
20940
+ if (_coreState === CoreState.PRODUCTION_DISABLED || _coreState === CoreState.REGISTRATION_FAILED || _coreState === CoreState.SHUTTING_DOWN || _coreState === CoreState.SHUTDOWN) {
20941
+ return Promise.reject(new Error(`SDK is in terminal state: ${_coreState}`));
20942
+ }
20943
+ return new Promise((resolve3, reject) => {
20944
+ let settled = false;
20945
+ const listener = ({ to }) => {
20946
+ if (settled) return;
20947
+ if (to === CoreState.ACTIVE || to === CoreState.ACTIVE_DEGRADED) {
20948
+ settled = true;
20949
+ offLifecycleEvent("core:state_changed", listener);
20950
+ resolve3();
20951
+ } else if (to === CoreState.PRODUCTION_DISABLED || to === CoreState.REGISTRATION_FAILED || to === CoreState.SHUTTING_DOWN || to === CoreState.SHUTDOWN) {
20952
+ settled = true;
20953
+ offLifecycleEvent("core:state_changed", listener);
20954
+ reject(new Error(`SDK reached terminal state: ${to}`));
20955
+ }
20956
+ };
20957
+ onLifecycleEvent("core:state_changed", listener);
20958
+ if (timeoutMs > 0) {
20959
+ const timer = setTimeout(() => {
20960
+ if (settled) return;
20961
+ settled = true;
20962
+ offLifecycleEvent("core:state_changed", listener);
20963
+ reject(new Error(`waitForReady timed out after ${timeoutMs}ms (state: ${_coreState})`));
20964
+ }, timeoutMs);
20965
+ if (typeof timer === "object" && "unref" in timer) {
20966
+ timer.unref();
20967
+ }
20968
+ }
20969
+ });
20970
+ }
20971
+ function getStatus() {
20972
+ let mode;
20973
+ if (_coreState === CoreState.PRODUCTION_DISABLED) {
20974
+ mode = "disabled";
20975
+ } else if (_authState === AuthState.CLAIMING || _authState === AuthState.CLAIMED) {
20976
+ mode = "claiming";
20977
+ } else if (_authState === AuthState.AUTHENTICATED) {
20978
+ mode = "authenticated";
20979
+ } else {
20980
+ mode = "anonymous";
20981
+ }
20982
+ let tracing;
20983
+ if (_otelState === OtelState.COEXISTENCE_FAILED || _otelState === OtelState.UNCONFIGURED || _otelState === OtelState.CONFIGURING) {
20984
+ tracing = "not-configured";
20985
+ } else if (_coreState === CoreState.ACTIVE_DEGRADED) {
20986
+ tracing = "degraded";
20987
+ } else if (_otelState === OtelState.AUTO_ATTACHED || _otelState === OtelState.PROCESSOR_PRESENT) {
20988
+ tracing = "coexistence";
20989
+ } else {
20990
+ tracing = "active";
20991
+ }
20992
+ return {
20993
+ ready: isReady(),
20994
+ mode,
20995
+ tracing
20996
+ };
20997
+ }
20998
+ var _shutdownHooks = [];
20999
+ var _signalHandlersRegistered = false;
21000
+ var _signalHandler = null;
21001
+ var _beforeExitRegistered = false;
21002
+ var _beforeExitHandler = null;
21003
+ var _shutdownExecuted = false;
21004
+ function registerShutdownHook(hook) {
21005
+ _shutdownHooks.push(hook);
21006
+ _shutdownHooks.sort((a, b) => a.priority - b.priority);
21007
+ }
21008
+ async function executeShutdown(timeoutMs = 5e3) {
21009
+ if (_shutdownExecuted) return;
21010
+ _shutdownExecuted = true;
21011
+ setCoreState(CoreState.SHUTTING_DOWN);
21012
+ for (const hook of _shutdownHooks) {
21013
+ try {
21014
+ const hookPromise = hook.fn();
21015
+ hookPromise.catch(() => {
21016
+ });
21017
+ await Promise.race([
21018
+ hookPromise,
21019
+ new Promise((_, reject) => {
21020
+ const timer = setTimeout(() => reject(new Error(`Shutdown hook "${hook.name}" timed out`)), timeoutMs);
21021
+ if (typeof timer === "object" && "unref" in timer) {
21022
+ timer.unref();
21023
+ }
21024
+ })
21025
+ ]);
21026
+ } catch (err) {
21027
+ _logger?.(
21028
+ "warn",
21029
+ `[glasstrace] Shutdown hook "${hook.name}" failed: ${err instanceof Error ? err.message : String(err)}`
21030
+ );
21031
+ }
21032
+ }
21033
+ setCoreState(CoreState.SHUTDOWN);
21034
+ }
21035
+ function registerSignalHandlers() {
21036
+ if (_signalHandlersRegistered) return;
21037
+ if (typeof process === "undefined" || typeof process.once !== "function") return;
21038
+ _signalHandlersRegistered = true;
21039
+ const handler = (signal) => {
21040
+ void executeShutdown().finally(() => {
21041
+ if (_signalHandler) {
21042
+ process.removeListener("SIGTERM", _signalHandler);
21043
+ process.removeListener("SIGINT", _signalHandler);
21044
+ }
21045
+ process.kill(process.pid, signal);
21046
+ });
21047
+ };
21048
+ _signalHandler = handler;
21049
+ process.once("SIGTERM", handler);
21050
+ process.once("SIGINT", handler);
21051
+ }
21052
+ function registerBeforeExitTrigger() {
21053
+ if (_beforeExitRegistered) return;
21054
+ if (typeof process === "undefined" || typeof process.once !== "function") return;
21055
+ _beforeExitRegistered = true;
21056
+ const handler = () => {
21057
+ void executeShutdown();
21058
+ };
21059
+ _beforeExitHandler = handler;
21060
+ process.once("beforeExit", handler);
21061
+ }
21062
+
21063
+ // src/coexistence.ts
21064
+ init_cjs_shims();
21065
+ init_env_detection();
21066
+ init_console_capture();
21067
+ function createGlasstraceSpanProcessor(options) {
21068
+ const config2 = resolveConfig(options);
21069
+ const exporterUrl = `${config2.endpoint}/v1/traces`;
21070
+ const createOtlpExporter = (url2, headers) => new OTLPTraceExporter({ url: url2, headers });
21071
+ const exporter = new GlasstraceExporter({
21072
+ getApiKey: getResolvedApiKey,
21073
+ sessionManager: getSessionManager(),
21074
+ getConfig: () => getActiveConfig(),
21075
+ environment: config2.environment,
21076
+ endpointUrl: exporterUrl,
21077
+ createDelegate: createOtlpExporter
21078
+ });
21079
+ registerExporterForKeyNotification(exporter);
21080
+ return new BatchSpanProcessor(exporter, {
21081
+ scheduledDelayMillis: 1e3
21082
+ });
21083
+ }
21084
+ function emitNudgeMessage() {
21085
+ const isSentry = detectSentry();
21086
+ if (isSentry) {
21087
+ sdkLog(
21088
+ "info",
21089
+ `[glasstrace] Detected existing OTel provider \u2014 auto-attached Glasstrace span processor.
21090
+ For a cleaner setup, add Glasstrace to your Sentry config:
21091
+
21092
+ import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
21093
+
21094
+ Sentry.init({
21095
+ dsn: '...',
21096
+ openTelemetrySpanProcessors: [createGlasstraceSpanProcessor()],
21097
+ });
21098
+
21099
+ This message will not appear once Glasstrace is added to your provider config.`
21100
+ );
21101
+ } else {
21102
+ sdkLog(
21103
+ "info",
21104
+ `[glasstrace] Detected existing OTel provider \u2014 auto-attached Glasstrace span processor.
21105
+ For a cleaner setup, add Glasstrace to your provider config:
21106
+
21107
+ import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
21108
+
21109
+ const provider = new BasicTracerProvider({
21110
+ spanProcessors: [
21111
+ // ... your existing processors,
21112
+ createGlasstraceSpanProcessor(),
21113
+ ],
21114
+ });
21115
+
21116
+ This message will not appear once Glasstrace is added to your provider config.`
21117
+ );
21118
+ }
21119
+ }
21120
+ function emitGuidanceMessage() {
21121
+ const isSentry = detectSentry();
21122
+ if (isSentry) {
21123
+ sdkLog(
21124
+ "warn",
21125
+ `[glasstrace] An existing OTel TracerProvider is registered but Glasstrace could not auto-attach its span processor.
21126
+ Add Glasstrace to your Sentry config:
21127
+
21128
+ import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
21129
+
21130
+ Sentry.init({
21131
+ dsn: '...',
21132
+ openTelemetrySpanProcessors: [createGlasstraceSpanProcessor()],
21133
+ });`
21134
+ );
21135
+ } else {
21136
+ sdkLog(
21137
+ "warn",
21138
+ `[glasstrace] An existing OTel TracerProvider is registered but Glasstrace could not auto-attach its span processor.
21139
+ Add Glasstrace to your provider configuration:
21140
+
21141
+ import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
21142
+
21143
+ const provider = new BasicTracerProvider({
21144
+ spanProcessors: [
21145
+ // ... your existing processors,
21146
+ createGlasstraceSpanProcessor(),
21147
+ ],
21148
+ });`
21149
+ );
21150
+ }
21151
+ }
21152
+ function detectSentry() {
21153
+ try {
21154
+ require.resolve("@sentry/node");
21155
+ return true;
21156
+ } catch {
21157
+ try {
21158
+ require.resolve("@sentry/nextjs");
21159
+ return true;
21160
+ } catch {
21161
+ return false;
21162
+ }
21163
+ }
21164
+ }
21165
+
21166
+ // src/otel-config.ts
20687
21167
  var _resolvedApiKey = API_KEY_PENDING;
20688
21168
  var _activeExporter = null;
20689
- var _shutdownHandler = null;
21169
+ var _additionalExporters = [];
21170
+ var _injectedProcessor = null;
20690
21171
  function setResolvedApiKey(key) {
20691
21172
  _resolvedApiKey = key;
20692
21173
  }
@@ -20695,6 +21176,12 @@ function getResolvedApiKey() {
20695
21176
  }
20696
21177
  function notifyApiKeyResolved() {
20697
21178
  _activeExporter?.notifyKeyResolved();
21179
+ for (const exporter of _additionalExporters) {
21180
+ exporter.notifyKeyResolved();
21181
+ }
21182
+ }
21183
+ function registerExporterForKeyNotification(exporter) {
21184
+ _additionalExporters.push(exporter);
20698
21185
  }
20699
21186
  async function tryImport(moduleId) {
20700
21187
  try {
@@ -20703,34 +21190,65 @@ async function tryImport(moduleId) {
20703
21190
  return null;
20704
21191
  }
20705
21192
  }
20706
- function registerShutdownHooks(provider) {
20707
- if (typeof process === "undefined" || typeof process.once !== "function") {
20708
- return;
20709
- }
20710
- if (_shutdownHandler) {
20711
- process.removeListener("SIGTERM", _shutdownHandler);
20712
- process.removeListener("SIGINT", _shutdownHandler);
21193
+ function tryInjectProcessor(tracerProvider, glasstraceExporter) {
21194
+ try {
21195
+ const proxy = tracerProvider;
21196
+ const delegate = typeof proxy.getDelegate === "function" ? proxy.getDelegate() : tracerProvider;
21197
+ const withAdd = delegate;
21198
+ if (typeof withAdd.addSpanProcessor === "function") {
21199
+ if (typeof withAdd.getActiveSpanProcessor === "function") {
21200
+ const active = withAdd.getActiveSpanProcessor();
21201
+ const brand = /* @__PURE__ */ Symbol.for("glasstrace.exporter");
21202
+ const processors = active?._spanProcessors;
21203
+ if (Array.isArray(processors) && processors.some((p) => {
21204
+ const exp = p._exporter;
21205
+ return exp?.[brand] === true;
21206
+ })) {
21207
+ return "already_present";
21208
+ }
21209
+ }
21210
+ const processor2 = new BatchSpanProcessor(glasstraceExporter, {
21211
+ scheduledDelayMillis: 1e3
21212
+ });
21213
+ withAdd.addSpanProcessor(processor2);
21214
+ _injectedProcessor = processor2;
21215
+ return "v1_public";
21216
+ }
21217
+ const provider = delegate;
21218
+ const multiProcessor = provider._activeSpanProcessor;
21219
+ if (!multiProcessor || !Array.isArray(multiProcessor._spanProcessors)) {
21220
+ return null;
21221
+ }
21222
+ const processor = new BatchSpanProcessor(glasstraceExporter, {
21223
+ scheduledDelayMillis: 1e3
21224
+ });
21225
+ multiProcessor._spanProcessors.push(processor);
21226
+ _injectedProcessor = processor;
21227
+ return "v2_private";
21228
+ } catch {
21229
+ return null;
20713
21230
  }
20714
- let shutdownCalled = false;
20715
- const shutdown = (signal) => {
20716
- if (shutdownCalled) return;
20717
- shutdownCalled = true;
20718
- void provider.shutdown().catch((err) => {
20719
- console.warn(
20720
- `[glasstrace] Error during OTel shutdown: ${err instanceof Error ? err.message : String(err)}`
20721
- );
20722
- }).finally(() => {
20723
- process.removeListener("SIGTERM", _shutdownHandler);
20724
- process.removeListener("SIGINT", _shutdownHandler);
20725
- process.kill(process.pid, signal);
21231
+ }
21232
+ function isGlasstraceProcessorPresent(tracerProvider) {
21233
+ try {
21234
+ const proxy = tracerProvider;
21235
+ const delegate = typeof proxy.getDelegate === "function" ? proxy.getDelegate() : tracerProvider;
21236
+ const provider = delegate;
21237
+ const processors = provider._activeSpanProcessor?._spanProcessors;
21238
+ if (!Array.isArray(processors)) {
21239
+ return false;
21240
+ }
21241
+ const brand = /* @__PURE__ */ Symbol.for("glasstrace.exporter");
21242
+ return processors.some((p) => {
21243
+ const exporter = p._exporter;
21244
+ return exporter?.[brand] === true;
20726
21245
  });
20727
- };
20728
- const handler = (signal) => shutdown(signal);
20729
- _shutdownHandler = handler;
20730
- process.once("SIGTERM", handler);
20731
- process.once("SIGINT", handler);
21246
+ } catch {
21247
+ return false;
21248
+ }
20732
21249
  }
20733
21250
  async function configureOtel(config2, sessionManager) {
21251
+ setOtelState(OtelState.CONFIGURING);
20734
21252
  const exporterUrl = `${config2.endpoint}/v1/traces`;
20735
21253
  const createOtlpExporter = (url2, headers) => new OTLPTraceExporter({ url: url2, headers });
20736
21254
  const glasstraceExporter = new GlasstraceExporter({
@@ -20743,29 +21261,87 @@ async function configureOtel(config2, sessionManager) {
20743
21261
  verbose: config2.verbose
20744
21262
  });
20745
21263
  _activeExporter = glasstraceExporter;
21264
+ await new Promise((resolve3) => {
21265
+ if (typeof setImmediate === "function") {
21266
+ setImmediate(resolve3);
21267
+ } else {
21268
+ setTimeout(resolve3, 0);
21269
+ }
21270
+ });
21271
+ const existingProvider = trace.getTracerProvider();
21272
+ const probeTracer = existingProvider.getTracer("glasstrace-probe");
21273
+ const anotherProviderRegistered = probeTracer.constructor.name !== "ProxyTracer";
21274
+ if (anotherProviderRegistered) {
21275
+ if (isGlasstraceProcessorPresent(existingProvider)) {
21276
+ if (config2.verbose) {
21277
+ sdkLog("info", "[glasstrace] Existing provider detected \u2014 Glasstrace processor already present.");
21278
+ }
21279
+ _activeExporter = null;
21280
+ setOtelState(OtelState.PROCESSOR_PRESENT);
21281
+ emitLifecycleEvent("otel:configured", { state: OtelState.PROCESSOR_PRESENT, scenario: "B-clean" });
21282
+ return;
21283
+ }
21284
+ const injectionMethod = tryInjectProcessor(existingProvider, glasstraceExporter);
21285
+ if (injectionMethod === "already_present") {
21286
+ if (config2.verbose) {
21287
+ sdkLog("info", "[glasstrace] Existing provider detected \u2014 Glasstrace processor already present (v1 check).");
21288
+ }
21289
+ _activeExporter = null;
21290
+ setOtelState(OtelState.PROCESSOR_PRESENT);
21291
+ emitLifecycleEvent("otel:configured", { state: OtelState.PROCESSOR_PRESENT, scenario: "B-clean" });
21292
+ return;
21293
+ }
21294
+ if (injectionMethod) {
21295
+ if (config2.verbose) {
21296
+ sdkLog("info", "[glasstrace] Existing provider detected \u2014 auto-attaching Glasstrace processor.");
21297
+ }
21298
+ registerShutdownHook({
21299
+ name: "coexistence-flush",
21300
+ priority: 5,
21301
+ fn: async () => {
21302
+ if (_injectedProcessor) {
21303
+ await _injectedProcessor.forceFlush();
21304
+ }
21305
+ }
21306
+ });
21307
+ registerBeforeExitTrigger();
21308
+ const scenario = injectionMethod === "v1_public" ? "D1" : "B-auto";
21309
+ setOtelState(OtelState.AUTO_ATTACHED);
21310
+ emitLifecycleEvent("otel:configured", { state: OtelState.AUTO_ATTACHED, scenario });
21311
+ emitLifecycleEvent("otel:injection_succeeded", { method: injectionMethod });
21312
+ emitNudgeMessage();
21313
+ return;
21314
+ }
21315
+ if (config2.verbose) {
21316
+ sdkLog("info", "[glasstrace] Existing provider detected \u2014 could not auto-attach.");
21317
+ }
21318
+ emitGuidanceMessage();
21319
+ _activeExporter = null;
21320
+ setOtelState(OtelState.COEXISTENCE_FAILED);
21321
+ emitLifecycleEvent("otel:configured", { state: OtelState.COEXISTENCE_FAILED, scenario: "C/F" });
21322
+ emitLifecycleEvent("otel:injection_failed", { reason: "provider internals inaccessible" });
21323
+ const coreState = getCoreState();
21324
+ if (coreState === CoreState.ACTIVE || coreState === CoreState.KEY_RESOLVED) {
21325
+ setCoreState(CoreState.ACTIVE_DEGRADED);
21326
+ }
21327
+ return;
21328
+ }
20746
21329
  const vercelOtel = await tryImport("@vercel/otel");
20747
21330
  if (vercelOtel && typeof vercelOtel.registerOTel === "function") {
20748
21331
  const otelConfig = {
20749
21332
  serviceName: "glasstrace-sdk",
20750
21333
  traceExporter: glasstraceExporter
20751
21334
  };
20752
- const prismaModule = await tryImport("@prisma/instrumentation");
20753
- if (prismaModule) {
20754
- const PrismaInstrumentation = prismaModule.PrismaInstrumentation;
21335
+ const prismaModule2 = await tryImport("@prisma/instrumentation");
21336
+ if (prismaModule2) {
21337
+ const PrismaInstrumentation = prismaModule2.PrismaInstrumentation;
20755
21338
  if (PrismaInstrumentation) {
20756
21339
  otelConfig.instrumentations = [new PrismaInstrumentation()];
20757
21340
  }
20758
21341
  }
20759
21342
  vercelOtel.registerOTel(otelConfig);
20760
- return;
20761
- }
20762
- const existingProvider = trace.getTracerProvider();
20763
- const probeTracer = existingProvider.getTracer("glasstrace-probe");
20764
- if (probeTracer.constructor.name !== "ProxyTracer") {
20765
- console.warn(
20766
- "[glasstrace] An existing OpenTelemetry TracerProvider is already registered. Glasstrace will not overwrite it. To use Glasstrace alongside another tracing tool, add GlasstraceExporter as an additional span processor on your existing provider."
20767
- );
20768
- _activeExporter = null;
21343
+ setOtelState(OtelState.OWNS_PROVIDER);
21344
+ emitLifecycleEvent("otel:configured", { state: OtelState.OWNS_PROVIDER, scenario: "E" });
20769
21345
  return;
20770
21346
  }
20771
21347
  if (config2.verbose) {
@@ -20787,7 +21363,29 @@ async function configureOtel(config2, sessionManager) {
20787
21363
  spanProcessors: [processor]
20788
21364
  });
20789
21365
  trace.setGlobalTracerProvider(provider);
20790
- registerShutdownHooks(provider);
21366
+ registerShutdownHook({
21367
+ name: "otel-provider-shutdown",
21368
+ priority: 0,
21369
+ fn: async () => {
21370
+ await provider.shutdown();
21371
+ }
21372
+ });
21373
+ registerSignalHandlers();
21374
+ registerBeforeExitTrigger();
21375
+ const prismaModule = await tryImport("@prisma/instrumentation");
21376
+ if (prismaModule) {
21377
+ const PrismaInstrumentation = prismaModule.PrismaInstrumentation;
21378
+ if (PrismaInstrumentation) {
21379
+ try {
21380
+ const inst = new PrismaInstrumentation();
21381
+ inst.setTracerProvider(provider);
21382
+ inst.enable();
21383
+ } catch {
21384
+ }
21385
+ }
21386
+ }
21387
+ setOtelState(OtelState.OWNS_PROVIDER);
21388
+ emitLifecycleEvent("otel:configured", { state: OtelState.OWNS_PROVIDER, scenario: "A" });
20791
21389
  }
20792
21390
 
20793
21391
  // src/context-manager.ts
@@ -20838,7 +21436,7 @@ var heartbeatGeneration = 0;
20838
21436
  var backoffAttempts = 0;
20839
21437
  var backoffUntil = 0;
20840
21438
  var tickInProgress = false;
20841
- var _shutdownHandler2 = null;
21439
+ var _shutdownHandler = null;
20842
21440
  function startHeartbeat(config2, anonKey, sdkVersion, generation, onClaimTransition) {
20843
21441
  if (heartbeatTimer !== null) return;
20844
21442
  heartbeatGeneration = generation;
@@ -20891,7 +21489,7 @@ async function heartbeatTick(config2, anonKey, sdkVersion, generation, onClaimTr
20891
21489
  backoffUntil = 0;
20892
21490
  }
20893
21491
  if (initResult?.claimResult) {
20894
- onClaimTransition(initResult.claimResult.newApiKey);
21492
+ onClaimTransition(initResult.claimResult.newApiKey, initResult.claimResult.accountId);
20895
21493
  }
20896
21494
  if (config2.verbose) {
20897
21495
  sdkLog("info", "[glasstrace] Heartbeat completed.");
@@ -20919,39 +21517,125 @@ function registerShutdownHandlers(config2, anonKey, sdkVersion) {
20919
21517
  process.kill(process.pid, signal);
20920
21518
  });
20921
21519
  };
20922
- _shutdownHandler2 = handler;
20923
- process.once("SIGTERM", _shutdownHandler2);
20924
- process.once("SIGINT", _shutdownHandler2);
21520
+ _shutdownHandler = handler;
21521
+ process.once("SIGTERM", _shutdownHandler);
21522
+ process.once("SIGINT", _shutdownHandler);
20925
21523
  }
20926
21524
  function removeShutdownHandlers() {
20927
- if (_shutdownHandler2 && typeof process !== "undefined") {
20928
- process.removeListener("SIGTERM", _shutdownHandler2);
20929
- process.removeListener("SIGINT", _shutdownHandler2);
20930
- _shutdownHandler2 = null;
21525
+ if (_shutdownHandler && typeof process !== "undefined") {
21526
+ process.removeListener("SIGTERM", _shutdownHandler);
21527
+ process.removeListener("SIGINT", _shutdownHandler);
21528
+ _shutdownHandler = null;
21529
+ }
21530
+ }
21531
+
21532
+ // src/runtime-state.ts
21533
+ init_cjs_shims();
21534
+ var import_node_fs = require("fs");
21535
+ var import_node_path = require("path");
21536
+ init_console_capture();
21537
+ var _projectRoot = null;
21538
+ var _sdkVersion = "unknown";
21539
+ var _lastScenario;
21540
+ var _debounceTimer = null;
21541
+ var _started = false;
21542
+ function startRuntimeStateWriter(options) {
21543
+ if (_started) return;
21544
+ _started = true;
21545
+ _projectRoot = options.projectRoot;
21546
+ _sdkVersion = options.sdkVersion;
21547
+ onLifecycleEvent("core:state_changed", ({ to }) => {
21548
+ if (to === CoreState.SHUTDOWN) {
21549
+ writeStateNow();
21550
+ } else {
21551
+ debouncedWrite();
21552
+ }
21553
+ });
21554
+ onLifecycleEvent("otel:configured", ({ scenario }) => {
21555
+ _lastScenario = scenario;
21556
+ debouncedWrite();
21557
+ });
21558
+ onLifecycleEvent("auth:key_resolved", () => debouncedWrite());
21559
+ onLifecycleEvent("auth:claim_started", () => debouncedWrite());
21560
+ onLifecycleEvent("auth:claim_completed", () => debouncedWrite());
21561
+ writeStateNow();
21562
+ }
21563
+ function debouncedWrite() {
21564
+ if (_debounceTimer) return;
21565
+ _debounceTimer = setTimeout(() => {
21566
+ _debounceTimer = null;
21567
+ writeStateNow();
21568
+ }, 1e3);
21569
+ if (typeof _debounceTimer === "object" && "unref" in _debounceTimer) {
21570
+ _debounceTimer.unref();
21571
+ }
21572
+ }
21573
+ function writeStateNow() {
21574
+ if (!_projectRoot) return;
21575
+ try {
21576
+ const state = getSdkState();
21577
+ const runtimeState = {
21578
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
21579
+ pid: process.pid,
21580
+ sdkVersion: _sdkVersion,
21581
+ core: { state: state.core },
21582
+ auth: { state: state.auth },
21583
+ otel: { state: state.otel, scenario: _lastScenario }
21584
+ };
21585
+ const dir = (0, import_node_path.join)(_projectRoot, ".glasstrace");
21586
+ const filePath = (0, import_node_path.join)(dir, "runtime-state.json");
21587
+ const tmpPath = (0, import_node_path.join)(dir, "runtime-state.json.tmp");
21588
+ (0, import_node_fs.mkdirSync)(dir, { recursive: true, mode: 448 });
21589
+ (0, import_node_fs.writeFileSync)(tmpPath, JSON.stringify(runtimeState, null, 2) + "\n", {
21590
+ mode: 384
21591
+ });
21592
+ (0, import_node_fs.renameSync)(tmpPath, filePath);
21593
+ } catch (err) {
21594
+ sdkLog(
21595
+ "warn",
21596
+ `[glasstrace] Failed to write runtime state: ${err instanceof Error ? err.message : String(err)}`
21597
+ );
20931
21598
  }
20932
21599
  }
20933
21600
 
20934
21601
  // src/register.ts
21602
+ function maskKey(key) {
21603
+ if (key.length <= 12) return key.slice(0, 4) + "...";
21604
+ return key.slice(0, 8) + "..." + key.slice(-4);
21605
+ }
20935
21606
  var consoleCaptureInstalled = false;
20936
21607
  var discoveryHandler = null;
20937
- var isRegistered = false;
20938
21608
  var registrationGeneration = 0;
21609
+ var _sessionManager = null;
21610
+ function getSessionManager() {
21611
+ if (!_sessionManager) {
21612
+ _sessionManager = new SessionManager();
21613
+ }
21614
+ return _sessionManager;
21615
+ }
20939
21616
  function registerGlasstrace(options) {
20940
21617
  try {
20941
- if (isRegistered) {
21618
+ if (getCoreState() !== CoreState.IDLE) {
20942
21619
  return;
20943
21620
  }
21621
+ initLifecycle({ logger: sdkLog });
20944
21622
  if (typeof process === "undefined" || typeof process.versions?.node !== "string") {
20945
21623
  console.warn(
20946
21624
  "[glasstrace] SDK requires a Node.js runtime. Edge Runtime, browser, and Deno without Node compat are not supported. Glasstrace is disabled in this environment."
20947
21625
  );
20948
21626
  return;
20949
21627
  }
21628
+ setCoreState(CoreState.REGISTERING);
21629
+ startRuntimeStateWriter({
21630
+ projectRoot: process.cwd(),
21631
+ sdkVersion: "0.14.0"
21632
+ });
20950
21633
  const config2 = resolveConfig(options);
20951
21634
  if (config2.verbose) {
20952
21635
  console.info("[glasstrace] Config resolved.");
20953
21636
  }
20954
21637
  if (isProductionDisabled(config2)) {
21638
+ setCoreState(CoreState.PRODUCTION_DISABLED);
20955
21639
  console.warn(
20956
21640
  "[glasstrace] Disabled in production. Set GLASSTRACE_FORCE_ENABLE=true to override."
20957
21641
  );
@@ -20962,8 +21646,13 @@ function registerGlasstrace(options) {
20962
21646
  }
20963
21647
  const anonymous = isAnonymousMode(config2);
20964
21648
  let effectiveKey = config2.apiKey;
21649
+ initAuthState(anonymous ? AuthState.ANONYMOUS : AuthState.AUTHENTICATED);
20965
21650
  if (effectiveKey) {
20966
21651
  setResolvedApiKey(effectiveKey);
21652
+ emitLifecycleEvent("auth:key_resolved", {
21653
+ key: maskKey(effectiveKey),
21654
+ mode: anonymous ? "anonymous" : "dev"
21655
+ });
20967
21656
  }
20968
21657
  if (config2.verbose) {
20969
21658
  console.info(
@@ -20979,11 +21668,11 @@ function registerGlasstrace(options) {
20979
21668
  `[glasstrace] Cached config ${cachedInitResponse ? "loaded and applied" : "not found"}.`
20980
21669
  );
20981
21670
  }
20982
- const sessionManager = new SessionManager();
21671
+ const sessionManager = getSessionManager();
20983
21672
  if (config2.verbose) {
20984
21673
  console.info("[glasstrace] SessionManager created.");
20985
21674
  }
20986
- isRegistered = true;
21675
+ setCoreState(CoreState.KEY_PENDING);
20987
21676
  const currentGeneration = registrationGeneration;
20988
21677
  const existingProbe = trace.getTracerProvider().getTracer("glasstrace-probe");
20989
21678
  const anotherProviderRegistered = existingProbe.constructor.name !== "ProxyTracer";
@@ -21036,6 +21725,7 @@ function registerGlasstrace(options) {
21036
21725
  resolvedAnonKey = anonKey;
21037
21726
  setResolvedApiKey(anonKey);
21038
21727
  notifyApiKeyResolved();
21728
+ emitLifecycleEvent("auth:key_resolved", { key: maskKey(anonKey), mode: "anonymous" });
21039
21729
  effectiveKey = anonKey;
21040
21730
  if (currentGeneration !== registrationGeneration) return;
21041
21731
  discoveryHandler = createDiscoveryHandler(
@@ -21057,6 +21747,7 @@ function registerGlasstrace(options) {
21057
21747
  const anonKey = await getOrCreateAnonKey();
21058
21748
  setResolvedApiKey(anonKey);
21059
21749
  notifyApiKeyResolved();
21750
+ emitLifecycleEvent("auth:key_resolved", { key: maskKey(anonKey), mode: "anonymous" });
21060
21751
  effectiveKey = anonKey;
21061
21752
  if (currentGeneration !== registrationGeneration) return;
21062
21753
  await backgroundInit(config2, anonKey, currentGeneration);
@@ -21089,6 +21780,7 @@ function registerGlasstrace(options) {
21089
21780
  console.info("[glasstrace] Import graph building skipped.");
21090
21781
  }
21091
21782
  } catch (err) {
21783
+ setCoreState(CoreState.REGISTRATION_FAILED);
21092
21784
  console.warn(
21093
21785
  `[glasstrace] Registration failed: ${err instanceof Error ? err.message : String(err)}`
21094
21786
  );
@@ -21098,18 +21790,37 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
21098
21790
  if (config2.verbose) {
21099
21791
  console.info("[glasstrace] Background init firing.");
21100
21792
  }
21101
- const healthReport = collectHealthReport("0.13.6");
21102
- const initResult = await performInit(config2, anonKeyForInit, "0.13.6", healthReport);
21793
+ const healthReport = collectHealthReport("0.14.0");
21794
+ const initResult = await performInit(config2, anonKeyForInit, "0.14.0", healthReport);
21103
21795
  if (generation !== registrationGeneration) return;
21796
+ const currentState = getCoreState();
21797
+ if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
21798
+ return;
21799
+ }
21800
+ if (currentState === CoreState.KEY_PENDING) {
21801
+ setCoreState(CoreState.KEY_RESOLVED);
21802
+ }
21803
+ if (getCoreState() === CoreState.KEY_RESOLVED) {
21804
+ setCoreState(didLastInitSucceed() ? CoreState.ACTIVE : CoreState.ACTIVE_DEGRADED);
21805
+ }
21104
21806
  if (initResult?.claimResult) {
21105
- setResolvedApiKey(initResult.claimResult.newApiKey);
21807
+ const { newApiKey, accountId } = initResult.claimResult;
21808
+ setAuthState(AuthState.CLAIMING);
21809
+ emitLifecycleEvent("auth:claim_started", { accountId });
21810
+ setResolvedApiKey(newApiKey);
21106
21811
  notifyApiKeyResolved();
21812
+ setAuthState(AuthState.CLAIMED);
21813
+ emitLifecycleEvent("auth:claim_completed", { newKey: maskKey(newApiKey), accountId });
21107
21814
  }
21108
21815
  maybeInstallConsoleCapture();
21109
21816
  if (didLastInitSucceed()) {
21110
- startHeartbeat(config2, anonKeyForInit, "0.13.6", generation, (newApiKey) => {
21817
+ startHeartbeat(config2, anonKeyForInit, "0.14.0", generation, (newApiKey, accountId) => {
21818
+ setAuthState(AuthState.CLAIMING);
21819
+ emitLifecycleEvent("auth:claim_started", { accountId });
21111
21820
  setResolvedApiKey(newApiKey);
21112
21821
  notifyApiKeyResolved();
21822
+ setAuthState(AuthState.CLAIMED);
21823
+ emitLifecycleEvent("auth:claim_completed", { newKey: maskKey(newApiKey), accountId });
21113
21824
  });
21114
21825
  }
21115
21826
  }
@@ -21407,6 +22118,7 @@ async function buildImportGraph(projectRoot) {
21407
22118
  collectSourceMaps,
21408
22119
  computeBuildHash,
21409
22120
  createDiscoveryHandler,
22121
+ createGlasstraceSpanProcessor,
21410
22122
  deriveSessionId,
21411
22123
  discoverSourceMapFiles,
21412
22124
  discoverTestFiles,
@@ -21417,8 +22129,10 @@ async function buildImportGraph(projectRoot) {
21417
22129
  getLinkedAccountId,
21418
22130
  getOrCreateAnonKey,
21419
22131
  getOrigin,
22132
+ getStatus,
21420
22133
  isAnonymousMode,
21421
22134
  isProductionDisabled,
22135
+ isReady,
21422
22136
  loadCachedConfig,
21423
22137
  performInit,
21424
22138
  readAnonKey,
@@ -21430,6 +22144,7 @@ async function buildImportGraph(projectRoot) {
21430
22144
  uploadSourceMaps,
21431
22145
  uploadSourceMapsAuto,
21432
22146
  uploadSourceMapsPresigned,
22147
+ waitForReady,
21433
22148
  withGlasstraceConfig
21434
22149
  });
21435
22150
  //# sourceMappingURL=index.cjs.map