efficient-shell 4.137.0 → 4.145.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.
Files changed (176) hide show
  1. package/LICENSE +6 -17
  2. package/README.md +80 -12
  3. package/dist/Browser-24YNRTKT.js +43 -0
  4. package/dist/Calculator-LER6KUQC.js +29 -0
  5. package/dist/ConfirmDialog-GAYETRMG.js +1 -0
  6. package/dist/CurrencyConverter-Y35GFDFF.js +21 -0
  7. package/dist/Documents-7FYX2CGT.js +52 -0
  8. package/dist/Files-RZOML2N6.js +89 -0
  9. package/dist/Notepad-VVDCBDUA.js +25 -0
  10. package/dist/PdfViewer-CvLb2j_l.d.ts +40 -0
  11. package/dist/PdfViewer-ZCT3PYXU.js +1 -0
  12. package/dist/PomodoroTimer-VAM3AJOX.js +99 -0
  13. package/dist/Preview-HZ37D7QJ.js +187 -0
  14. package/dist/Sidebar-CVF7C6BO.js +23 -0
  15. package/dist/Spreadsheet-6WX3P6AB.js +37 -0
  16. package/dist/Stock-AUWI3TUX.js +16 -0
  17. package/dist/Weather-HU75TH7T.js +60 -0
  18. package/dist/WorldClock-T64MDRMJ.js +32 -0
  19. package/dist/apps/index.d.ts +3 -23
  20. package/dist/apps/index.js +1 -151
  21. package/dist/brand.css +1 -1
  22. package/dist/chunk-2RHMSFZV.js +9 -0
  23. package/dist/chunk-4FS742BM.js +1 -0
  24. package/dist/chunk-57MIENLJ.js +1 -0
  25. package/dist/chunk-7DAQ3WVP.js +106 -0
  26. package/dist/chunk-BR22X7E5.js +1 -0
  27. package/dist/chunk-BUTSU7FO.js +1 -0
  28. package/dist/chunk-CVTOZCM3.js +24 -0
  29. package/dist/chunk-D65T4H6J.js +1 -0
  30. package/dist/chunk-ESL5TDNA.js +1 -0
  31. package/dist/chunk-FBDZGO3V.js +1 -0
  32. package/dist/chunk-FHTLC7HH.js +1 -0
  33. package/dist/chunk-GDSGXDET.js +34 -0
  34. package/dist/chunk-I55UMU3R.js +6 -0
  35. package/dist/chunk-KKOHUQPF.js +1 -0
  36. package/dist/chunk-L7TEFXIS.js +69 -0
  37. package/dist/chunk-LVDRBRYU.js +1 -0
  38. package/dist/chunk-LVFMK5OQ.js +29 -0
  39. package/dist/chunk-LWLCNQY7.js +1 -0
  40. package/dist/chunk-MAIHBBWT.js +1 -0
  41. package/dist/chunk-MU5H2CDL.js +2 -0
  42. package/dist/chunk-NBBOFQPL.js +947 -0
  43. package/dist/chunk-NPJH5MD7.js +13 -0
  44. package/dist/chunk-OCSOMMY2.js +1 -0
  45. package/dist/chunk-PH3PRIFP.js +5 -0
  46. package/dist/chunk-RJ4LACFH.js +9 -0
  47. package/dist/chunk-SLCR26NK.js +4 -0
  48. package/dist/chunk-TFKB2WEB.js +19 -0
  49. package/dist/chunk-TR6PLN7W.js +1 -0
  50. package/dist/chunk-TWV42Q3K.js +1 -0
  51. package/dist/chunk-UB22J6EF.js +1 -0
  52. package/dist/chunk-UB4JIOLD.js +2 -0
  53. package/dist/chunk-V453E4KU.js +11 -0
  54. package/dist/chunk-VTVSMRFX.js +1 -0
  55. package/dist/file-intake/index.js +1 -4
  56. package/dist/{index-DVI9DMSu.d.ts → index-NhR7frRu.d.ts} +189 -17
  57. package/dist/index.d.ts +2 -2
  58. package/dist/index.js +639 -7473
  59. package/dist/map/index.d.ts +266 -13
  60. package/dist/map/index.js +22 -540
  61. package/dist/markdown/index.js +6 -184
  62. package/dist/markup/index.js +1 -135
  63. package/dist/page-tabs/index.js +21 -709
  64. package/dist/pdf/index.d.ts +9 -0
  65. package/dist/pdf/index.js +2 -0
  66. package/dist/sounds-OMHXVVQ4.js +1 -0
  67. package/dist/ui/index.d.ts +1 -1
  68. package/dist/ui/index.js +1 -19
  69. package/dist/ui.css +7 -0
  70. package/package.json +9 -3
  71. package/dist/Browser-ZNX4WFUH.js +0 -482
  72. package/dist/Browser-ZNX4WFUH.js.map +0 -1
  73. package/dist/Calculator-6FGNKOXU.js +0 -192
  74. package/dist/Calculator-6FGNKOXU.js.map +0 -1
  75. package/dist/ConfirmDialog-NPQMIGUR.js +0 -4
  76. package/dist/ConfirmDialog-NPQMIGUR.js.map +0 -1
  77. package/dist/CurrencyConverter-FF7EXRYL.js +0 -236
  78. package/dist/CurrencyConverter-FF7EXRYL.js.map +0 -1
  79. package/dist/Documents-H3R7XSBH.js +0 -441
  80. package/dist/Documents-H3R7XSBH.js.map +0 -1
  81. package/dist/Files-ZHJIAUC2.js +0 -805
  82. package/dist/Files-ZHJIAUC2.js.map +0 -1
  83. package/dist/Notepad-VE7ISWRQ.js +0 -410
  84. package/dist/Notepad-VE7ISWRQ.js.map +0 -1
  85. package/dist/PdfViewer-SQBFYAGW.js +0 -5
  86. package/dist/PdfViewer-SQBFYAGW.js.map +0 -1
  87. package/dist/PomodoroTimer-IR3WREED.js +0 -633
  88. package/dist/PomodoroTimer-IR3WREED.js.map +0 -1
  89. package/dist/Preview-DAQGRNRM.js +0 -2959
  90. package/dist/Preview-DAQGRNRM.js.map +0 -1
  91. package/dist/Sidebar-YW6H4NDJ.js +0 -291
  92. package/dist/Sidebar-YW6H4NDJ.js.map +0 -1
  93. package/dist/Spreadsheet-HOCPHJOC.js +0 -519
  94. package/dist/Spreadsheet-HOCPHJOC.js.map +0 -1
  95. package/dist/Stock-LVRQPURG.js +0 -158
  96. package/dist/Stock-LVRQPURG.js.map +0 -1
  97. package/dist/Weather-LZQGVDJL.js +0 -431
  98. package/dist/Weather-LZQGVDJL.js.map +0 -1
  99. package/dist/WorldClock-XPD7WOZT.js +0 -202
  100. package/dist/WorldClock-XPD7WOZT.js.map +0 -1
  101. package/dist/apps/index.js.map +0 -1
  102. package/dist/chunk-5O42JXQE.js +0 -26
  103. package/dist/chunk-5O42JXQE.js.map +0 -1
  104. package/dist/chunk-5RPTS3BT.js +0 -70
  105. package/dist/chunk-5RPTS3BT.js.map +0 -1
  106. package/dist/chunk-6XJEJWNJ.js +0 -61
  107. package/dist/chunk-6XJEJWNJ.js.map +0 -1
  108. package/dist/chunk-7CCHEEYC.js +0 -94
  109. package/dist/chunk-7CCHEEYC.js.map +0 -1
  110. package/dist/chunk-BE7FZOFU.js +0 -17
  111. package/dist/chunk-BE7FZOFU.js.map +0 -1
  112. package/dist/chunk-COWYSHG2.js +0 -79
  113. package/dist/chunk-COWYSHG2.js.map +0 -1
  114. package/dist/chunk-D7PYW2QS.js +0 -265
  115. package/dist/chunk-D7PYW2QS.js.map +0 -1
  116. package/dist/chunk-DVZWYWSD.js +0 -26
  117. package/dist/chunk-DVZWYWSD.js.map +0 -1
  118. package/dist/chunk-E7TB6WD2.js +0 -153
  119. package/dist/chunk-E7TB6WD2.js.map +0 -1
  120. package/dist/chunk-FIHOGVUP.js +0 -416
  121. package/dist/chunk-FIHOGVUP.js.map +0 -1
  122. package/dist/chunk-GA35NEND.js +0 -56
  123. package/dist/chunk-GA35NEND.js.map +0 -1
  124. package/dist/chunk-HUBJAUGG.js +0 -316
  125. package/dist/chunk-HUBJAUGG.js.map +0 -1
  126. package/dist/chunk-I2TAAJHS.js +0 -465
  127. package/dist/chunk-I2TAAJHS.js.map +0 -1
  128. package/dist/chunk-ICTRCKUE.js +0 -3710
  129. package/dist/chunk-ICTRCKUE.js.map +0 -1
  130. package/dist/chunk-IPXN646P.js +0 -14
  131. package/dist/chunk-IPXN646P.js.map +0 -1
  132. package/dist/chunk-IRWSRJ4K.js +0 -48
  133. package/dist/chunk-IRWSRJ4K.js.map +0 -1
  134. package/dist/chunk-JOPU6WPY.js +0 -504
  135. package/dist/chunk-JOPU6WPY.js.map +0 -1
  136. package/dist/chunk-MGGY74RY.js +0 -14
  137. package/dist/chunk-MGGY74RY.js.map +0 -1
  138. package/dist/chunk-PVPPAWVM.js +0 -46
  139. package/dist/chunk-PVPPAWVM.js.map +0 -1
  140. package/dist/chunk-R7QGMK6N.js +0 -102
  141. package/dist/chunk-R7QGMK6N.js.map +0 -1
  142. package/dist/chunk-RT6DSB5Y.js +0 -143
  143. package/dist/chunk-RT6DSB5Y.js.map +0 -1
  144. package/dist/chunk-TRCWINHF.js +0 -105
  145. package/dist/chunk-TRCWINHF.js.map +0 -1
  146. package/dist/chunk-TW7LPMVR.js +0 -16
  147. package/dist/chunk-TW7LPMVR.js.map +0 -1
  148. package/dist/chunk-UTYKLGGT.js +0 -195
  149. package/dist/chunk-UTYKLGGT.js.map +0 -1
  150. package/dist/chunk-VNJJCH5A.js +0 -822
  151. package/dist/chunk-VNJJCH5A.js.map +0 -1
  152. package/dist/chunk-XJHZWSKV.js +0 -1103
  153. package/dist/chunk-XJHZWSKV.js.map +0 -1
  154. package/dist/chunk-Y3GYJ7YR.js +0 -549
  155. package/dist/chunk-Y3GYJ7YR.js.map +0 -1
  156. package/dist/chunk-YA4EE7ST.js +0 -14107
  157. package/dist/chunk-YA4EE7ST.js.map +0 -1
  158. package/dist/chunk-YDHXWCCJ.js +0 -145
  159. package/dist/chunk-YDHXWCCJ.js.map +0 -1
  160. package/dist/chunk-YE6GUDGP.js +0 -548
  161. package/dist/chunk-YE6GUDGP.js.map +0 -1
  162. package/dist/chunk-YNKK7NE3.js +0 -171
  163. package/dist/chunk-YNKK7NE3.js.map +0 -1
  164. package/dist/chunk-YPO6RDMX.js +0 -20
  165. package/dist/chunk-YPO6RDMX.js.map +0 -1
  166. package/dist/chunk-ZS7PMGUW.js +0 -7
  167. package/dist/chunk-ZS7PMGUW.js.map +0 -1
  168. package/dist/file-intake/index.js.map +0 -1
  169. package/dist/index.js.map +0 -1
  170. package/dist/map/index.js.map +0 -1
  171. package/dist/markdown/index.js.map +0 -1
  172. package/dist/markup/index.js.map +0 -1
  173. package/dist/page-tabs/index.js.map +0 -1
  174. package/dist/sounds-NT4DEZGD.js +0 -3
  175. package/dist/sounds-NT4DEZGD.js.map +0 -1
  176. package/dist/ui/index.js.map +0 -1
