@leavepulse/ui 0.72.2 → 0.72.3

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.
@@ -127,7 +127,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
127
127
  }
128
128
  }
129
129
  const copyable = (t) => t.variant === "error" || t.variant === "warning";
130
- const toastText = (t) => () => [t.title, t.message, t.details].filter(Boolean).join("\n");
130
+ const toastText = (t) => () => [t.title, t.message, t.details, t.context].filter(Boolean).join("\n");
131
131
  function selecting() {
132
132
  return Boolean(window.getSelection()?.toString());
133
133
  }
@@ -364,8 +364,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
364
364
  onRemember?: ((item: RecentItem, command: Command) => any) | undefined;
365
365
  }>, {
366
366
  placeholder: string;
367
- hotkey: boolean;
368
367
  context: boolean;
368
+ hotkey: boolean;
369
369
  commands: Command[];
370
370
  emptyText: string;
371
371
  debounce: number;
@@ -1,4 +1,4 @@
1
- import { _ as _sfc_main } from "../chunks/LpToaster-D5Pj_wc9.js";
1
+ import { _ as _sfc_main } from "../chunks/LpToaster-CmmqSF2o.js";
2
2
  export {
3
3
  _sfc_main as default
4
4
  };
@@ -21,6 +21,8 @@ export interface ToastItem {
21
21
  onClick?: () => void | Promise<void>;
22
22
  /** Copied with the message, not shown: what a bug report needs (request, status, ids). */
23
23
  details?: string;
24
+ /** Page and moment an error toast came up, copied last: "it broke" rarely says where or when. */
25
+ context?: string;
24
26
  }
25
27
  export interface ToastOptions {
26
28
  /**
@@ -5,9 +5,18 @@ function detailsOf(source, depth = 0) {
5
5
  if (typeof details === "string" && details) return details;
6
6
  return detailsOf(cause, depth + 1);
7
7
  }
8
+ function traceOf(source) {
9
+ if (!(source instanceof Error)) return void 0;
10
+ const head = `${source.name}: ${source.message}`;
11
+ const frames = (source.stack ?? "").split("\n").filter((line) => line.trim() && line.trim() !== head);
12
+ const own = [head, ...frames].join("\n");
13
+ const inner = traceOf(source.cause);
14
+ return inner ? `${own}
15
+ Caused by ${inner}` : own;
16
+ }
8
17
  function split(message, options) {
9
18
  const text = typeof message === "string" ? message : message.message;
10
- const details = options.details ?? (typeof message === "string" ? void 0 : detailsOf(message)) ?? detailsOf(options.cause);
19
+ const details = options.details ?? (typeof message === "string" ? void 0 : detailsOf(message)) ?? detailsOf(options.cause) ?? traceOf(typeof message === "string" ? options.cause : message);
11
20
  return [text, { ...options, details }];
12
21
  }
13
22
  const DEFAULT_DURATION = 4500;
@@ -29,7 +38,8 @@ function push(variant, input, given = {}) {
29
38
  dismissAt: duration > 0 ? Date.now() + duration : null,
30
39
  actions: options.actions,
31
40
  onClick: options.onClick,
32
- details: options.details
41
+ details: options.details,
42
+ context: variant === "error" ? [globalThis.location?.href, (/* @__PURE__ */ new Date()).toISOString()].filter(Boolean).join(" · ") : void 0
33
43
  };
34
44
  const same = options.key === void 0 ? -1 : queue.findIndex((t) => t.key === options.key);
35
45
  const existing = queue[same];
package/dist/index.js CHANGED
@@ -107,7 +107,7 @@ import { addTags, splitTags } from "./components/tags.js";
107
107
  import { _ as _75 } from "./chunks/LpTextarea-Blv8qdz0.js";
108
108
  import { _ as _76 } from "./chunks/LpThemeSwitcher-BGIVrM1l.js";
