sentry-miniapp 1.4.1 → 1.5.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.
@@ -4938,7 +4938,7 @@ function addBreadcrumb(breadcrumb, hint) {
4938
4938
  }
4939
4939
  isolationScope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);
4940
4940
  }
4941
- const SDK_VERSION = "1.4.1";
4941
+ const SDK_VERSION = "1.5.0";
4942
4942
  const SDK_NAME = "sentry.javascript.miniapp";
4943
4943
  const getSDK = () => {
4944
4944
  let currentSdk = {
@@ -6079,40 +6079,27 @@ const _Router = class _Router {
6079
6079
  * Instrument navigation functions
6080
6080
  */
6081
6081
  _instrumentNavigation() {
6082
- const global2 = globalThis;
6083
- if (global2.wx && global2.wx.navigateTo) {
6084
- const originalNavigateTo = global2.wx.navigateTo;
6085
- global2.wx.navigateTo = (options) => {
6086
- this._recordNavigation("navigateTo", options.url, this._getCurrentRoute());
6087
- return originalNavigateTo.call(global2.wx, options);
6088
- };
6089
- }
6090
- if (global2.wx && global2.wx.redirectTo) {
6091
- const originalRedirectTo = global2.wx.redirectTo;
6092
- global2.wx.redirectTo = (options) => {
6093
- this._recordNavigation("redirectTo", options.url, this._getCurrentRoute());
6094
- return originalRedirectTo.call(global2.wx, options);
6095
- };
6082
+ let currentSdk;
6083
+ try {
6084
+ currentSdk = sdk();
6085
+ } catch (_e) {
6086
+ return;
6096
6087
  }
6097
- if (global2.wx && global2.wx.switchTab) {
6098
- const originalSwitchTab = global2.wx.switchTab;
6099
- global2.wx.switchTab = (options) => {
6100
- this._recordNavigation("switchTab", options.url, this._getCurrentRoute());
6101
- return originalSwitchTab.call(global2.wx, options);
6102
- };
6088
+ const methods = ["navigateTo", "redirectTo", "switchTab", "reLaunch"];
6089
+ for (const method of methods) {
6090
+ if (currentSdk[method]) {
6091
+ const original = currentSdk[method];
6092
+ currentSdk[method] = (options) => {
6093
+ this._recordNavigation(method, options.url, this._getCurrentRoute());
6094
+ return original.call(currentSdk, options);
6095
+ };
6096
+ }
6103
6097
  }
6104
- if (global2.wx && global2.wx.navigateBack) {
6105
- const originalNavigateBack = global2.wx.navigateBack;
6106
- global2.wx.navigateBack = (options = {}) => {
6098
+ if (currentSdk.navigateBack) {
6099
+ const originalNavigateBack = currentSdk.navigateBack;
6100
+ currentSdk.navigateBack = (options = {}) => {
6107
6101
  this._recordNavigation("navigateBack", "back", this._getCurrentRoute(), options.delta);
6108
- return originalNavigateBack.call(global2.wx, options);
6109
- };
6110
- }
6111
- if (global2.wx && global2.wx.reLaunch) {
6112
- const originalReLaunch = global2.wx.reLaunch;
6113
- global2.wx.reLaunch = (options) => {
6114
- this._recordNavigation("reLaunch", options.url, this._getCurrentRoute());
6115
- return originalReLaunch.call(global2.wx, options);
6102
+ return originalNavigateBack.call(currentSdk, options);
6116
6103
  };
6117
6104
  }
6118
6105
  }
@@ -6201,15 +6188,24 @@ const _PerformanceIntegration = class _PerformanceIntegration {
6201
6188
  this._observers = [];
6202
6189
  this._entryBuffer = [];
6203
6190
  this._reportTimer = null;
6204
- this._options = __spreadValues({
6191
+ this._options = __spreadProps(__spreadValues({
6205
6192
  enableNavigation: true,
6206
6193
  enableRender: true,
6207
6194
  enableResource: true,
6208
6195
  enableUserTiming: false,
6209
6196
  sampleRate: 1,
6210
6197
  bufferSize: 100,
6211
- reportInterval: 3e4
6212
- }, options);
6198
+ reportInterval: 3e4,
6199
+ // 30秒
6200
+ enableMemory: false
6201
+ }, options), {
6202
+ thresholds: __spreadValues({
6203
+ navigation: 3e3,
6204
+ render: 1e3,
6205
+ resource: 2e3,
6206
+ setData: 50
6207
+ }, options == null ? void 0 : options.thresholds)
6208
+ });
6213
6209
  }
6214
6210
  /**
6215
6211
  * @inheritDoc
@@ -6405,6 +6401,7 @@ const _PerformanceIntegration = class _PerformanceIntegration {
6405
6401
  * 处理渲染性能条目
6406
6402
  */
6407
6403
  _processRenderEntry(entry) {
6404
+ var _a, _b;
6408
6405
  startSpan(
6409
6406
  {
6410
6407
  name: `Render: ${entry.name}`,
@@ -6423,6 +6420,24 @@ const _PerformanceIntegration = class _PerformanceIntegration {
6423
6420
  span.end((entry.startTime + entry.duration) / 1e3);
6424
6421
  }
6425
6422
  );
6423
+ const setDataThreshold = (_b = (_a = this._options.thresholds) == null ? void 0 : _a.setData) != null ? _b : 50;
6424
+ if (entry.duration > setDataThreshold) {
6425
+ const scope = getCurrentScope();
6426
+ scope.addBreadcrumb({
6427
+ message: `慢渲染检测: ${entry.name} (${entry.duration.toFixed(1)}ms)`,
6428
+ category: "performance.setData.slow",
6429
+ level: "warning",
6430
+ data: {
6431
+ name: entry.name,
6432
+ duration: entry.duration,
6433
+ threshold: setDataThreshold,
6434
+ renderStart: entry.renderStart,
6435
+ renderEnd: entry.renderEnd,
6436
+ scriptStart: entry.scriptStart,
6437
+ scriptEnd: entry.scriptEnd
6438
+ }
6439
+ });
6440
+ }
6426
6441
  }
6427
6442
  /**
6428
6443
  * 处理资源加载性能条目
@@ -6517,6 +6532,10 @@ const _PerformanceIntegration = class _PerformanceIntegration {
6517
6532
  try {
6518
6533
  const scope = getCurrentScope();
6519
6534
  const stats = this._calculatePerformanceStats();
6535
+ const memoryInfo = this._collectMemoryInfo();
6536
+ if (memoryInfo) {
6537
+ stats["memory"] = memoryInfo;
6538
+ }
6520
6539
  scope.setContext("performance_summary", __spreadValues({
6521
6540
  total_entries: this._entryBuffer.length,
6522
6541
  navigation_count: this._entryBuffer.filter((e) => e.entryType === "navigation").length,
@@ -6556,6 +6575,14 @@ const _PerformanceIntegration = class _PerformanceIntegration {
6556
6575
  max_duration: Math.max(...durations),
6557
6576
  min_duration: Math.min(...durations)
6558
6577
  };
6578
+ const slowRenders = renderEntries.filter(
6579
+ (e) => {
6580
+ var _a, _b;
6581
+ return e.duration > ((_b = (_a = this._options.thresholds) == null ? void 0 : _a.setData) != null ? _b : 50);
6582
+ }
6583
+ );
6584
+ stats["render_stats"].slow_render_count = slowRenders.length;
6585
+ stats["render_stats"].slow_render_ratio = slowRenders.length / renderEntries.length;
6559
6586
  }
6560
6587
  if (resourceEntries.length > 0) {
6561
6588
  const durations = resourceEntries.map((e) => e.duration);
@@ -6573,38 +6600,41 @@ const _PerformanceIntegration = class _PerformanceIntegration {
6573
6600
  * 检查性能阈值
6574
6601
  */
6575
6602
  _checkPerformanceThresholds(stats) {
6576
- var _a, _b, _c;
6603
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
6577
6604
  const scope = getCurrentScope();
6578
- if (((_a = stats["navigation_stats"]) == null ? void 0 : _a.avg_duration) > 3e3) {
6605
+ const navigationThreshold = (_b = (_a = this._options.thresholds) == null ? void 0 : _a.navigation) != null ? _b : 3e3;
6606
+ if (((_c = stats["navigation_stats"]) == null ? void 0 : _c.avg_duration) > navigationThreshold) {
6579
6607
  scope.addBreadcrumb({
6580
6608
  message: "页面导航性能较慢",
6581
6609
  category: "performance.warning",
6582
6610
  level: "warning",
6583
6611
  data: {
6584
6612
  avg_duration: stats["navigation_stats"].avg_duration,
6585
- threshold: 3e3
6613
+ threshold: navigationThreshold
6586
6614
  }
6587
6615
  });
6588
6616
  }
6589
- if (((_b = stats["render_stats"]) == null ? void 0 : _b.avg_duration) > 1e3) {
6617
+ const renderThreshold = (_e = (_d = this._options.thresholds) == null ? void 0 : _d.render) != null ? _e : 1e3;
6618
+ if (((_f = stats["render_stats"]) == null ? void 0 : _f.avg_duration) > renderThreshold) {
6590
6619
  scope.addBreadcrumb({
6591
6620
  message: "页面渲染性能较慢",
6592
6621
  category: "performance.warning",
6593
6622
  level: "warning",
6594
6623
  data: {
6595
6624
  avg_duration: stats["render_stats"].avg_duration,
6596
- threshold: 1e3
6625
+ threshold: renderThreshold
6597
6626
  }
6598
6627
  });
6599
6628
  }
6600
- if (((_c = stats["resource_stats"]) == null ? void 0 : _c.avg_load_time) > 2e3) {
6629
+ const resourceThreshold = (_h = (_g = this._options.thresholds) == null ? void 0 : _g.resource) != null ? _h : 2e3;
6630
+ if (((_i = stats["resource_stats"]) == null ? void 0 : _i.avg_load_time) > resourceThreshold) {
6601
6631
  scope.addBreadcrumb({
6602
6632
  message: "资源加载性能较慢",
6603
6633
  category: "performance.warning",
6604
6634
  level: "warning",
6605
6635
  data: {
6606
6636
  avg_load_time: stats["resource_stats"].avg_load_time,
6607
- threshold: 2e3
6637
+ threshold: resourceThreshold
6608
6638
  }
6609
6639
  });
6610
6640
  }
@@ -6632,6 +6662,26 @@ const _PerformanceIntegration = class _PerformanceIntegration {
6632
6662
  console.warn("[Sentry Performance] Failed to report to native API:", error2);
6633
6663
  }
6634
6664
  }
6665
+ /**
6666
+ * 采集内存信息
6667
+ */
6668
+ _collectMemoryInfo() {
6669
+ if (!this._options.enableMemory) return null;
6670
+ try {
6671
+ const currentSdk = sdk();
6672
+ if (currentSdk.getPerformance) {
6673
+ const perf = currentSdk.getPerformance();
6674
+ if (perf && perf.memory) {
6675
+ return {
6676
+ jsHeapSizeUsed: perf.memory.jsHeapSizeUsed,
6677
+ jsHeapSizeLimit: perf.memory.jsHeapSizeLimit
6678
+ };
6679
+ }
6680
+ }
6681
+ } catch (_e) {
6682
+ }
6683
+ return null;
6684
+ }
6635
6685
  /**
6636
6686
  * 添加性能上下文信息
6637
6687
  */
@@ -6836,18 +6886,179 @@ const _NetworkBreadcrumbs = class _NetworkBreadcrumbs {
6836
6886
  };
6837
6887
  _NetworkBreadcrumbs.id = "NetworkBreadcrumbs";
6838
6888
  let NetworkBreadcrumbs = _NetworkBreadcrumbs;
6889
+ const PAGE_LIFECYCLE_METHODS = ["onLoad", "onShow", "onHide", "onUnload", "onReady"];
6890
+ const APP_LIFECYCLE_METHODS = ["onLaunch", "onShow", "onHide"];
6891
+ function isUserInteractionHandler(name) {
6892
+ if (PAGE_LIFECYCLE_METHODS.includes(name)) return false;
6893
+ if (name.startsWith("_")) return false;
6894
+ return /^(on|handle|bind)[A-Z]/.test(name) || /[Tt]ap$/.test(name) || /[Cc]lick$/.test(name) || /[Cc]hange$/.test(name) || /[Ss]ubmit$/.test(name) || /[Ss]croll$/.test(name) || /[Ii]nput$/.test(name);
6895
+ }
6896
+ const _PageBreadcrumbs = class _PageBreadcrumbs {
6897
+ constructor(options = {}) {
6898
+ this.name = _PageBreadcrumbs.id;
6899
+ this._options = __spreadValues({
6900
+ enableLifecycle: true,
6901
+ enableUserInteraction: true
6902
+ }, options);
6903
+ }
6904
+ setupOnce() {
6905
+ this._wrapPage();
6906
+ this._wrapApp();
6907
+ }
6908
+ /**
6909
+ * 包装全局 Page() 构造函数
6910
+ */
6911
+ _wrapPage() {
6912
+ const global2 = globalThis;
6913
+ if (typeof global2.Page !== "function") return;
6914
+ const originalPage = global2.Page;
6915
+ const options = this._options;
6916
+ global2.Page = function(pageOptions) {
6917
+ if (pageOptions && typeof pageOptions === "object") {
6918
+ if (options.enableLifecycle) {
6919
+ for (const method of PAGE_LIFECYCLE_METHODS) {
6920
+ if (typeof pageOptions[method] === "function") {
6921
+ const original = pageOptions[method];
6922
+ pageOptions[method] = function(...args) {
6923
+ const route = (this == null ? void 0 : this.route) || (this == null ? void 0 : this.__route__) || "unknown";
6924
+ addBreadcrumb({
6925
+ category: "page.lifecycle",
6926
+ message: `${method}: ${route}`,
6927
+ level: "info",
6928
+ data: {
6929
+ action: method,
6930
+ page: route
6931
+ }
6932
+ });
6933
+ return original.apply(this, args);
6934
+ };
6935
+ }
6936
+ }
6937
+ }
6938
+ if (options.enableUserInteraction) {
6939
+ for (const key of Object.keys(pageOptions)) {
6940
+ if (typeof pageOptions[key] === "function" && isUserInteractionHandler(key)) {
6941
+ const original = pageOptions[key];
6942
+ pageOptions[key] = function(event, ...rest) {
6943
+ const route = (this == null ? void 0 : this.route) || (this == null ? void 0 : this.__route__) || "unknown";
6944
+ const breadcrumbData = {
6945
+ handler: key,
6946
+ page: route
6947
+ };
6948
+ if (event && typeof event === "object") {
6949
+ if (event.target) {
6950
+ if (event.target.id) breadcrumbData["targetId"] = event.target.id;
6951
+ if (event.target.dataset) breadcrumbData["dataset"] = event.target.dataset;
6952
+ }
6953
+ if (event.type) breadcrumbData["eventType"] = event.type;
6954
+ }
6955
+ addBreadcrumb({
6956
+ category: "user.interaction",
6957
+ message: `${key} on ${route}`,
6958
+ level: "info",
6959
+ data: breadcrumbData
6960
+ });
6961
+ return original.apply(this, [event, ...rest]);
6962
+ };
6963
+ }
6964
+ }
6965
+ }
6966
+ }
6967
+ return originalPage(pageOptions);
6968
+ };
6969
+ }
6970
+ /**
6971
+ * 包装全局 App() 构造函数
6972
+ */
6973
+ _wrapApp() {
6974
+ const global2 = globalThis;
6975
+ if (typeof global2.App !== "function") return;
6976
+ const originalApp = global2.App;
6977
+ const options = this._options;
6978
+ global2.App = function(appOptions) {
6979
+ if (appOptions && typeof appOptions === "object" && options.enableLifecycle) {
6980
+ for (const method of APP_LIFECYCLE_METHODS) {
6981
+ if (typeof appOptions[method] === "function") {
6982
+ const original = appOptions[method];
6983
+ appOptions[method] = function(...args) {
6984
+ addBreadcrumb({
6985
+ category: "app.lifecycle",
6986
+ message: `App.${method}`,
6987
+ level: "info",
6988
+ data: {
6989
+ action: method
6990
+ }
6991
+ });
6992
+ return original.apply(this, args);
6993
+ };
6994
+ }
6995
+ }
6996
+ }
6997
+ return originalApp(appOptions);
6998
+ };
6999
+ }
7000
+ };
7001
+ _PageBreadcrumbs.id = "PageBreadcrumbs";
7002
+ let PageBreadcrumbs = _PageBreadcrumbs;
7003
+ const pageBreadcrumbsIntegration = (options) => {
7004
+ return new PageBreadcrumbs(options);
7005
+ };
7006
+ const CONSOLE_LEVELS = ["debug", "info", "warn", "error", "log"];
7007
+ const LEVEL_TO_SEVERITY = {
7008
+ debug: "debug",
7009
+ info: "info",
7010
+ log: "info",
7011
+ warn: "warning",
7012
+ error: "error"
7013
+ };
7014
+ const _ConsoleBreadcrumbs = class _ConsoleBreadcrumbs {
7015
+ constructor(options = {}) {
7016
+ this.name = _ConsoleBreadcrumbs.id;
7017
+ this._levels = options.levels || [...CONSOLE_LEVELS];
7018
+ }
7019
+ setupOnce() {
7020
+ for (const level of this._levels) {
7021
+ if (typeof console[level] !== "function") continue;
7022
+ const original = console[level];
7023
+ console[level] = function(...args) {
7024
+ addBreadcrumb({
7025
+ category: "console",
7026
+ level: LEVEL_TO_SEVERITY[level],
7027
+ message: args.map((a) => {
7028
+ if (typeof a === "string") return a;
7029
+ try {
7030
+ return JSON.stringify(a);
7031
+ } catch (_e) {
7032
+ return String(a);
7033
+ }
7034
+ }).join(" ")
7035
+ });
7036
+ return original.apply(console, args);
7037
+ };
7038
+ }
7039
+ }
7040
+ };
7041
+ _ConsoleBreadcrumbs.id = "ConsoleBreadcrumbs";
7042
+ let ConsoleBreadcrumbs = _ConsoleBreadcrumbs;
7043
+ const consoleBreadcrumbsIntegration = (options) => {
7044
+ return new ConsoleBreadcrumbs(options);
7045
+ };
6839
7046
  const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6840
7047
  __proto__: null,
7048
+ ConsoleBreadcrumbs,
6841
7049
  Dedupe,
6842
7050
  GlobalHandlers,
6843
7051
  HttpContext,
6844
7052
  LinkedErrors,
6845
7053
  NetworkBreadcrumbs,
7054
+ PageBreadcrumbs,
6846
7055
  PerformanceIntegration,
6847
7056
  RewriteFrames,
6848
7057
  Router,
6849
7058
  System,
6850
7059
  TryCatch,
7060
+ consoleBreadcrumbsIntegration,
7061
+ pageBreadcrumbsIntegration,
6851
7062
  performanceIntegration
6852
7063
  }, Symbol.toStringTag, { value: "Module" }));
6853
7064
  const defaultIntegrations = [
@@ -6884,6 +7095,12 @@ function init(options = {}) {
6884
7095
  opts.integrations.push(new RewriteFrames());
6885
7096
  }
6886
7097
  opts.integrations.push(new NetworkBreadcrumbs({ traceNetworkBody: opts.traceNetworkBody }));
7098
+ if (opts.enableUserInteractionBreadcrumbs !== false) {
7099
+ opts.integrations.push(new PageBreadcrumbs());
7100
+ }
7101
+ if (opts.enableConsoleBreadcrumbs) {
7102
+ opts.integrations.push(new ConsoleBreadcrumbs());
7103
+ }
6887
7104
  setContext("miniapp", {
6888
7105
  platform: appName,
6889
7106
  environment: "miniapp"