@@ -1,105 +0,0 @@
1
- import { useState, useEffect } from 'react';
2
- import { jsx } from 'react/jsx-runtime';
3
-
4
- // src/forms/BrandMark.tsx
5
- var SLOT_CLASS = {
6
- favicon: "h-8 w-8",
7
- compact: "h-10 w-10",
8
- wordmark: "h-10 w-40"
9
- };
10
- function monogram(alt) {
11
- return alt.trim().charAt(0).toLocaleUpperCase() || "\xB7";
12
- }
13
- function resolveBrandMarkTreatment(hasAlpha, isLight, surface) {
14
- if (hasAlpha === false) return "framed";
15
- if (hasAlpha == null || isLight == null) return "plate-light";
16
- if (isLight) return surface === "light" ? "plate-dark" : "bare";
17
- return surface === "dark" ? "plate-light" : "bare";
18
- }
19
- var TREATMENT_CLASS = {
20
- "plate-light": "bg-white shadow-[0_2px_12px_var(--rosh-mark-plate-shadow)]",
21
- "plate-dark": "bg-neutral-900 shadow-[0_2px_12px_var(--rosh-mark-plate-shadow-strong)]",
22
- framed: "border border-black/10 shadow-[0_2px_12px_var(--rosh-mark-plate-shadow)]",
23
- bare: ""
24
- };
25
- function treatmentStyle(treatment, radius, padding) {
26
- if (treatment === "bare") return {};
27
- return treatment === "framed" ? { borderRadius: radius } : { borderRadius: radius, padding };
28
- }
29
- function BrandMark({
30
- src,
31
- fallbackSrc,
32
- fallbackHasAlpha = null,
33
- fallbackIsLight = null,
34
- fallbackAdaptive,
35
- alt,
36
- slot = "compact",
37
- surface = "light",
38
- size,
39
- width,
40
- height,
41
- decorative = false,
42
- fallbackMode = "monogram",
43
- adaptive = false,
44
- hasAlpha = null,
45
- isLight = null,
46
- treatmentPadding = 4,
47
- treatmentRadius = 8,
48
- className = "",
49
- style
50
- }) {
51
- const [activeSrc, setActiveSrc] = useState(src || fallbackSrc || "");
52
- useEffect(() => {
53
- setActiveSrc(src || fallbackSrc || "");
54
- }, [src, fallbackSrc]);
55
- const usingFallback = Boolean(
56
- fallbackSrc && activeSrc === fallbackSrc && activeSrc !== src
57
- );
58
- const activeAdaptive = usingFallback ? fallbackAdaptive ?? adaptive : adaptive;
59
- const activeHasAlpha = usingFallback ? fallbackHasAlpha : hasAlpha;
60
- const activeIsLight = usingFallback ? fallbackIsLight : isLight;
61
- const treatment = activeAdaptive ? resolveBrandMarkTreatment(activeHasAlpha, activeIsLight, surface) : "bare";
62
- const frameClass = [
63
- "inline-flex shrink-0 items-center justify-center overflow-hidden",
64
- size == null && width == null && height == null ? SLOT_CLASS[slot] : "",
65
- surface === "dark" ? "text-white" : "text-gray-700",
66
- TREATMENT_CLASS[treatment],
67
- className
68
- ].filter(Boolean).join(" ");
69
- const frameStyle = {
70
- ...treatmentStyle(treatment, treatmentRadius, treatmentPadding),
71
- ...size == null ? { width, height } : { width: size, height: size },
72
- ...style
73
- };
74
- if (!activeSrc) {
75
- if (fallbackMode === "none") return null;
76
- return /* @__PURE__ */ jsx(
77
- "span",
78
- {
79
- "data-brand-fallback": true,
80
- "data-brand-slot": slot,
81
- "aria-label": decorative ? void 0 : alt,
82
- "aria-hidden": decorative || void 0,
83
- role: decorative ? void 0 : "img",
84
- className: `${frameClass} rounded-md bg-gray-100 font-semibold`,
85
- style: frameStyle,
86
- children: decorative ? null : monogram(alt)
87
- }
88
- );
89
- }
90
- return /* @__PURE__ */ jsx("span", { className: frameClass, "data-brand-treatment": treatment, style: frameStyle, children: /* @__PURE__ */ jsx(
91
- "img",
92
- {
93
- src: activeSrc,
94
- alt: decorative ? "" : alt,
95
- "data-brand-slot": slot,
96
- className: "block max-h-full max-w-full",
97
- style: { objectFit: "contain" },
98
- onError: () => setActiveSrc((current) => fallbackSrc && current !== fallbackSrc ? fallbackSrc : "")
99
- }
100
- ) });
101
- }
102
-
103
- export { BrandMark, resolveBrandMarkTreatment };
104
- //# sourceMappingURL=chunk-TRCWINHF.js.map
105
- //# sourceMappingURL=chunk-TRCWINHF.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/forms/BrandMark.tsx"],"names":[],"mappings":"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","file":"chunk-TRCWINHF.js","sourcesContent":["import { useEffect, useState, type CSSProperties } from 'react';\n\nexport type BrandMarkSlot = 'favicon' | 'compact' | 'wordmark';\nexport type BrandMarkSurface = 'light' | 'dark';\nexport type BrandMarkTreatment = 'plate-light' | 'plate-dark' | 'framed' | 'bare';\n\nexport interface BrandMarkProps {\n src?: string | null;\n fallbackSrc?: string | null;\n fallbackHasAlpha?: boolean | null;\n fallbackIsLight?: boolean | null;\n fallbackAdaptive?: boolean;\n alt: string;\n slot?: BrandMarkSlot;\n surface?: BrandMarkSurface;\n /** Override the square slot size in pixels for compact shell chrome. */\n size?: number;\n /** Override a natural-aspect slot width without forcing square dimensions. */\n width?: number | string;\n /** Override a natural-aspect slot height without forcing square dimensions. */\n height?: number | string;\n /** Mark the image decorative when the adjacent text already names it. */\n decorative?: boolean;\n /** Hide the slot after load failure when surrounding UI owns the fallback. */\n fallbackMode?: 'monogram' | 'none';\n /** Keep an arbitrary tenant mark readable without recolouring the artwork. */\n adaptive?: boolean;\n /** Server-detected transparency hint for the selected asset. */\n hasAlpha?: boolean | null;\n /** Server-detected tone hint for the selected asset. */\n isLight?: boolean | null;\n treatmentPadding?: number | string;\n treatmentRadius?: number;\n className?: string;\n style?: CSSProperties;\n}\n\nconst SLOT_CLASS: Record<BrandMarkSlot, string> = {\n favicon: 'h-8 w-8',\n compact: 'h-10 w-10',\n wordmark: 'h-10 w-40',\n};\n\nfunction monogram(alt: string) {\n return alt.trim().charAt(0).toLocaleUpperCase() || '·';\n}\n\n/**\n * Chooses the smallest backing needed to preserve contrast. Opaque artwork\n * carries its own background; transparent artwork only needs a plate when its\n * tone would disappear into the current surface. Unknown artwork gets the\n * conservative light plate used by every portal.\n */\nexport function resolveBrandMarkTreatment(\n hasAlpha: boolean | null,\n isLight: boolean | null,\n surface: BrandMarkSurface,\n): BrandMarkTreatment {\n if (hasAlpha === false) return 'framed';\n if (hasAlpha == null || isLight == null) return 'plate-light';\n if (isLight) return surface === 'light' ? 'plate-dark' : 'bare';\n return surface === 'dark' ? 'plate-light' : 'bare';\n}\n\n/** The plate's colour and border are classes, so they follow the theme like\n * the rest of the file; only the caller-tunable radius and padding are\n * inline, because those arrive as numbers. The shadow's geometry is in the\n * class and its colour is a token (`--rosh-mark-plate-shadow`, and the\n * `-strong` one under the dark plate), so a host restyling depth reaches it. */\nconst TREATMENT_CLASS: Record<BrandMarkTreatment, string> = {\n 'plate-light': 'bg-white shadow-[0_2px_12px_var(--rosh-mark-plate-shadow)]',\n 'plate-dark': 'bg-neutral-900 shadow-[0_2px_12px_var(--rosh-mark-plate-shadow-strong)]',\n framed: 'border border-black/10 shadow-[0_2px_12px_var(--rosh-mark-plate-shadow)]',\n bare: '',\n};\n\nfunction treatmentStyle(\n treatment: BrandMarkTreatment,\n radius: number,\n padding: number | string,\n): CSSProperties {\n if (treatment === 'bare') return {};\n return treatment === 'framed'\n ? { borderRadius: radius }\n : { borderRadius: radius, padding };\n}\n\n/**\n * Renders a brand asset inside a stable portal slot without ever cropping or\n * stretching the source. Raster normalisation belongs to the server; this\n * component owns only the presentation contract shared by portal surfaces.\n */\nexport default function BrandMark({\n src,\n fallbackSrc,\n fallbackHasAlpha = null,\n fallbackIsLight = null,\n fallbackAdaptive,\n alt,\n slot = 'compact',\n surface = 'light',\n size,\n width,\n height,\n decorative = false,\n fallbackMode = 'monogram',\n adaptive = false,\n hasAlpha = null,\n isLight = null,\n treatmentPadding = 4,\n treatmentRadius = 8,\n className = '',\n style,\n}: BrandMarkProps) {\n const [activeSrc, setActiveSrc] = useState(src || fallbackSrc || '');\n\n useEffect(() => {\n setActiveSrc(src || fallbackSrc || '');\n }, [src, fallbackSrc]);\n\n const usingFallback = Boolean(\n fallbackSrc && activeSrc === fallbackSrc && activeSrc !== src,\n );\n const activeAdaptive = usingFallback ? fallbackAdaptive ?? adaptive : adaptive;\n const activeHasAlpha = usingFallback ? fallbackHasAlpha : hasAlpha;\n const activeIsLight = usingFallback ? fallbackIsLight : isLight;\n const treatment = activeAdaptive\n ? resolveBrandMarkTreatment(activeHasAlpha, activeIsLight, surface)\n : 'bare';\n const frameClass = [\n 'inline-flex shrink-0 items-center justify-center overflow-hidden',\n size == null && width == null && height == null ? SLOT_CLASS[slot] : '',\n surface === 'dark' ? 'text-white' : 'text-gray-700',\n TREATMENT_CLASS[treatment],\n className,\n ].filter(Boolean).join(' ');\n const frameStyle: CSSProperties = {\n ...treatmentStyle(treatment, treatmentRadius, treatmentPadding),\n ...(size == null ? { width, height } : { width: size, height: size }),\n ...style,\n };\n\n if (!activeSrc) {\n if (fallbackMode === 'none') return null;\n return (\n <span\n data-brand-fallback\n data-brand-slot={slot}\n aria-label={decorative ? undefined : alt}\n aria-hidden={decorative || undefined}\n role={decorative ? undefined : 'img'}\n className={`${frameClass} rounded-md bg-gray-100 font-semibold`}\n style={frameStyle}\n >\n {decorative ? null : monogram(alt)}\n </span>\n );\n }\n\n return (\n <span className={frameClass} data-brand-treatment={treatment} style={frameStyle}>\n <img\n src={activeSrc}\n alt={decorative ? '' : alt}\n data-brand-slot={slot}\n className=\"block max-h-full max-w-full\"\n style={{ objectFit: 'contain' }}\n onError={() => setActiveSrc(current => (\n fallbackSrc && current !== fallbackSrc ? fallbackSrc : ''\n ))}\n />\n </span>\n );\n}\n"]}
@@ -1,16 +0,0 @@
1
- // src/apps/_browserStage.ts
2
- var pendingStartUrl = null;
3
- var nextStartToken = 0;
4
- function setBrowserStartUrl(url) {
5
- pendingStartUrl = { token: ++nextStartToken, url };
6
- }
7
- function peekBrowserStartUrl() {
8
- return pendingStartUrl;
9
- }
10
- function claimBrowserStartUrl(stage) {
11
- if (pendingStartUrl === stage) pendingStartUrl = null;
12
- }
13
-
14
- export { claimBrowserStartUrl, peekBrowserStartUrl, setBrowserStartUrl };
15
- //# sourceMappingURL=chunk-TW7LPMVR.js.map
16
- //# sourceMappingURL=chunk-TW7LPMVR.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/apps/_browserStage.ts"],"names":[],"mappings":";AAeA,IAAI,eAAA,GAA0C,IAAA;AAC9C,IAAI,cAAA,GAAiB,CAAA;AAKd,SAAS,mBAAmB,GAAA,EAAmB;AACpD,EAAA,eAAA,GAAkB,EAAE,KAAA,EAAO,EAAE,cAAA,EAAgB,GAAA,EAAI;AACnD;AAGO,SAAS,mBAAA,GAA8C;AAC5D,EAAA,OAAO,eAAA;AACT;AAKO,SAAS,qBAAqB,KAAA,EAA8B;AACjE,EAAA,IAAI,eAAA,KAAoB,OAAO,eAAA,GAAkB,IAAA;AACnD","file":"chunk-TW7LPMVR.js","sourcesContent":["/**\n * Browser start-URL staging — the tiny consumer-facing surface of the Browser\n * app. Lives apart from Browser.tsx so importing `setBrowserStartUrl` (from\n * `efficient-shell/apps`) never drags the Browser implementation into a host's\n * startup bundle. The Browser window component stays behind its React.lazy\n * dynamic import and drains the stage on mount via the @internal peek/claim\n * helpers below.\n */\n\n/** @internal Staged URL awaiting the next Browser window mount. */\nexport interface PendingStartUrl {\n token: number;\n url: string;\n}\n\nlet pendingStartUrl: PendingStartUrl | null = null;\nlet nextStartToken = 0;\n\n/** Stage a URL for the next Browser window mount — pair with\n * `openPage('/browser')`. Used by \"open this link in the Browser\" flows\n * (e.g. links inside an email body). */\nexport function setBrowserStartUrl(url: string): void {\n pendingStartUrl = { token: ++nextStartToken, url };\n}\n\n/** @internal Render-phase peek — see Browser.tsx for the drain protocol. */\nexport function peekBrowserStartUrl(): PendingStartUrl | null {\n return pendingStartUrl;\n}\n\n/** @internal Commit-phase claim. The identity check keeps a URL staged\n * *after* the claimant's render-phase peek available for the window it\n * belongs to. */\nexport function claimBrowserStartUrl(stage: PendingStartUrl): void {\n if (pendingStartUrl === stage) pendingStartUrl = null;\n}\n"]}
@@ -1,195 +0,0 @@
1
- import { currentShellStrings } from './chunk-YE6GUDGP.js';
2
-
3
- // src/shell/toast.ts
4
- var TOAST_CONTAINER_ID = "toast-container";
5
- var TOAST_BOTTOM_CONTAINER_ID = "toast-container-bottom";
6
- var NOTIF_CONTAINER_ID = "notif-container";
7
- var FADE_MS = 300;
8
- var SVG_NS = "http://www.w3.org/2000/svg";
9
- var defaults = {};
10
- var live = /* @__PURE__ */ new Map();
11
- function getOrCreate(id, className) {
12
- let el = document.getElementById(id);
13
- if (!el) {
14
- el = document.createElement("div");
15
- el.id = id;
16
- el.className = className;
17
- document.body.appendChild(el);
18
- }
19
- return el;
20
- }
21
- var GLYPHS = {
22
- success: "M5 13l4 4L19 7",
23
- error: "M6 18L18 6M6 6l12 12",
24
- warning: "M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z",
25
- info: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z",
26
- loading: "M12 3a9 9 0 019 9",
27
- bell: "M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0"
28
- };
29
- function glyph(name, className) {
30
- const svg = document.createElementNS(SVG_NS, "svg");
31
- svg.setAttribute("class", className);
32
- svg.setAttribute("fill", "none");
33
- svg.setAttribute("viewBox", "0 0 24 24");
34
- svg.setAttribute("stroke", "currentColor");
35
- svg.setAttribute("stroke-width", "2");
36
- const path = document.createElementNS(SVG_NS, "path");
37
- path.setAttribute("stroke-linecap", "round");
38
- if (name !== "loading") path.setAttribute("stroke-linejoin", "round");
39
- path.setAttribute("d", GLYPHS[name]);
40
- svg.appendChild(path);
41
- return svg;
42
- }
43
- function div(className, text) {
44
- const el = document.createElement("div");
45
- el.className = className;
46
- if (text !== void 0) el.textContent = text;
47
- return el;
48
- }
49
- function showToast(variant, message, opts) {
50
- const opts_ = { ...defaults, ...opts };
51
- const placement = opts_.placement ?? "top";
52
- const sticky = opts_.sticky ?? false;
53
- const key = `${placement}|${variant}|${message}`;
54
- if (opts_.dedupe) {
55
- const existing = live.get(key);
56
- if (existing) {
57
- existing.restart();
58
- return { dismiss: existing.dismiss };
59
- }
60
- }
61
- if (variant !== "loading") {
62
- import('./sounds-NT4DEZGD.js').then((s) => {
63
- if (variant === "success") s.playSuccess();
64
- else if (variant === "error") s.playError();
65
- else s.playNotification();
66
- }).catch(() => {
67
- });
68
- }
69
- const container = placement === "bottom" ? getOrCreate(TOAST_BOTTOM_CONTAINER_ID, "fixed bottom-4 left-1/2 -translate-x-1/2 z-[9999] flex flex-col-reverse gap-2 items-center pointer-events-none") : getOrCreate(TOAST_CONTAINER_ID, "fixed top-4 left-1/2 -translate-x-1/2 z-[9999] flex flex-col gap-2 items-center pointer-events-none");
70
- const offscreen = placement === "bottom" ? "translateY(10px)" : "translateY(-10px)";
71
- const el = div("pointer-events-auto cursor-pointer rosh-toast");
72
- el.style.opacity = "0";
73
- el.style.transform = `${offscreen} scale(0.95)`;
74
- el.setAttribute("role", variant === "error" ? "alert" : "status");
75
- el.setAttribute("aria-atomic", "true");
76
- el.appendChild(glyph(variant, `h-4 w-4 rosh-tone-${variant}${variant === "loading" ? " animate-spin" : ""}`));
77
- const span = document.createElement("span");
78
- span.textContent = message;
79
- el.appendChild(span);
80
- container.appendChild(el);
81
- requestAnimationFrame(() => {
82
- el.style.opacity = "1";
83
- el.style.transform = "translateY(0) scale(1)";
84
- });
85
- let timer;
86
- let gone = false;
87
- const dismiss = () => {
88
- if (gone) return;
89
- gone = true;
90
- if (timer) clearTimeout(timer);
91
- live.delete(key);
92
- el.style.opacity = "0";
93
- el.style.transform = `${offscreen} scale(0.95)`;
94
- setTimeout(() => el.remove(), FADE_MS);
95
- };
96
- const duration = opts_.duration ?? (variant === "info" ? 4500 : 3e3);
97
- const restart = () => {
98
- if (timer) clearTimeout(timer);
99
- if (!sticky) timer = setTimeout(dismiss, duration);
100
- };
101
- restart();
102
- el.addEventListener("mouseenter", () => {
103
- if (timer) clearTimeout(timer);
104
- });
105
- el.addEventListener("mouseleave", () => {
106
- if (!gone) restart();
107
- });
108
- el.addEventListener("click", dismiss);
109
- live.set(key, { el, restart, dismiss });
110
- return { dismiss };
111
- }
112
- function showNotification(message, opts) {
113
- import('./sounds-NT4DEZGD.js').then((s) => s.playNotification()).catch(() => {
114
- });
115
- const container = getOrCreate(NOTIF_CONTAINER_ID, "fixed top-4 right-4 z-[9999] flex flex-col gap-3 items-end pointer-events-none");
116
- const el = div("pointer-events-auto cursor-pointer rosh-notif");
117
- el.style.opacity = "0";
118
- el.style.transform = "translateX(30px) scale(0.95)";
119
- const badge = div("rosh-notif-badge");
120
- badge.appendChild(glyph("bell", "h-5 w-5"));
121
- const body = div("rosh-notif-body");
122
- body.append(div("rosh-notif-title", currentShellStrings().toast.notification), div("notif-msg rosh-notif-msg", message));
123
- const close = document.createElement("button");
124
- close.className = "rosh-notif-close";
125
- close.textContent = "\xD7";
126
- el.append(badge, body, close);
127
- const dismiss = () => {
128
- el.style.opacity = "0";
129
- el.style.transform = "translateX(30px) scale(0.95)";
130
- setTimeout(() => el.remove(), FADE_MS);
131
- };
132
- close.addEventListener("click", (e) => {
133
- e.stopPropagation();
134
- dismiss();
135
- });
136
- el.addEventListener("click", dismiss);
137
- container.appendChild(el);
138
- requestAnimationFrame(() => {
139
- el.style.opacity = "1";
140
- el.style.transform = "translateX(0) scale(1)";
141
- });
142
- setTimeout(dismiss, opts?.duration ?? 1e4);
143
- }
144
- var toast = {
145
- success: (message, opts) => showToast("success", message, opts),
146
- error: (message, opts) => showToast("error", message, opts),
147
- /**
148
- * Something the user should read before continuing — a partial success, a
149
- * setting that will not apply until they do something else. Distinct from
150
- * `error`, which is "this did not happen".
151
- */
152
- warning: (message, opts) => showToast("warning", message, opts),
153
- info: (message, opts) => showToast("info", message, opts),
154
- // Persistent top-right notification card (the old toast.info presentation).
155
- notify: (message, opts) => showNotification(message, opts),
156
- /**
157
- * One toast for one async operation: a spinning "loading" toast while `p`
158
- * is pending, swapped for a success or error toast when it settles. The
159
- * promise is returned untouched, so `await toast.promise(save(), …)` still
160
- * throws to the caller — this narrates the operation, it does not handle it.
161
- *
162
- * `error` is REQUIRED, and there is deliberately no fallback that prints
163
- * the exception: a raw `e.message` in a toast is how internals leak to the
164
- * screen (the same reasoning that keeps ErrorBoundary's stack behind
165
- * `showDetails`). The success/error messages may be functions of the
166
- * resolved value / the rejection, for the "Saved 3 rows" case.
167
- */
168
- promise: (p, msgs, opts) => {
169
- const pending = showToast("loading", msgs.loading, { ...opts, sticky: true });
170
- p.then(
171
- (value) => {
172
- pending.dismiss();
173
- showToast("success", typeof msgs.success === "function" ? msgs.success(value) : msgs.success, opts);
174
- },
175
- (error) => {
176
- pending.dismiss();
177
- showToast("error", typeof msgs.error === "function" ? msgs.error(error) : msgs.error, opts);
178
- }
179
- );
180
- return p;
181
- },
182
- /**
183
- * Set defaults for every subsequent toast. Call once at app startup; later
184
- * calls replace the whole object rather than merging, so a consumer sets its
185
- * policy in one place. Per-call options still take precedence.
186
- */
187
- configure: (next) => {
188
- defaults = { ...next };
189
- }
190
- };
191
- var toast_default = toast;
192
-
193
- export { toast_default };
194
- //# sourceMappingURL=chunk-UTYKLGGT.js.map
195
- //# sourceMappingURL=chunk-UTYKLGGT.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/shell/toast.ts"],"names":[],"mappings":"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","file":"chunk-UTYKLGGT.js","sourcesContent":["/**\n * Two presentations:\n *\n * 1. toast.success / error / info — brief operation feedback, top-center,\n * auto-dismiss (success/error ~3s, info ~4.5s). The everyday \"what just\n * happened\" feedback — most messages want this.\n * 2. toast.notify — system notification, top-right card, stays 10s, dismissible.\n * For an alert worth lingering on; reach for it deliberately, not by default.\n *\n * (Historically `toast.info` rendered the top-right notification card; it now\n * renders a brief toast — that persistent card moved to `toast.notify`.)\n *\n * ── Built for a strict Content-Security-Policy ──\n *\n * Every node here is made with `createElement`/`createElementNS` and dressed\n * with CLASSES from ui.css (`.rosh-toast`, `.rosh-notif`…). There is no HTML\n * string, no `style=\"…\"` attribute and no `on…=` handler anywhere in the\n * markup, and that is load-bearing rather than tidy:\n *\n * - An inline handler attribute is inline SCRIPT. Under any `script-src`\n * without `'unsafe-inline'` (a nonce-based policy, which is what Next.js\n * apps run) the browser refuses it and files a violation report. The\n * notification card's close button used to carry one for its hover colour,\n * so every `toast.notify` on such a site was a CSP report.\n * - A `style` attribute that arrives through markup is governed by\n * `style-src`; a policy with a nonce or a hash there ignores\n * `'unsafe-inline'` and drops it. Styles set through the CSSOM\n * (`el.style.opacity = …`) are not, which is why the enter/leave motion\n * below still writes `el.style` directly — that is the one dynamic part.\n * - No `innerHTML` also means nothing here needs a Trusted Types policy.\n *\n * The cost is that the toast's look now lives in ui.css, which every consumer\n * already imports (alone, or inside styles.css). Its colours are custom\n * properties there (`--rosh-toast-*`) with the values it always had, so a host\n * can restyle a toast without forking it.\n * `tests/strictCsp.test.ts` holds the DOM to all of this.\n */\n\nimport { currentShellStrings } from './strings';\n\nconst TOAST_CONTAINER_ID = 'toast-container';\nconst TOAST_BOTTOM_CONTAINER_ID = 'toast-container-bottom';\nconst NOTIF_CONTAINER_ID = 'notif-container';\nconst FADE_MS = 300;\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\nexport type ToastPlacement = 'top' | 'bottom';\n\nexport interface ToastOptions {\n /** Milliseconds before auto-dismiss. Ignored when `sticky`. */\n duration?: number;\n /**\n * Stay until dismissed. For a message the user must actually act on — the\n * kind that must not scroll past while they are looking at a customer.\n * Implies tap-to-dismiss is the only way out, which it already is.\n */\n sticky?: boolean;\n /**\n * `bottom` centres toasts along the bottom edge. On a till the top of the\n * screen is the cart total and the bottom is nearest the hand.\n */\n placement?: ToastPlacement;\n /**\n * Drop a message identical to one already showing, and RESTART its timer\n * rather than stacking a second copy. A failing poll otherwise writes the\n * same sentence a dozen times. The restart matters: the user asked twice, so\n * the message should persist, not expire on the first one's schedule.\n */\n dedupe?: boolean;\n}\n\n/**\n * Defaults for every subsequent toast, set once at app startup — the same\n * \"consumer wires this once\" shape as `setShellApiClient`/`setShellNavIcons`.\n * A till calls `toast.configure({ placement: 'bottom', duration: 6000,\n * dedupe: true })` instead of repeating those options at 40 call sites.\n * Per-call options still win.\n */\nlet defaults: ToastOptions = {};\n\n/** Live toasts by dedupe key, so a repeat can find and refresh its own. */\nconst live = new Map<string, { el: HTMLElement; restart: () => void; dismiss: () => void }>();\n\nfunction getOrCreate(id: string, className: string): HTMLElement {\n let el = document.getElementById(id);\n if (!el) {\n el = document.createElement('div');\n el.id = id;\n el.className = className;\n document.body.appendChild(el);\n }\n return el;\n}\n\ntype Tone = 'success' | 'error' | 'warning' | 'info' | 'loading';\n\n/**\n * Outline glyphs (Heroicons' paths), stroked in `currentColor` so the colour\n * comes from the tone class in ui.css rather than from an attribute here.\n * `loading` is an open arc that spins — the same vocabulary as LoadingSpinner.\n */\nconst GLYPHS: Record<Tone | 'bell', string> = {\n success: 'M5 13l4 4L19 7',\n error: 'M6 18L18 6M6 6l12 12',\n warning: 'M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z',\n info: 'M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z',\n loading: 'M12 3a9 9 0 019 9',\n bell: 'M14.857 17.082a23.848 23.848 0 005.454-1.31A8.967 8.967 0 0118 9.75v-.7V9A6 6 0 006 9v.75a8.967 8.967 0 01-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 01-5.714 0m5.714 0a3 3 0 11-5.714 0',\n};\n\nfunction glyph(name: Tone | 'bell', className: string): SVGSVGElement {\n const svg = document.createElementNS(SVG_NS, 'svg');\n svg.setAttribute('class', className);\n svg.setAttribute('fill', 'none');\n svg.setAttribute('viewBox', '0 0 24 24');\n svg.setAttribute('stroke', 'currentColor');\n svg.setAttribute('stroke-width', '2');\n const path = document.createElementNS(SVG_NS, 'path');\n path.setAttribute('stroke-linecap', 'round');\n if (name !== 'loading') path.setAttribute('stroke-linejoin', 'round');\n path.setAttribute('d', GLYPHS[name]);\n svg.appendChild(path);\n return svg;\n}\n\nfunction div(className: string, text?: string): HTMLDivElement {\n const el = document.createElement('div');\n el.className = className;\n if (text !== undefined) el.textContent = text;\n return el;\n}\n\n// ── Toast (operation feedback) — top-center, brief ──\n\nfunction showToast(variant: Tone, message: string,\n opts?: ToastOptions): { dismiss: () => void } {\n const opts_ = { ...defaults, ...opts };\n const placement: ToastPlacement = opts_.placement ?? 'top';\n const sticky = opts_.sticky ?? false;\n\n // A repeat of a message already on screen refreshes it instead of stacking.\n const key = `${placement}|${variant}|${message}`;\n if (opts_.dedupe) {\n const existing = live.get(key);\n if (existing) { existing.restart(); return { dismiss: existing.dismiss }; }\n }\n\n // A loading toast is the START of an operation — the sound belongs to the\n // outcome, which follows in a moment.\n if (variant !== 'loading') {\n import('../utils/sounds').then(s => {\n if (variant === 'success') s.playSuccess();\n else if (variant === 'error') s.playError();\n else s.playNotification();\n }).catch(() => {});\n }\n\n const container = placement === 'bottom'\n ? getOrCreate(TOAST_BOTTOM_CONTAINER_ID, 'fixed bottom-4 left-1/2 -translate-x-1/2 z-[9999] flex flex-col-reverse gap-2 items-center pointer-events-none')\n : getOrCreate(TOAST_CONTAINER_ID, 'fixed top-4 left-1/2 -translate-x-1/2 z-[9999] flex flex-col gap-2 items-center pointer-events-none');\n\n // Enter from the edge the toast is anchored to, so it reads as arriving from\n // off-screen rather than drifting in from the wrong direction.\n const offscreen = placement === 'bottom' ? 'translateY(10px)' : 'translateY(-10px)';\n\n // The tone is a CLASS: `.rosh-tone-warning` and friends in ui.css colour the\n // glyph through `--rosh-toast-*`. Warning is amber and deliberately not the\n // error red: a warning is something to read before continuing, not something\n // that failed, and painting both red teaches people to ignore the colour.\n const el = div('pointer-events-auto cursor-pointer rosh-toast');\n el.style.opacity = '0';\n el.style.transform = `${offscreen} scale(0.95)`;\n // A toast IS a status message, and it appears without the user moving focus\n // — so without a live region it is announced to nobody. `alert` is\n // assertive and interrupts whatever is being read, which is right for a\n // failure and wrong for a confirmation the user already expected.\n el.setAttribute('role', variant === 'error' ? 'alert' : 'status');\n // Read the whole toast, not the word that changed. Without it a repeat that\n // only alters a number announces the number alone.\n el.setAttribute('aria-atomic', 'true');\n\n el.appendChild(glyph(variant, `h-4 w-4 rosh-tone-${variant}${variant === 'loading' ? ' animate-spin' : ''}`));\n const span = document.createElement('span');\n span.textContent = message;\n el.appendChild(span);\n\n container.appendChild(el);\n requestAnimationFrame(() => { el.style.opacity = '1'; el.style.transform = 'translateY(0) scale(1)'; });\n\n let timer: ReturnType<typeof setTimeout> | undefined;\n let gone = false;\n const dismiss = () => {\n if (gone) return;\n gone = true;\n if (timer) clearTimeout(timer);\n live.delete(key);\n el.style.opacity = '0';\n el.style.transform = `${offscreen} scale(0.95)`;\n setTimeout(() => el.remove(), FADE_MS);\n };\n\n // Info messages are usually a sentence (\"no matches — check X\"); give them a\n // beat longer to read than the terse success/error confirmations.\n const duration = opts_.duration ?? (variant === 'info' ? 4500 : 3000);\n const restart = () => {\n if (timer) clearTimeout(timer);\n if (!sticky) timer = setTimeout(dismiss, duration);\n };\n restart();\n\n // Hold the timer while the pointer rests on it. Three seconds is enough to\n // read a confirmation and not enough to read an address someone leaned in\n // for — and a toast that vanishes as you reach for it cannot be re-read at\n // all, since there is no history to open.\n el.addEventListener('mouseenter', () => { if (timer) clearTimeout(timer); });\n el.addEventListener('mouseleave', () => { if (!gone) restart(); });\n\n // Tap anywhere on the toast to dismiss it. A toast has no other click\n // affordance, and a sticky one has no other exit at all — `notify` has\n // behaved this way since it existed.\n el.addEventListener('click', dismiss);\n\n live.set(key, { el, restart, dismiss });\n // Internal handle — `toast.promise` swaps its loading toast for the outcome.\n return { dismiss };\n}\n\n// ── Notification (system alert) — top-right, stays longer ──\n\nfunction showNotification(message: string, opts?: { duration?: number }) {\n import('../utils/sounds').then(s => s.playNotification()).catch(() => {});\n\n const container = getOrCreate(NOTIF_CONTAINER_ID, 'fixed top-4 right-4 z-[9999] flex flex-col gap-3 items-end pointer-events-none');\n\n const el = div('pointer-events-auto cursor-pointer rosh-notif');\n el.style.opacity = '0';\n el.style.transform = 'translateX(30px) scale(0.95)';\n\n const badge = div('rosh-notif-badge');\n badge.appendChild(glyph('bell', 'h-5 w-5'));\n const body = div('rosh-notif-body');\n // The heading is the app's catalog word — read here, outside React.\n body.append(div('rosh-notif-title', currentShellStrings().toast.notification), div('notif-msg rosh-notif-msg', message));\n // The close button's hover colour is a `:hover` rule in ui.css. It was an\n // `onmouseenter` attribute — inline script, refused by a strict CSP.\n const close = document.createElement('button');\n close.className = 'rosh-notif-close';\n close.textContent = '×';\n el.append(badge, body, close);\n\n const dismiss = () => {\n el.style.opacity = '0';\n el.style.transform = 'translateX(30px) scale(0.95)';\n setTimeout(() => el.remove(), FADE_MS);\n };\n\n close.addEventListener('click', (e) => { e.stopPropagation(); dismiss(); });\n el.addEventListener('click', dismiss);\n\n container.appendChild(el);\n requestAnimationFrame(() => { el.style.opacity = '1'; el.style.transform = 'translateX(0) scale(1)'; });\n\n setTimeout(dismiss, opts?.duration ?? 10000);\n}\n\nconst toast = {\n success: (message: string, opts?: ToastOptions) => showToast('success', message, opts),\n error: (message: string, opts?: ToastOptions) => showToast('error', message, opts),\n /**\n * Something the user should read before continuing — a partial success, a\n * setting that will not apply until they do something else. Distinct from\n * `error`, which is \"this did not happen\".\n */\n warning: (message: string, opts?: ToastOptions) => showToast('warning', message, opts),\n info: (message: string, opts?: ToastOptions) => showToast('info', message, opts),\n // Persistent top-right notification card (the old toast.info presentation).\n notify: (message: string, opts?: { duration?: number }) => showNotification(message, opts),\n /**\n * One toast for one async operation: a spinning \"loading\" toast while `p`\n * is pending, swapped for a success or error toast when it settles. The\n * promise is returned untouched, so `await toast.promise(save(), …)` still\n * throws to the caller — this narrates the operation, it does not handle it.\n *\n * `error` is REQUIRED, and there is deliberately no fallback that prints\n * the exception: a raw `e.message` in a toast is how internals leak to the\n * screen (the same reasoning that keeps ErrorBoundary's stack behind\n * `showDetails`). The success/error messages may be functions of the\n * resolved value / the rejection, for the \"Saved 3 rows\" case.\n */\n promise: <T,>(\n p: Promise<T>,\n msgs: {\n loading: string;\n success: string | ((value: T) => string);\n error: string | ((error: unknown) => string);\n },\n opts?: ToastOptions,\n ): Promise<T> => {\n const pending = showToast('loading', msgs.loading, { ...opts, sticky: true });\n p.then(\n value => {\n pending.dismiss();\n showToast('success', typeof msgs.success === 'function' ? msgs.success(value) : msgs.success, opts);\n },\n error => {\n pending.dismiss();\n showToast('error', typeof msgs.error === 'function' ? msgs.error(error) : msgs.error, opts);\n },\n );\n return p;\n },\n /**\n * Set defaults for every subsequent toast. Call once at app startup; later\n * calls replace the whole object rather than merging, so a consumer sets its\n * policy in one place. Per-call options still take precedence.\n */\n configure: (next: ToastOptions) => { defaults = { ...next }; },\n};\n\nexport default toast;\n"]}