@flareapp/vue 2.10.0 → 2.12.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/README.md CHANGED
@@ -87,6 +87,18 @@ are mounted. A component with an async `setup()`, or one inside a `<Suspense>` b
87
87
  after its profiled ancestor's span has closed, so it appears after its parent in the waterfall. If the
88
88
  whole trace closed by then, the span is dropped rather than attached to a finished trace.
89
89
 
90
+ ### Self time
91
+
92
+ Every component span carries `flare.component.self_time_ns`: the span's duration minus the time its own
93
+ profiled children account for. Children that overlap in time are counted once, so the value never goes
94
+ below zero.
95
+
96
+ A child that mounts after its parent's span closed is not subtracted. Its work happened outside the
97
+ parent's window, so the parent keeps its full duration.
98
+
99
+ A layout is the usual example. `vue-router` resolves the first route after the layout mounted, so the page
100
+ component's work falls outside the layout's window.
101
+
90
102
  ### Naming with Inertia
91
103
 
92
104
  Inertia names navigation spans after the page component from its page object, so a root reads `Products/Show`.
@@ -8,7 +8,6 @@ const { registerDefaultFlare, resolveFlare } = createFlareResolver({ packageName
8
8
 
9
9
  //#endregion
10
10
  //#region src/constants.ts
11
- /** Injected at build time via tsdown --env.PACKAGE_VERSION (reads package.json version). */
12
11
  const PACKAGE_VERSION = typeof process !== "undefined" && typeof process.env?.PACKAGE_VERSION !== "undefined" ? process.env.PACKAGE_VERSION : "?";
13
12
  const MAX_HIERARCHY_DEPTH = 50;
14
13
  const DEFAULT_PROPS_DENYLIST = /password|passwd|pwd|token|secret|authorization|\bauth\b|bearer|oauth|credentials?|cookie|api[-_]?key|private[-_]?key|session|csrf|xsrf|\bpin\b|\bssn\b|card[-_]?number|\bcvv\b/i;
@@ -105,10 +104,6 @@ function buildComponentHierarchy(instance) {
105
104
 
106
105
  //#endregion
107
106
  //#region src/serializeProps.ts
108
- /**
109
- * JSON-safe, redacted, size-bounded copy of a Vue component's props for the report payload. Delegates
110
- * to core safeClone (display mode) so the cycle / BigInt / throwing-getter safety is shared with core.
111
- */
112
107
  function serializeProps(value, maxDepth, denylist = DEFAULT_PROPS_DENYLIST) {
113
108
  return safeClone(value, {
114
109
  mode: "display",
@@ -140,10 +135,6 @@ function buildComponentHierarchyFrames(instance, options) {
140
135
 
141
136
  //#endregion
142
137
  //#region src/getErrorOrigin.ts
143
- /**
144
- * Vue's `info` is a human-readable string in dev (e.g. "render function") but a numeric/short code
145
- * in production. INFO_TO_ORIGIN maps both forms to a stable origin category.
146
- */
147
138
  function getErrorOrigin(info) {
148
139
  return INFO_TO_ORIGIN[info] ?? "unknown";
149
140
  }
@@ -151,7 +142,6 @@ function getErrorOrigin(info) {
151
142
  //#endregion
152
143
  //#region src/getRouteContext.ts
153
144
  const ROUTE_PARAMS_DEPTH = 2;
154
- /** vue-router allows a symbol route name; neither shape survives JSON, so convert both to a string. */
155
145
  function routeNameOf(value) {
156
146
  if (typeof value === "string") return value;
157
147
  if (typeof value === "symbol") return value.toString();
@@ -168,12 +158,6 @@ function recordOrEmpty(value) {
168
158
  if (!value || typeof value !== "object") return {};
169
159
  return value;
170
160
  }
171
- /**
172
- * `router` is typed `unknown` because vue-router is an optional peer (importing it would force every
173
- * consumer to install it, and the runtime shape may differ across v4.x patches). The chained
174
- * type-guards read defensively so a missing or shimmed router yields `null` rather than throwing
175
- * inside an error handler.
176
- */
177
161
  function getRouteContext(router, options = {}) {
178
162
  if (!router || typeof router !== "object" || !("currentRoute" in router)) return null;
179
163
  const currentRouteRef = router.currentRoute;
@@ -202,11 +186,9 @@ const tagger = createIdentityTagger({
202
186
  sdkVersion: PACKAGE_VERSION,
203
187
  frameworkName: FrameworkName.Vue
204
188
  });
205
- /** Web path: SDK identity only; the framework version (app.version) is only known at install time. */
206
189
  function registerVueSdkInfo(flare) {
207
190
  tagger.registerSdkIdentity(flare);
208
191
  }
209
- /** Both paths tag the framework; never touches sdkInfo (would clobber an injected SDK name). */
210
192
  function tagVueFramework(flare, appVersion) {
211
193
  tagger.tagFramework(flare, appVersion);
212
194
  }
@@ -214,8 +196,6 @@ function tagVueFramework(flare, appVersion) {
214
196
  //#endregion
215
197
  //#region src/profileVueComponents.ts
216
198
  const PROFILE = Symbol("flareComponentProfile");
217
- /** Only matched components store a marker, so unmatched ones, and functional components, which get
218
- * no lifecycle hooks at all, need no code of their own. */
219
199
  function nearestMarker(instance) {
220
200
  for (let node = instance.parent; node; node = node.parent) {
221
201
  const state = node[PROFILE];
@@ -223,14 +203,6 @@ function nearestMarker(instance) {
223
203
  }
224
204
  return null;
225
205
  }
226
- /**
227
- * Record one `browser_component` span per matched component mount. `beforeMount` reserves the span id
228
- * and captures the start; `mounted` records it. Vue runs `beforeMount` top-down and `mounted` bottom-up,
229
- * so a parent's span encloses its SYNCHRONOUS descendants in time. Async components and anything under
230
- * `<Suspense>` are outside that contract: their span can start after the parent's ended, or be dropped
231
- * entirely when the root closed in the meantime. Nesting by parent id holds while the trace is the
232
- * same; a trace change re-homes a descendant to the live root instead of its dead-trace ancestor.
233
- */
234
206
  function createComponentProfilerMixin(matches) {
235
207
  return {
236
208
  beforeMount() {
@@ -278,13 +250,10 @@ function createComponentProfilerMixin(matches) {
278
250
  //#endregion
279
251
  //#region src/traceVueRouter.ts
280
252
  const NAVIGATION_CANCELLED = 8;
281
- /** Internal, wired through `flareVue({ router })`. Opens a held navigation root per route change,
282
- * settled when the navigation confirms. */
283
253
  function traceVueRouter(router) {
284
254
  if (!isVueRouter(router)) return () => {};
285
255
  return instrumentOnce(router, (track) => install(router, track));
286
256
  }
287
- /** Guards only what the integration calls unconditionally; `resolve` and `onError` stay optional. */
288
257
  function isVueRouter(router) {
289
258
  if (typeof router !== "object" || router === null) return false;
290
259
  return "beforeEach" in router && typeof router.beforeEach === "function" && "afterEach" in router && typeof router.afterEach === "function";
@@ -8,7 +8,6 @@ const { registerDefaultFlare, resolveFlare } = (0, _flareapp_js_browser.createFl
8
8
 
9
9
  //#endregion
10
10
  //#region src/constants.ts
11
- /** Injected at build time via tsdown --env.PACKAGE_VERSION (reads package.json version). */
12
11
  const PACKAGE_VERSION = typeof process !== "undefined" && typeof process.env?.PACKAGE_VERSION !== "undefined" ? process.env.PACKAGE_VERSION : "?";
13
12
  const MAX_HIERARCHY_DEPTH = 50;
14
13
  const DEFAULT_PROPS_DENYLIST = /password|passwd|pwd|token|secret|authorization|\bauth\b|bearer|oauth|credentials?|cookie|api[-_]?key|private[-_]?key|session|csrf|xsrf|\bpin\b|\bssn\b|card[-_]?number|\bcvv\b/i;
@@ -105,10 +104,6 @@ function buildComponentHierarchy(instance) {
105
104
 
106
105
  //#endregion
107
106
  //#region src/serializeProps.ts
108
- /**
109
- * JSON-safe, redacted, size-bounded copy of a Vue component's props for the report payload. Delegates
110
- * to core safeClone (display mode) so the cycle / BigInt / throwing-getter safety is shared with core.
111
- */
112
107
  function serializeProps(value, maxDepth, denylist = DEFAULT_PROPS_DENYLIST) {
113
108
  return (0, _flareapp_core.safeClone)(value, {
114
109
  mode: "display",
@@ -140,10 +135,6 @@ function buildComponentHierarchyFrames(instance, options) {
140
135
 
141
136
  //#endregion
142
137
  //#region src/getErrorOrigin.ts
143
- /**
144
- * Vue's `info` is a human-readable string in dev (e.g. "render function") but a numeric/short code
145
- * in production. INFO_TO_ORIGIN maps both forms to a stable origin category.
146
- */
147
138
  function getErrorOrigin(info) {
148
139
  return INFO_TO_ORIGIN[info] ?? "unknown";
149
140
  }
@@ -151,7 +142,6 @@ function getErrorOrigin(info) {
151
142
  //#endregion
152
143
  //#region src/getRouteContext.ts
153
144
  const ROUTE_PARAMS_DEPTH = 2;
154
- /** vue-router allows a symbol route name; neither shape survives JSON, so convert both to a string. */
155
145
  function routeNameOf(value) {
156
146
  if (typeof value === "string") return value;
157
147
  if (typeof value === "symbol") return value.toString();
@@ -168,12 +158,6 @@ function recordOrEmpty(value) {
168
158
  if (!value || typeof value !== "object") return {};
169
159
  return value;
170
160
  }
171
- /**
172
- * `router` is typed `unknown` because vue-router is an optional peer (importing it would force every
173
- * consumer to install it, and the runtime shape may differ across v4.x patches). The chained
174
- * type-guards read defensively so a missing or shimmed router yields `null` rather than throwing
175
- * inside an error handler.
176
- */
177
161
  function getRouteContext(router, options = {}) {
178
162
  if (!router || typeof router !== "object" || !("currentRoute" in router)) return null;
179
163
  const currentRouteRef = router.currentRoute;
@@ -202,11 +186,9 @@ const tagger = (0, _flareapp_core.createIdentityTagger)({
202
186
  sdkVersion: PACKAGE_VERSION,
203
187
  frameworkName: _flareapp_core.FrameworkName.Vue
204
188
  });
205
- /** Web path: SDK identity only; the framework version (app.version) is only known at install time. */
206
189
  function registerVueSdkInfo(flare) {
207
190
  tagger.registerSdkIdentity(flare);
208
191
  }
209
- /** Both paths tag the framework; never touches sdkInfo (would clobber an injected SDK name). */
210
192
  function tagVueFramework(flare, appVersion) {
211
193
  tagger.tagFramework(flare, appVersion);
212
194
  }
@@ -214,8 +196,6 @@ function tagVueFramework(flare, appVersion) {
214
196
  //#endregion
215
197
  //#region src/profileVueComponents.ts
216
198
  const PROFILE = Symbol("flareComponentProfile");
217
- /** Only matched components store a marker, so unmatched ones, and functional components, which get
218
- * no lifecycle hooks at all, need no code of their own. */
219
199
  function nearestMarker(instance) {
220
200
  for (let node = instance.parent; node; node = node.parent) {
221
201
  const state = node[PROFILE];
@@ -223,14 +203,6 @@ function nearestMarker(instance) {
223
203
  }
224
204
  return null;
225
205
  }
226
- /**
227
- * Record one `browser_component` span per matched component mount. `beforeMount` reserves the span id
228
- * and captures the start; `mounted` records it. Vue runs `beforeMount` top-down and `mounted` bottom-up,
229
- * so a parent's span encloses its SYNCHRONOUS descendants in time. Async components and anything under
230
- * `<Suspense>` are outside that contract: their span can start after the parent's ended, or be dropped
231
- * entirely when the root closed in the meantime. Nesting by parent id holds while the trace is the
232
- * same; a trace change re-homes a descendant to the live root instead of its dead-trace ancestor.
233
- */
234
206
  function createComponentProfilerMixin(matches) {
235
207
  return {
236
208
  beforeMount() {
@@ -278,13 +250,10 @@ function createComponentProfilerMixin(matches) {
278
250
  //#endregion
279
251
  //#region src/traceVueRouter.ts
280
252
  const NAVIGATION_CANCELLED = 8;
281
- /** Internal, wired through `flareVue({ router })`. Opens a held navigation root per route change,
282
- * settled when the navigation confirms. */
283
253
  function traceVueRouter(router) {
284
254
  if (!isVueRouter(router)) return () => {};
285
255
  return (0, _flareapp_js_browser.instrumentOnce)(router, (track) => install(router, track));
286
256
  }
287
- /** Guards only what the integration calls unconditionally; `resolve` and `onError` stay optional. */
288
257
  function isVueRouter(router) {
289
258
  if (typeof router !== "object" || router === null) return false;
290
259
  return "beforeEach" in router && typeof router.beforeEach === "function" && "afterEach" in router && typeof router.afterEach === "function";
@@ -50,9 +50,9 @@ type FlareVueOptions = {
50
50
  flare?: Flare; /** A vue-router Router instance. When set, enables navigation/pageload performance tracing. */
51
51
  router?: unknown;
52
52
  /**
53
- * Record a span per component mount. An array matches component names exactly (string) or by
54
- * `test()` (RegExp). `true` profiles every named component, which is a debugging aid: a real page
55
- * will hit `maxSpansPerTrace` and bury the useful spans. Requires `enableTracing`.
53
+ * Records a span per component mount. An array matches component names exactly (string) or by
54
+ * `test()` (RegExp). `true` profiles every named component useful for debugging, but a real
55
+ * page will hit `maxSpansPerTrace` and bury the useful spans. Requires `enableTracing`.
56
56
  */
57
57
  profileComponents?: ProfileComponentsOption;
58
58
  captureWarnings?: boolean;
@@ -50,9 +50,9 @@ type FlareVueOptions = {
50
50
  flare?: Flare; /** A vue-router Router instance. When set, enables navigation/pageload performance tracing. */
51
51
  router?: unknown;
52
52
  /**
53
- * Record a span per component mount. An array matches component names exactly (string) or by
54
- * `test()` (RegExp). `true` profiles every named component, which is a debugging aid: a real page
55
- * will hit `maxSpansPerTrace` and bury the useful spans. Requires `enableTracing`.
53
+ * Records a span per component mount. An array matches component names exactly (string) or by
54
+ * `test()` (RegExp). `true` profiles every named component useful for debugging, but a real
55
+ * page will hit `maxSpansPerTrace` and bury the useful spans. Requires `enableTracing`.
56
56
  */
57
57
  profileComponents?: ProfileComponentsOption;
58
58
  captureWarnings?: boolean;
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_FlareErrorBoundary = require('./FlareErrorBoundary-BndkpJFI.cjs');
2
+ const require_FlareErrorBoundary = require('./FlareErrorBoundary-LL-1P3x9.cjs');
3
3
  let _flareapp_js = require("@flareapp/js");
4
4
 
5
5
  //#region src/index.ts
package/dist/index.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ErrorOrigin, c as FlareVueContext, d as RouteContext, f as RouteParamValue, i as ComponentHierarchyFrame, l as FlareVueOptions, n as flareVue, o as FlareErrorBoundaryFallbackProps, p as RouteQueryValue, r as FlareErrorBoundary, s as FlareErrorBoundaryHookParams, t as DEFAULT_PROPS_DENYLIST, u as FlareVueWarningContext } from "./constants-BFiYPDOl.cjs";
1
+ import { a as ErrorOrigin, c as FlareVueContext, d as RouteContext, f as RouteParamValue, i as ComponentHierarchyFrame, l as FlareVueOptions, n as flareVue, o as FlareErrorBoundaryFallbackProps, p as RouteQueryValue, r as FlareErrorBoundary, s as FlareErrorBoundaryHookParams, t as DEFAULT_PROPS_DENYLIST, u as FlareVueWarningContext } from "./constants-D3YW5iYm.cjs";
2
2
  export { type ComponentHierarchyFrame, DEFAULT_PROPS_DENYLIST, type ErrorOrigin, FlareErrorBoundary, type FlareErrorBoundaryFallbackProps, type FlareErrorBoundaryHookParams, type FlareVueContext, type FlareVueOptions, type FlareVueWarningContext, type RouteContext, type RouteParamValue, type RouteQueryValue, flareVue };
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ErrorOrigin, c as FlareVueContext, d as RouteContext, f as RouteParamValue, i as ComponentHierarchyFrame, l as FlareVueOptions, n as flareVue, o as FlareErrorBoundaryFallbackProps, p as RouteQueryValue, r as FlareErrorBoundary, s as FlareErrorBoundaryHookParams, t as DEFAULT_PROPS_DENYLIST, u as FlareVueWarningContext } from "./constants-CFWxnFRO.mjs";
1
+ import { a as ErrorOrigin, c as FlareVueContext, d as RouteContext, f as RouteParamValue, i as ComponentHierarchyFrame, l as FlareVueOptions, n as flareVue, o as FlareErrorBoundaryFallbackProps, p as RouteQueryValue, r as FlareErrorBoundary, s as FlareErrorBoundaryHookParams, t as DEFAULT_PROPS_DENYLIST, u as FlareVueWarningContext } from "./constants-y6kJnEiP.mjs";
2
2
  export { type ComponentHierarchyFrame, DEFAULT_PROPS_DENYLIST, type ErrorOrigin, FlareErrorBoundary, type FlareErrorBoundaryFallbackProps, type FlareErrorBoundaryHookParams, type FlareVueContext, type FlareVueOptions, type FlareVueWarningContext, type RouteContext, type RouteParamValue, type RouteQueryValue, flareVue };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { i as registerDefaultFlare, n as flareVue, r as DEFAULT_PROPS_DENYLIST, t as FlareErrorBoundary } from "./FlareErrorBoundary-CO0ZV9lZ.mjs";
1
+ import { i as registerDefaultFlare, n as flareVue, r as DEFAULT_PROPS_DENYLIST, t as FlareErrorBoundary } from "./FlareErrorBoundary-C0uUTn2h.mjs";
2
2
  import { flare } from "@flareapp/js";
3
3
 
4
4
  //#region src/index.ts
package/dist/inject.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_FlareErrorBoundary = require('./FlareErrorBoundary-BndkpJFI.cjs');
2
+ const require_FlareErrorBoundary = require('./FlareErrorBoundary-LL-1P3x9.cjs');
3
3
 
4
4
  exports.DEFAULT_PROPS_DENYLIST = require_FlareErrorBoundary.DEFAULT_PROPS_DENYLIST;
5
5
  exports.FlareErrorBoundary = require_FlareErrorBoundary.FlareErrorBoundary;
package/dist/inject.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ErrorOrigin, c as FlareVueContext, d as RouteContext, f as RouteParamValue, i as ComponentHierarchyFrame, l as FlareVueOptions, n as flareVue, o as FlareErrorBoundaryFallbackProps, p as RouteQueryValue, r as FlareErrorBoundary, s as FlareErrorBoundaryHookParams, t as DEFAULT_PROPS_DENYLIST, u as FlareVueWarningContext } from "./constants-BFiYPDOl.cjs";
1
+ import { a as ErrorOrigin, c as FlareVueContext, d as RouteContext, f as RouteParamValue, i as ComponentHierarchyFrame, l as FlareVueOptions, n as flareVue, o as FlareErrorBoundaryFallbackProps, p as RouteQueryValue, r as FlareErrorBoundary, s as FlareErrorBoundaryHookParams, t as DEFAULT_PROPS_DENYLIST, u as FlareVueWarningContext } from "./constants-D3YW5iYm.cjs";
2
2
  export { type ComponentHierarchyFrame, DEFAULT_PROPS_DENYLIST, type ErrorOrigin, FlareErrorBoundary, type FlareErrorBoundaryFallbackProps, type FlareErrorBoundaryHookParams, type FlareVueContext, type FlareVueOptions, type FlareVueWarningContext, type RouteContext, type RouteParamValue, type RouteQueryValue, flareVue };
package/dist/inject.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ErrorOrigin, c as FlareVueContext, d as RouteContext, f as RouteParamValue, i as ComponentHierarchyFrame, l as FlareVueOptions, n as flareVue, o as FlareErrorBoundaryFallbackProps, p as RouteQueryValue, r as FlareErrorBoundary, s as FlareErrorBoundaryHookParams, t as DEFAULT_PROPS_DENYLIST, u as FlareVueWarningContext } from "./constants-CFWxnFRO.mjs";
1
+ import { a as ErrorOrigin, c as FlareVueContext, d as RouteContext, f as RouteParamValue, i as ComponentHierarchyFrame, l as FlareVueOptions, n as flareVue, o as FlareErrorBoundaryFallbackProps, p as RouteQueryValue, r as FlareErrorBoundary, s as FlareErrorBoundaryHookParams, t as DEFAULT_PROPS_DENYLIST, u as FlareVueWarningContext } from "./constants-y6kJnEiP.mjs";
2
2
  export { type ComponentHierarchyFrame, DEFAULT_PROPS_DENYLIST, type ErrorOrigin, FlareErrorBoundary, type FlareErrorBoundaryFallbackProps, type FlareErrorBoundaryHookParams, type FlareVueContext, type FlareVueOptions, type FlareVueWarningContext, type RouteContext, type RouteParamValue, type RouteQueryValue, flareVue };
package/dist/inject.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { n as flareVue, r as DEFAULT_PROPS_DENYLIST, t as FlareErrorBoundary } from "./FlareErrorBoundary-CO0ZV9lZ.mjs";
1
+ import { n as flareVue, r as DEFAULT_PROPS_DENYLIST, t as FlareErrorBoundary } from "./FlareErrorBoundary-C0uUTn2h.mjs";
2
2
 
3
3
  export { DEFAULT_PROPS_DENYLIST, FlareErrorBoundary, flareVue };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flareapp/vue",
3
- "version": "2.10.0",
3
+ "version": "2.12.0",
4
4
  "description": "Vue client for flareapp.io",
5
5
  "homepage": "https://flareapp.io",
6
6
  "bugs": "https://github.com/spatie/flare-client-js/issues",
@@ -62,7 +62,7 @@
62
62
  "verify:inject": "node scripts/verify-inject-no-root.mjs"
63
63
  },
64
64
  "dependencies": {
65
- "@flareapp/core": "2.10.0"
65
+ "@flareapp/core": "2.12.0"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@flareapp/electron": "file:../electron",
@@ -77,7 +77,7 @@
77
77
  "vue-router": "^5.0.0"
78
78
  },
79
79
  "peerDependencies": {
80
- "@flareapp/js": "^2.10.0",
80
+ "@flareapp/js": "^2.12.0",
81
81
  "vue": "^3.0.0",
82
82
  "vue-router": "^4.0.0 || ^5.0.0"
83
83
  },