@autter/runtime-node 1.5.0 → 1.6.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.
@@ -1,7 +1,7 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;
2
2
 
3
3
 
4
- var _chunkGI47WGRRcjs = require('./chunk-GI47WGRR.cjs');
4
+ var _chunkARN26OK6cjs = require('./chunk-ARN26OK6.cjs');
5
5
 
6
6
  // ../runtime-core/dist/index.js
7
7
  var SENSITIVE_KEY_PATTERNS = [
@@ -327,8 +327,8 @@ function priority(key) {
327
327
  if (/^(?:exception|autter\.error)\./.test(key)) return 1;
328
328
  return 0;
329
329
  }
330
- function boundContext(attributes = {}, redact2) {
331
- const redacted = redact2 ? redact2(attributes) : redactAttributes(attributes);
330
+ function boundContext(attributes = {}, redact3) {
331
+ const redacted = redact3 ? redact3(attributes) : redactAttributes(attributes);
332
332
  let budget = 512;
333
333
  let characters = 16384;
334
334
  let truncated = false;
@@ -365,14 +365,14 @@ function boundContext(attributes = {}, redact2) {
365
365
  if (truncated) result["autter.context.truncated"] = true;
366
366
  return result;
367
367
  }
368
- function userContext(attributes = {}, redact2) {
368
+ function userContext(attributes = {}, redact3) {
369
369
  return Object.fromEntries(
370
- Object.entries(boundContext(attributes, redact2)).filter(
370
+ Object.entries(boundContext(attributes, redact3)).filter(
371
371
  ([key]) => !RESERVED_KEY.test(key)
372
372
  )
373
373
  );
374
374
  }
375
- function mergeContext(current, next = {}, redact2) {
375
+ function mergeContext(current, next = {}, redact3) {
376
376
  const merge2 = (left, right, depth) => {
377
377
  const result = { ...left };
378
378
  for (const [key, value] of Object.entries(right)) {
@@ -381,7 +381,7 @@ function mergeContext(current, next = {}, redact2) {
381
381
  }
382
382
  return result;
383
383
  };
384
- return userContext(merge2(current, userContext(next, redact2), 0), redact2);
384
+ return userContext(merge2(current, userContext(next, redact3), 0), redact3);
385
385
  }
386
386
  function toSpanAttributes(context) {
387
387
  return Object.fromEntries(
@@ -473,6 +473,17 @@ function defineRuntimeErrors(namespace, catalog) {
473
473
  }
474
474
  return out;
475
475
  }
476
+ function isError(value) {
477
+ if (!value || typeof value !== "object") return false;
478
+ try {
479
+ if (value instanceof Error) return true;
480
+ const native = Error.isError;
481
+ if (typeof native === "function") return native(value) === true;
482
+ return Object.prototype.toString.call(value) === "[object Error]";
483
+ } catch (e10) {
484
+ return false;
485
+ }
486
+ }
476
487
  function isRuntimeErrorLike(err) {
477
488
  if (err instanceof RuntimeError) return true;
478
489
  if (!err || typeof err !== "object") return false;
@@ -483,7 +494,7 @@ function field(err, key) {
483
494
  if (!err || typeof err !== "object") return void 0;
484
495
  try {
485
496
  return err[key];
486
- } catch (e10) {
497
+ } catch (e11) {
487
498
  return void 0;
488
499
  }
489
500
  }
@@ -523,15 +534,15 @@ function errorAttributes(err, options = {}) {
523
534
  for (let n = 1; n <= CAUSE_DEPTH && cause !== void 0 && cause !== null; n++) {
524
535
  if (seen.has(cause)) break;
525
536
  seen.add(cause);
526
- const isError = typeof cause === "object";
527
- const type = isError ? String(_nullishCoalesce(_nullishCoalesce(field(cause, "name"), () => ( _optionalChain([cause, 'access', _10 => _10.constructor, 'optionalAccess', _11 => _11.name]))), () => ( "Error"))) : typeof cause;
528
- const message = isError ? field(cause, "message") : cause;
537
+ const isError2 = typeof cause === "object";
538
+ const type = isError2 ? String(_nullishCoalesce(_nullishCoalesce(field(cause, "name"), () => ( _optionalChain([cause, 'access', _10 => _10.constructor, 'optionalAccess', _11 => _11.name]))), () => ( "Error"))) : typeof cause;
539
+ const message = isError2 ? field(cause, "message") : cause;
529
540
  out[`exception.cause.${n}.type`] = type.slice(0, 200);
530
541
  out[`exception.cause.${n}.message`] = String(_nullishCoalesce(message, () => ( ""))).slice(0, 1e3);
531
542
  const causeCode = field(cause, "code");
532
543
  if (typeof causeCode === "string" && causeCode)
533
544
  out[`exception.cause.${n}.code`] = causeCode.slice(0, CODE_MAX_LENGTH);
534
- cause = isError ? field(cause, "cause") : void 0;
545
+ cause = isError2 ? field(cause, "cause") : void 0;
535
546
  }
536
547
  }
537
548
  return out;
@@ -577,19 +588,19 @@ function createInlineLogState(startedAt) {
577
588
  level: "info"
578
589
  };
579
590
  }
580
- function appendInlineLog(state, level, message, attrs, redact2, now = Date.now()) {
591
+ function appendInlineLog(state, level, message, attrs, redact3, now = Date.now()) {
581
592
  state.level = maxLevel(state.level, level);
582
593
  if (state.logs.length >= INLINE_LOG_LIMIT) {
583
594
  state.logsTruncated = true;
584
595
  return;
585
596
  }
586
- const text = String(_nullishCoalesce(boundContext({ message }, redact2).message, () => ( ""))).slice(
597
+ const text = String(_nullishCoalesce(boundContext({ message }, redact3).message, () => ( ""))).slice(
587
598
  0,
588
599
  INLINE_MESSAGE_MAX
589
600
  );
590
601
  let small;
591
602
  if (attrs && Object.keys(attrs).length) {
592
- small = boundContext(attrs, redact2);
603
+ small = boundContext(attrs, redact3);
593
604
  const encoded = JSON.stringify(small);
594
605
  if (encoded.length > 1e3) small = { "autter.context.truncated": true };
595
606
  }
@@ -779,7 +790,7 @@ function parseCarrier(input) {
779
790
  if (value.length > 1024) return null;
780
791
  try {
781
792
  value = JSON.parse(value);
782
- } catch (e11) {
793
+ } catch (e12) {
783
794
  return null;
784
795
  }
785
796
  }
@@ -806,6 +817,172 @@ function parseUserAgent(ua) {
806
817
  const device = !value ? "unknown" : bot ? "bot" : /iPad|Tablet/.test(value) || /Android/.test(value) && !/Mobile/.test(value) ? "tablet" : /Mobi|iPhone|iPod|Android/.test(value) ? "mobile" : "desktop";
807
818
  return { browser, os, device, bot };
808
819
  }
820
+ var BREADCRUMBS_ATTRIBUTE = "autter.breadcrumbs";
821
+ var MAX_BREADCRUMBS = 30;
822
+ var MAX_MESSAGE = 500;
823
+ var MAX_DATA_KEYS = 10;
824
+ var MAX_DATA_STRING = 200;
825
+ var BREADCRUMBS_ATTRIBUTE_MAX_CHARS = 16 * 1024;
826
+ var MASK = "[redacted]";
827
+ var TYPES = /* @__PURE__ */ new Set(["console", "request", "navigation", "click", "log", "custom"]);
828
+ var LEVELS = {
829
+ debug: "debug",
830
+ trace: "debug",
831
+ info: "info",
832
+ log: "info",
833
+ warning: "warning",
834
+ warn: "warning",
835
+ error: "error",
836
+ fatal: "error"
837
+ };
838
+ var UNSAFE_KEY = /^(?:__proto__|constructor|prototype)$/;
839
+ function scrubber(redact3) {
840
+ return (value, max) => {
841
+ const scrubbed = redact3({ message: value.slice(0, max + 512) }).message;
842
+ return stripUrlQueries(typeof scrubbed === "string" ? scrubbed : "").slice(0, max);
843
+ };
844
+ }
845
+ function cleanData(raw, redact3) {
846
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
847
+ const picked = {};
848
+ let count = 0;
849
+ for (const key of Object.keys(raw).slice(0, 64)) {
850
+ if (count >= MAX_DATA_KEYS) break;
851
+ if (!key || UNSAFE_KEY.test(key)) continue;
852
+ const value = raw[key];
853
+ const name = key.slice(0, 100);
854
+ if (typeof value === "string") {
855
+ const text = /(?:url|path|route|target)$/i.test(name) ? value.split(/[?#]/)[0] : value;
856
+ picked[name] = text.slice(0, MAX_DATA_STRING + 512);
857
+ } else if (typeof value === "number") {
858
+ if (!Number.isFinite(value)) continue;
859
+ picked[name] = value;
860
+ } else if (typeof value === "boolean" || value === null) {
861
+ picked[name] = value;
862
+ } else {
863
+ continue;
864
+ }
865
+ count++;
866
+ }
867
+ if (count === 0) return void 0;
868
+ const redacted = redact3(picked);
869
+ const out = {};
870
+ for (const key of Object.keys(picked)) {
871
+ const value = key in redacted ? redacted[key] : picked[key];
872
+ out[key] = typeof value === "string" ? stripUrlQueries(value).slice(0, MAX_DATA_STRING) : value;
873
+ }
874
+ return out;
875
+ }
876
+ function timestamp(value) {
877
+ if (value === void 0) return (/* @__PURE__ */ new Date()).toISOString();
878
+ if (typeof value !== "string" && typeof value !== "number" && !(value instanceof Date)) return null;
879
+ const at = new Date(value);
880
+ return Number.isNaN(at.getTime()) ? null : at.toISOString();
881
+ }
882
+ function normalizeBreadcrumb(input, redact3, options = {}) {
883
+ try {
884
+ if (!input || typeof input !== "object" || Array.isArray(input)) return null;
885
+ const raw = input;
886
+ if (options.requireAt && raw.at === void 0) return null;
887
+ const at = timestamp(raw.at);
888
+ if (!at) return null;
889
+ const rawMessage = raw.message;
890
+ const message = typeof rawMessage === "string" ? rawMessage : typeof rawMessage === "number" || typeof rawMessage === "boolean" ? String(rawMessage) : "";
891
+ const data = cleanData(raw.data, redact3);
892
+ if (!message && !data) return null;
893
+ const type = typeof raw.type === "string" && TYPES.has(raw.type) ? raw.type : "custom";
894
+ const level = typeof raw.level === "string" ? LEVELS[raw.level.toLowerCase()] : void 0;
895
+ return {
896
+ type,
897
+ at,
898
+ ...level ? { level } : {},
899
+ message: scrubber(redact3)(message, MAX_MESSAGE),
900
+ ...data ? { data } : {}
901
+ };
902
+ } catch (e13) {
903
+ return null;
904
+ }
905
+ }
906
+ function sanitizeBreadcrumbs(raw, redact3) {
907
+ const out = [];
908
+ try {
909
+ if (!Array.isArray(raw)) return void 0;
910
+ const first = Math.max(0, raw.length - 200);
911
+ for (let i = raw.length - 1; i >= first && out.length < MAX_BREADCRUMBS; i--) {
912
+ const crumb = normalizeBreadcrumb(raw[i], redact3, { requireAt: true });
913
+ if (crumb) out.push(crumb);
914
+ }
915
+ } catch (e14) {
916
+ }
917
+ return out.length ? out.reverse() : void 0;
918
+ }
919
+ var BreadcrumbTrail = (_class = class {
920
+ constructor(max = MAX_BREADCRUMBS) {;_class.prototype.__init.call(this);
921
+ this.max = max;
922
+ }
923
+
924
+ __init() {this.items = []}
925
+ add(crumb) {
926
+ this.items.push(crumb);
927
+ if (this.items.length > this.max) this.items.splice(0, this.items.length - this.max);
928
+ }
929
+ /** Copies, oldest first. */
930
+ list() {
931
+ return this.items.map((crumb) => ({ ...crumb, ...crumb.data ? { data: { ...crumb.data } } : {} }));
932
+ }
933
+ get size() {
934
+ return this.items.length;
935
+ }
936
+ clear() {
937
+ this.items = [];
938
+ }
939
+ }, _class);
940
+ function breadcrumbsAttribute(list, scrub, maxChars = BREADCRUMBS_ATTRIBUTE_MAX_CHARS) {
941
+ const parts = [];
942
+ let chars = 2;
943
+ for (let i = list.length - 1; i >= 0 && parts.length < MAX_BREADCRUMBS; i--) {
944
+ const crumb = list[i];
945
+ let json = JSON.stringify(crumb);
946
+ if (scrub(json) !== json) {
947
+ json = JSON.stringify({ type: crumb.type, at: crumb.at, ...crumb.level ? { level: crumb.level } : {}, message: MASK });
948
+ }
949
+ if (chars + json.length + 1 > maxChars) break;
950
+ chars += json.length + 1;
951
+ parts.push(json);
952
+ }
953
+ if (parts.length === 0) return void 0;
954
+ const out = `[${parts.reverse().join(",")}]`;
955
+ return scrub(out) === out ? out : void 0;
956
+ }
957
+ var FINGERPRINT_ATTRIBUTE = "autter.fingerprint";
958
+ var FINGERPRINT_MAX_VALUES = 10;
959
+ var FINGERPRINT_MAX_LENGTH = 200;
960
+ function fingerprintValues(value, scrub = (text) => text) {
961
+ const list = Array.isArray(value) ? value : [value];
962
+ const values = list.filter((item) => typeof item === "string" && item !== "").slice(0, FINGERPRINT_MAX_VALUES).map((item) => scrub(item.slice(0, FINGERPRINT_MAX_LENGTH + 512)).slice(0, FINGERPRINT_MAX_LENGTH)).filter((item) => item !== "");
963
+ return values.length > 0 ? values : void 0;
964
+ }
965
+ function fingerprintEventAttributes(value, scrub) {
966
+ const values = fingerprintValues(value, scrub);
967
+ return values ? { [FINGERPRINT_ATTRIBUTE]: JSON.stringify(values) } : {};
968
+ }
969
+ function splitFingerprint(attributes) {
970
+ if (!attributes || typeof attributes !== "object" || !("fingerprint" in attributes)) {
971
+ return { attributes: _nullishCoalesce(attributes, () => ( void 0)), fingerprint: void 0 };
972
+ }
973
+ const { fingerprint, ...rest } = attributes;
974
+ return { attributes: rest, fingerprint };
975
+ }
976
+
977
+ // src/breadcrumbs.ts
978
+ var _api = require('@opentelemetry/api');
979
+
980
+ // src/logger.ts
981
+ var _async_hooks = require('async_hooks');
982
+ var _crypto = require('crypto');
983
+
984
+
985
+
809
986
 
810
987
  // src/sinks.ts
811
988
 
@@ -892,7 +1069,7 @@ function otlpSink(options = {}) {
892
1069
  Math.max(1, Math.min(3e3, deadline - Date.now()))
893
1070
  )
894
1071
  });
895
- _chunkGI47WGRRcjs.observeIngesterResponse.call(void 0, { status: response.status, headers: response.headers, route: "/v1/logs" });
1072
+ _chunkARN26OK6cjs.observeIngesterResponse.call(void 0, { status: response.status, headers: response.headers, route: "/v1/logs" });
896
1073
  if (!response.ok)
897
1074
  throw new Error(`Runtime log export failed (${response.status})`);
898
1075
  failure = void 0;
@@ -942,7 +1119,7 @@ function otlpSink(options = {}) {
942
1119
  }
943
1120
  queue.push({ record, bytes });
944
1121
  queueBytes += bytes;
945
- _chunkGI47WGRRcjs.noteCompatFeature.call(void 0, "operation_logging");
1122
+ _chunkARN26OK6cjs.noteCompatFeature.call(void 0, "operation_logging");
946
1123
  scheduleFlush();
947
1124
  },
948
1125
  flush,
@@ -1115,7 +1292,7 @@ function fileSink(options = {}) {
1115
1292
  index = sameDay.length ? sameDay[sameDay.length - 1].index : 0;
1116
1293
  try {
1117
1294
  currentBytes = _fs.statSync.call(void 0, _path.join.call(void 0, dir, fileName(day, index))).size;
1118
- } catch (e12) {
1295
+ } catch (e15) {
1119
1296
  currentBytes = 0;
1120
1297
  }
1121
1298
  prune();
@@ -1185,11 +1362,6 @@ function memorySink() {
1185
1362
  }
1186
1363
 
1187
1364
  // src/logger.ts
1188
- var _async_hooks = require('async_hooks');
1189
- var _crypto = require('crypto');
1190
-
1191
-
1192
- var _api = require('@opentelemetry/api');
1193
1365
  var local = new (0, _async_hooks.AsyncLocalStorage)();
1194
1366
  var config = null;
1195
1367
  var sinks = [];
@@ -1237,6 +1409,7 @@ function emit(level, message, attributes, extra = {}, options = {}) {
1237
1409
  const state = options.state !== void 0 ? _nullishCoalesce(options.state, () => ( void 0)) : local.getStore();
1238
1410
  if (_optionalChain([state, 'optionalAccess', _18 => _18.sealed])) return;
1239
1411
  const summary = extra["autter.event.type"] === "operation";
1412
+ if (!summary) recordLogBreadcrumb(level, message, attributes, state);
1240
1413
  if (!summary && LEVEL_SEVERITY[level] < LEVEL_SEVERITY[_nullishCoalesce(_optionalChain([config, 'optionalAccess', _19 => _19.options, 'optionalAccess', _20 => _20.minLevel]), () => ( "debug"))])
1241
1414
  return;
1242
1415
  if (!summary && state && _optionalChain([config, 'optionalAccess', _21 => _21.options, 'optionalAccess', _22 => _22.inline]) !== false) {
@@ -1269,7 +1442,7 @@ function emit(level, message, attributes, extra = {}, options = {}) {
1269
1442
  res: state.res,
1270
1443
  operation: { id: state.id, name: state.name, kind: state.kind }
1271
1444
  });
1272
- } catch (e13) {
1445
+ } catch (e16) {
1273
1446
  }
1274
1447
  }
1275
1448
  }
@@ -1282,7 +1455,7 @@ function emit(level, message, attributes, extra = {}, options = {}) {
1282
1455
  for (const sink of activeSinks()) {
1283
1456
  try {
1284
1457
  sink.write(event);
1285
- } catch (e14) {
1458
+ } catch (e17) {
1286
1459
  }
1287
1460
  }
1288
1461
  }
@@ -1299,10 +1472,13 @@ function configureRuntimeLogger(next) {
1299
1472
  ...next.release ? { release: next.release } : {},
1300
1473
  ...next.distro ? { distro: next.distro } : {}
1301
1474
  })]);
1302
- } catch (e15) {
1475
+ } catch (e18) {
1303
1476
  }
1304
1477
  }
1305
1478
  }
1479
+ function loggerConfigured() {
1480
+ return config;
1481
+ }
1306
1482
  function addRuntimeSink(sink) {
1307
1483
  extraSinks.add(sink);
1308
1484
  return () => extraSinks.delete(sink);
@@ -1313,8 +1489,8 @@ function notifyException(error, attributes = {}) {
1313
1489
  const record = {
1314
1490
  time: Date.now(),
1315
1491
  error,
1316
- message: error instanceof Error ? error.message : String(error),
1317
- type: error instanceof Error ? error.name : "Error",
1492
+ message: isError(error) ? error.message : String(error),
1493
+ type: isError(error) ? error.name : "Error",
1318
1494
  attributes: { ...attributes, ...errorAttributes(error) },
1319
1495
  ...state ? { operationId: state.id } : {},
1320
1496
  ..._optionalChain([state, 'optionalAccess', _33 => _33.requestId]) ? { requestId: state.requestId } : {}
@@ -1322,7 +1498,7 @@ function notifyException(error, attributes = {}) {
1322
1498
  for (const sink of [...sinks, ...extraSinks]) {
1323
1499
  try {
1324
1500
  _optionalChain([sink, 'access', _34 => _34.exception, 'optionalCall', _35 => _35(record)]);
1325
- } catch (e16) {
1501
+ } catch (e19) {
1326
1502
  }
1327
1503
  }
1328
1504
  }
@@ -1367,11 +1543,11 @@ function createRuntimeLogger(attributes = {}) {
1367
1543
  warn: (message, extra) => emit("warning", message, merge(attrs, extra)),
1368
1544
  error: (error, extra) => emit(
1369
1545
  "error",
1370
- error instanceof Error ? error.message : String(error),
1546
+ isError(error) ? error.message : String(error),
1371
1547
  {
1372
1548
  ...attrs,
1373
1549
  ...extra,
1374
- ...error instanceof Error ? {
1550
+ ...isError(error) ? {
1375
1551
  "exception.type": error.name,
1376
1552
  "exception.stacktrace": _nullishCoalesce(error.stack, () => ( ""))
1377
1553
  } : {}
@@ -1382,16 +1558,16 @@ function createRuntimeLogger(attributes = {}) {
1382
1558
  }
1383
1559
  var runtimeLogger = createRuntimeLogger();
1384
1560
  function captureExceptionAsLog(error, attributes = {}) {
1385
- const isError = error instanceof Error;
1386
- const message = isError ? error.message : String(error);
1387
- const stack = isError && error.stack ? error.stack : _nullishCoalesce(_optionalChain([new Error(), 'access', _42 => _42.stack, 'optionalAccess', _43 => _43.split, 'call', _44 => _44("\n"), 'access', _45 => _45.filter, 'call', _46 => _46((line, i) => i === 0 || !/captureException/.test(line)), 'access', _47 => _47.join, 'call', _48 => _48("\n")]), () => ( ""));
1561
+ const isErr = isError(error);
1562
+ const message = isErr ? error.message : String(error);
1563
+ const stack = isErr && error.stack ? error.stack : _nullishCoalesce(_optionalChain([new Error(), 'access', _42 => _42.stack, 'optionalAccess', _43 => _43.split, 'call', _44 => _44("\n"), 'access', _45 => _45.filter, 'call', _46 => _46((line, i) => i === 0 || !/captureException/.test(line)), 'access', _47 => _47.join, 'call', _48 => _48("\n")]), () => ( ""));
1388
1564
  noteOperationError(error);
1389
1565
  emit(
1390
1566
  "error",
1391
1567
  message,
1392
1568
  {
1393
1569
  ...attributes,
1394
- "exception.type": isError ? error.name : "Error",
1570
+ "exception.type": isErr ? error.name : "Error",
1395
1571
  "exception.message": message,
1396
1572
  "exception.stacktrace": stack
1397
1573
  },
@@ -1486,7 +1662,7 @@ function emitSummary(state, options = {}) {
1486
1662
  _nullishCoalesce(state.message, () => ( `${state.name}: ${state.outcome}`)),
1487
1663
  {
1488
1664
  ...operationAttributes(state),
1489
- ...err instanceof Error ? {
1665
+ ...isError(err) ? {
1490
1666
  "exception.type": err.name,
1491
1667
  "exception.stacktrace": _nullishCoalesce(err.stack, () => ( ""))
1492
1668
  } : {}
@@ -1521,6 +1697,7 @@ function startOperation(name, fn, attributes, options, internal = {}) {
1521
1697
  ..._optionalChain([parent, 'optionalAccess', _56 => _56.requestId]) ? { requestId: parent.requestId } : {}
1522
1698
  }
1523
1699
  );
1700
+ if (linked && parent) state.breadcrumbs = parent.breadcrumbs ??= new BreadcrumbTrail();
1524
1701
  const operation = operationHandle(state);
1525
1702
  const run = () => local.run(state, async () => {
1526
1703
  let thrown;
@@ -1530,6 +1707,7 @@ function startOperation(name, fn, attributes, options, internal = {}) {
1530
1707
  state.outcome = "failed";
1531
1708
  thrown = error;
1532
1709
  noteOperationError(error, true, state);
1710
+ rememberThrownBreadcrumbs(error, state);
1533
1711
  _optionalChain([config, 'optionalAccess', _57 => _57.captureThrown, 'optionalCall', _58 => _58(error)]);
1534
1712
  throw error;
1535
1713
  } finally {
@@ -1567,7 +1745,7 @@ function startOperation(name, fn, attributes, options, internal = {}) {
1567
1745
  try {
1568
1746
  waitUntil(flushRuntimeLogs().catch(() => {
1569
1747
  }));
1570
- } catch (e17) {
1748
+ } catch (e20) {
1571
1749
  }
1572
1750
  });
1573
1751
  }
@@ -1634,6 +1812,90 @@ var runtimeContext = {
1634
1812
  }
1635
1813
  };
1636
1814
 
1815
+ // src/breadcrumbs.ts
1816
+ var INVALID_TRACE_ID = "00000000000000000000000000000000";
1817
+ var MAX_TRACE_TRAILS = 200;
1818
+ var byTrace = /* @__PURE__ */ new Map();
1819
+ var processTrail = new BreadcrumbTrail();
1820
+ var thrownTrails = /* @__PURE__ */ new WeakMap();
1821
+ function redact2(attributes) {
1822
+ return _nullishCoalesce(_optionalChain([loggerConfigured, 'call', _80 => _80(), 'optionalAccess', _81 => _81.redact, 'call', _82 => _82(attributes)]), () => ( redactAttributes(attributes)));
1823
+ }
1824
+ function trailFor(create, state = local.getStore()) {
1825
+ if (state) {
1826
+ if (!state.breadcrumbs && create) state.breadcrumbs = new BreadcrumbTrail();
1827
+ return state.breadcrumbs;
1828
+ }
1829
+ const traceId = _optionalChain([_api.trace, 'access', _83 => _83.getActiveSpan, 'call', _84 => _84(), 'optionalAccess', _85 => _85.spanContext, 'call', _86 => _86(), 'access', _87 => _87.traceId]);
1830
+ if (traceId && traceId !== INVALID_TRACE_ID) {
1831
+ let trail = byTrace.get(traceId);
1832
+ if (!trail && create) {
1833
+ trail = new BreadcrumbTrail();
1834
+ byTrace.set(traceId, trail);
1835
+ if (byTrace.size > MAX_TRACE_TRAILS) {
1836
+ const oldest = byTrace.keys().next().value;
1837
+ if (oldest !== void 0) byTrace.delete(oldest);
1838
+ }
1839
+ }
1840
+ return trail;
1841
+ }
1842
+ return processTrail;
1843
+ }
1844
+ function addBreadcrumb(input) {
1845
+ try {
1846
+ const crumb = normalizeBreadcrumb(input, redact2);
1847
+ if (!crumb) return;
1848
+ _optionalChain([trailFor, 'call', _88 => _88(true), 'optionalAccess', _89 => _89.add, 'call', _90 => _90(crumb)]);
1849
+ _chunkARN26OK6cjs.noteCompatFeature.call(void 0, "breadcrumbs");
1850
+ } catch (e21) {
1851
+ }
1852
+ }
1853
+ function recordLogBreadcrumb(level, message, attributes, state) {
1854
+ try {
1855
+ const data = {};
1856
+ let count = 0;
1857
+ for (const [key, value] of Object.entries(attributes)) {
1858
+ if (count >= 10) break;
1859
+ if (/^(?:exception|autter)\./.test(key)) continue;
1860
+ if (value === null || ["string", "number", "boolean"].includes(typeof value)) {
1861
+ data[key] = value;
1862
+ count++;
1863
+ }
1864
+ }
1865
+ const crumb = normalizeBreadcrumb({ type: "log", level, message, data }, redact2);
1866
+ if (crumb) _optionalChain([trailFor, 'call', _91 => _91(true, state), 'optionalAccess', _92 => _92.add, 'call', _93 => _93(crumb)]);
1867
+ } catch (e22) {
1868
+ }
1869
+ }
1870
+ function attributeBudget() {
1871
+ const limit = Number(
1872
+ _nullishCoalesce(process.env.OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, () => ( process.env.OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT))
1873
+ );
1874
+ return Number.isFinite(limit) && limit > 0 ? Math.min(BREADCRUMBS_ATTRIBUTE_MAX_CHARS, limit) : BREADCRUMBS_ATTRIBUTE_MAX_CHARS;
1875
+ }
1876
+ function rememberThrownBreadcrumbs(error, state) {
1877
+ if (state.breadcrumbs && error !== null && (typeof error === "object" || typeof error === "function"))
1878
+ thrownTrails.set(error, state.breadcrumbs);
1879
+ }
1880
+ function breadcrumbEventAttributes(scrub, error) {
1881
+ try {
1882
+ const thrown = error !== null && typeof error === "object" ? thrownTrails.get(error) : void 0;
1883
+ const trail = _nullishCoalesce(thrown, () => ( trailFor(false)));
1884
+ if (!_optionalChain([trail, 'optionalAccess', _94 => _94.size])) return {};
1885
+ const json = breadcrumbsAttribute(trail.list(), scrub, attributeBudget());
1886
+ return json ? { [BREADCRUMBS_ATTRIBUTE]: json } : {};
1887
+ } catch (e23) {
1888
+ return {};
1889
+ }
1890
+ }
1891
+
1892
+
1893
+
1894
+
1895
+
1896
+
1897
+
1898
+
1637
1899
 
1638
1900
 
1639
1901
 
@@ -1677,4 +1939,4 @@ var runtimeContext = {
1677
1939
 
1678
1940
 
1679
1941
 
1680
- exports.redactAttributes = redactAttributes; exports.redactText = redactText; exports.makeRedactor = makeRedactor; exports.CODE_PATTERN = CODE_PATTERN; exports.RuntimeError = RuntimeError; exports.defineRuntimeErrors = defineRuntimeErrors; exports.isRuntimeErrorLike = isRuntimeErrorLike; exports.errorCodeOf = errorCodeOf; exports.errorAttributes = errorAttributes; exports.errorInternal = errorInternal; exports.toClientError = toClientError; exports.responseStatusOf = responseStatusOf; exports.isSummary = isSummary; exports.DEFAULT_REQUEST_ID_HEADER = DEFAULT_REQUEST_ID_HEADER; exports.resolveRequestId = resolveRequestId; exports.normalizeRoutePath = normalizeRoutePath; exports.compileIgnore = compileIgnore; exports.requestOutcome = requestOutcome; exports.parseUserAgent = parseUserAgent; exports.otlpSink = otlpSink; exports.consoleSink = consoleSink; exports.fileSink = fileSink; exports.memorySink = memorySink; exports.local = local; exports.currentOperation = currentOperation; exports.configureRuntimeLogger = configureRuntimeLogger; exports.addRuntimeSink = addRuntimeSink; exports.notifyException = notifyException; exports.runtimeLogStats = runtimeLogStats; exports.flushRuntimeLogs = flushRuntimeLogs; exports.shutdownRuntimeLogger = shutdownRuntimeLogger; exports.noteOperationError = noteOperationError; exports.recordOperationAiUsage = recordOperationAiUsage; exports.createRuntimeLogger = createRuntimeLogger; exports.runtimeLogger = runtimeLogger; exports.captureExceptionAsLog = captureExceptionAsLog; exports.createRequestState = createRequestState; exports.emitSummary = emitSummary; exports.reportExplicitFailure = reportExplicitFailure; exports.withRuntimeOperation = withRuntimeOperation; exports.runInBackground = runInBackground; exports.runtimeContext = runtimeContext;
1942
+ exports.redactAttributes = redactAttributes; exports.redactText = redactText; exports.makeRedactor = makeRedactor; exports.CODE_PATTERN = CODE_PATTERN; exports.RuntimeError = RuntimeError; exports.defineRuntimeErrors = defineRuntimeErrors; exports.isError = isError; exports.isRuntimeErrorLike = isRuntimeErrorLike; exports.errorCodeOf = errorCodeOf; exports.errorAttributes = errorAttributes; exports.errorInternal = errorInternal; exports.toClientError = toClientError; exports.responseStatusOf = responseStatusOf; exports.isSummary = isSummary; exports.DEFAULT_REQUEST_ID_HEADER = DEFAULT_REQUEST_ID_HEADER; exports.resolveRequestId = resolveRequestId; exports.normalizeRoutePath = normalizeRoutePath; exports.compileIgnore = compileIgnore; exports.requestOutcome = requestOutcome; exports.parseUserAgent = parseUserAgent; exports.sanitizeBreadcrumbs = sanitizeBreadcrumbs; exports.fingerprintValues = fingerprintValues; exports.fingerprintEventAttributes = fingerprintEventAttributes; exports.splitFingerprint = splitFingerprint; exports.addBreadcrumb = addBreadcrumb; exports.breadcrumbEventAttributes = breadcrumbEventAttributes; exports.otlpSink = otlpSink; exports.consoleSink = consoleSink; exports.fileSink = fileSink; exports.memorySink = memorySink; exports.local = local; exports.currentOperation = currentOperation; exports.configureRuntimeLogger = configureRuntimeLogger; exports.addRuntimeSink = addRuntimeSink; exports.notifyException = notifyException; exports.runtimeLogStats = runtimeLogStats; exports.flushRuntimeLogs = flushRuntimeLogs; exports.shutdownRuntimeLogger = shutdownRuntimeLogger; exports.noteOperationError = noteOperationError; exports.recordOperationAiUsage = recordOperationAiUsage; exports.createRuntimeLogger = createRuntimeLogger; exports.runtimeLogger = runtimeLogger; exports.captureExceptionAsLog = captureExceptionAsLog; exports.createRequestState = createRequestState; exports.emitSummary = emitSummary; exports.reportExplicitFailure = reportExplicitFailure; exports.withRuntimeOperation = withRuntimeOperation; exports.runInBackground = runInBackground; exports.runtimeContext = runtimeContext;
@@ -5,7 +5,7 @@ import {
5
5
  evaluateCompat,
6
6
  fetchIngesterCompat,
7
7
  versionAtLeast
8
- } from "./chunk-L7HWKMCZ.js";
8
+ } from "./chunk-OY2HTUWY.js";
9
9
 
10
10
  // src/doctor.ts
11
11
  import { existsSync, readFileSync } from "fs";
package/dist/cli.cjs CHANGED
@@ -1,32 +1,52 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
2
+ "use strict"; function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
3
3
 
4
4
 
5
5
 
6
6
 
7
- var _chunkL6SRL65Jcjs = require('./chunk-L6SRL65J.cjs');
8
- require('./chunk-GI47WGRR.cjs');
7
+ var _chunkUGNPCOIWcjs = require('./chunk-UGNPCOIW.cjs');
8
+ require('./chunk-ARN26OK6.cjs');
9
9
 
10
10
  // src/cli.ts
11
+ var _child_process = require('child_process');
12
+ var _fs = require('fs');
13
+ var _module = require('module');
14
+ var _path = require('path');
15
+ function delegateToRuntimeCli(argv) {
16
+ try {
17
+ const manifest = _module.createRequire.call(void 0, _path.join.call(void 0, process.cwd(), "package.json")).resolve("@autter/runtime-cli/package.json");
18
+ const bin = _optionalChain([JSON, 'access', _ => _.parse, 'call', _2 => _2(_fs.readFileSync.call(void 0, manifest, "utf8")), 'access', _3 => _3.bin, 'optionalAccess', _4 => _4["autter-runtime"]]);
19
+ if (!bin) return null;
20
+ return _nullishCoalesce(_child_process.spawnSync.call(void 0, process.execPath, [_path.resolve.call(void 0, _path.dirname.call(void 0, manifest), bin), ...argv], { stdio: "inherit" }).status, () => ( 1));
21
+ } catch (e) {
22
+ return null;
23
+ }
24
+ }
11
25
  async function main(argv) {
12
26
  const [command, ...rest] = argv;
27
+ if (command === "sourcemaps") {
28
+ const code = delegateToRuntimeCli(argv);
29
+ if (code !== null) return code;
30
+ console.error("autter-runtime sourcemaps is part of @autter/runtime-cli: npm install -D @autter/runtime-cli");
31
+ return 64;
32
+ }
13
33
  if (command !== "doctor") {
14
- console.log(_chunkL6SRL65Jcjs.DOCTOR_USAGE);
34
+ console.log(_chunkUGNPCOIWcjs.DOCTOR_USAGE);
15
35
  return command === void 0 || command === "--help" || command === "-h" ? 0 : 64;
16
36
  }
17
- const parsed = _chunkL6SRL65Jcjs.parseDoctorArgs.call(void 0, rest);
37
+ const parsed = _chunkUGNPCOIWcjs.parseDoctorArgs.call(void 0, rest);
18
38
  if ("help" in parsed) {
19
- console.log(_chunkL6SRL65Jcjs.DOCTOR_USAGE);
39
+ console.log(_chunkUGNPCOIWcjs.DOCTOR_USAGE);
20
40
  return 0;
21
41
  }
22
42
  if ("error" in parsed) {
23
43
  console.error(`${parsed.error}
24
44
 
25
- ${_chunkL6SRL65Jcjs.DOCTOR_USAGE}`);
45
+ ${_chunkUGNPCOIWcjs.DOCTOR_USAGE}`);
26
46
  return 64;
27
47
  }
28
- const report = await _chunkL6SRL65Jcjs.runDoctor.call(void 0, parsed);
29
- console.log(parsed.json ? JSON.stringify(report, null, 2) : _chunkL6SRL65Jcjs.formatDoctorReport.call(void 0, report));
48
+ const report = await _chunkUGNPCOIWcjs.runDoctor.call(void 0, parsed);
49
+ console.log(parsed.json ? JSON.stringify(report, null, 2) : _chunkUGNPCOIWcjs.formatDoctorReport.call(void 0, report));
30
50
  return report.exitCode;
31
51
  }
32
52
  main(process.argv.slice(2)).then(
package/dist/cli.js CHANGED
@@ -4,12 +4,32 @@ import {
4
4
  formatDoctorReport,
5
5
  parseDoctorArgs,
6
6
  runDoctor
7
- } from "./chunk-ZS4WQJQR.js";
8
- import "./chunk-L7HWKMCZ.js";
7
+ } from "./chunk-Y4T7SQMO.js";
8
+ import "./chunk-OY2HTUWY.js";
9
9
 
10
10
  // src/cli.ts
11
+ import { spawnSync } from "child_process";
12
+ import { readFileSync } from "fs";
13
+ import { createRequire } from "module";
14
+ import { dirname, join, resolve } from "path";
15
+ function delegateToRuntimeCli(argv) {
16
+ try {
17
+ const manifest = createRequire(join(process.cwd(), "package.json")).resolve("@autter/runtime-cli/package.json");
18
+ const bin = JSON.parse(readFileSync(manifest, "utf8")).bin?.["autter-runtime"];
19
+ if (!bin) return null;
20
+ return spawnSync(process.execPath, [resolve(dirname(manifest), bin), ...argv], { stdio: "inherit" }).status ?? 1;
21
+ } catch {
22
+ return null;
23
+ }
24
+ }
11
25
  async function main(argv) {
12
26
  const [command, ...rest] = argv;
27
+ if (command === "sourcemaps") {
28
+ const code = delegateToRuntimeCli(argv);
29
+ if (code !== null) return code;
30
+ console.error("autter-runtime sourcemaps is part of @autter/runtime-cli: npm install -D @autter/runtime-cli");
31
+ return 64;
32
+ }
13
33
  if (command !== "doctor") {
14
34
  console.log(DOCTOR_USAGE);
15
35
  return command === void 0 || command === "--help" || command === "-h" ? 0 : 64;