109
109
  import { _ as _77 } from "./chunks/LpTilt-B7KHX1zH.js";
110
- import { _ as _78 } from "./chunks/LpToaster-D5Pj_wc9.js";
110
+ import { _ as _78 } from "./chunks/LpToaster-CmmqSF2o.js";
111
111
  import { _ as _79 } from "./chunks/LpTooltip-BcBvIx4z.js";
112
112
  import { _ as _80 } from "./chunks/LpTour-BU4JX3RU.js";
113
113
  import { holeOf, openContextMenu, panelsAround } from "./components/tour.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leavepulse/ui",
3
- "version": "0.72.2",
3
+ "version": "0.72.3",
4
4
  "type": "module",
5
5
  "description": "LeavePulse token-driven Vue component kit.",
6
6
  "repository": {
@@ -204,7 +204,7 @@ async function settle(t: ToastItem, run: () => void | Promise<void>) {
204
204
  */
205
205
  const copyable = (t: ToastItem) => t.variant === "error" || t.variant === "warning"
206
206
  // Read on click rather than bound, so a toast whose text is updated in place copies what it now says.
207
- const toastText = (t: ToastItem) => () => [t.title, t.message, t.details].filter(Boolean).join("\n")
207
+ const toastText = (t: ToastItem) => () => [t.title, t.message, t.details, t.context].filter(Boolean).join("\n")
208
208
 
209
209
  function selecting(): boolean {
210
210
  return Boolean(window.getSelection()?.toString())
@@ -25,6 +25,8 @@ export interface ToastItem {
25
25
  onClick?: () => void | Promise<void>
26
26
  /** Copied with the message, not shown: what a bug report needs (request, status, ids). */
27
27
  details?: string
28
+ /** Page and moment an error toast came up, copied last: "it broke" rarely says where or when. */
29
+ context?: string
28
30
  }
29
31
 
30
32
  export interface ToastOptions {
@@ -61,9 +63,26 @@ function detailsOf(source: unknown, depth = 0): string | undefined {
61
63
  return detailsOf(cause, depth + 1)
62
64
  }
63
65
 
66
+ // A code fault (TypeError and the like) has no request behind it, and its
67
+ // message alone ("x is undefined") says nothing about where it happened: the
68
+ // copy gets its type and stack instead. Firefox and Safari leave the message
69
+ // out of `stack`, Chromium starts with it; the head is written once either way.
70
+ function traceOf(source: unknown): string | undefined {
71
+ if (!(source instanceof Error)) return undefined
72
+ const head = `${source.name}: ${source.message}`
73
+ const frames = (source.stack ?? "").split("\n").filter((line) => line.trim() && line.trim() !== head)
74
+ const own = [head, ...frames].join("\n")
75
+ const inner = traceOf(source.cause)
76
+ return inner ? `${own}\nCaused by ${inner}` : own
77
+ }
78
+
64
79
  function split(message: ToastMessage, options: ToastOptions): [string, ToastOptions] {
65
80
  const text = typeof message === "string" ? message : message.message
66
- const details = options.details ?? (typeof message === "string" ? undefined : detailsOf(message)) ?? detailsOf(options.cause)
81
+ const details =
82
+ options.details ??
83
+ (typeof message === "string" ? undefined : detailsOf(message)) ??
84
+ detailsOf(options.cause) ??
85
+ traceOf(typeof message === "string" ? options.cause : message)
67
86
  return [text, { ...options, details }]
68
87
  }
69
88
 
@@ -101,6 +120,7 @@ function push(
101
120
  actions: options.actions,
102
121
  onClick: options.onClick,
103
122
  details: options.details,
123
+ context: variant === "error" ? [globalThis.location?.href, new Date().toISOString()].filter(Boolean).join(" · ") : undefined,
104
124
  }
105
125
 
106
126
  const same = options.key === undefined ? -1 : queue.findIndex((t) => t.key === options.key)