@buoy-gg/images 7.0.41 → 7.0.43

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 (194) hide show
  1. package/README.md +11 -70
  2. package/lib/commonjs/autoCapture.js +1 -4
  3. package/lib/commonjs/autoCapture.web.js +1 -6
  4. package/lib/commonjs/capture/actions.js +1 -243
  5. package/lib/commonjs/capture/install.js +1 -45
  6. package/lib/commonjs/capture/install.web.js +1 -250
  7. package/lib/commonjs/capture/installExpoImage.js +1 -99
  8. package/lib/commonjs/capture/installRnImage.js +1 -132
  9. package/lib/commonjs/capture/nativeImageModules.js +1 -30
  10. package/lib/commonjs/capture/nativeImageModules.web.js +1 -18
  11. package/lib/commonjs/capture/overrides.js +1 -346
  12. package/lib/commonjs/capture/rnDecoratorEarly.js +1 -55
  13. package/lib/commonjs/capture/savings.js +1 -209
  14. package/lib/commonjs/capture/savings.web.js +1 -71
  15. package/lib/commonjs/capture/shared.js +1 -378
  16. package/lib/commonjs/components/ImageDetail.js +1 -455
  17. package/lib/commonjs/components/ImageDetailFooter.js +1 -158
  18. package/lib/commonjs/components/ImageRow.js +1 -156
  19. package/lib/commonjs/components/ImagesHeader.js +1 -63
  20. package/lib/commonjs/components/ImagesIcon.js +1 -19
  21. package/lib/commonjs/components/ImagesListFooter.js +1 -126
  22. package/lib/commonjs/components/ImagesModal.js +1 -240
  23. package/lib/commonjs/components/ImagesRoot.js +1 -24
  24. package/lib/commonjs/components/ImagesRoot.web.js +1 -13
  25. package/lib/commonjs/components/InsightsBar.js +1 -59
  26. package/lib/commonjs/export.js +1 -81
  27. package/lib/commonjs/format.js +1 -117
  28. package/lib/commonjs/hooks/useImageRecords.js +1 -20
  29. package/lib/commonjs/index.js +1 -261
  30. package/lib/commonjs/preset.js +1 -39
  31. package/lib/commonjs/register.js +1 -19
  32. package/lib/commonjs/registerEarly.js +1 -14
  33. package/lib/commonjs/remote.js +1 -42
  34. package/lib/commonjs/state.js +1 -58
  35. package/lib/commonjs/store/imageEventStore.js +1 -238
  36. package/lib/commonjs/store/insights.js +1 -76
  37. package/lib/commonjs/sync/imagesSyncAdapter.js +1 -361
  38. package/lib/commonjs/types.js +0 -1
  39. package/lib/module/autoCapture.js +1 -4
  40. package/lib/module/autoCapture.web.js +1 -5
  41. package/lib/module/capture/actions.js +1 -230
  42. package/lib/module/capture/install.js +1 -40
  43. package/lib/module/capture/install.web.js +1 -243
  44. package/lib/module/capture/installExpoImage.js +1 -94
  45. package/lib/module/capture/installRnImage.js +1 -125
  46. package/lib/module/capture/nativeImageModules.js +1 -24
  47. package/lib/module/capture/nativeImageModules.web.js +1 -12
  48. package/lib/module/capture/overrides.js +1 -329
  49. package/lib/module/capture/rnDecoratorEarly.js +1 -50
  50. package/lib/module/capture/savings.js +1 -205
  51. package/lib/module/capture/savings.web.js +1 -67
  52. package/lib/module/capture/shared.js +1 -369
  53. package/lib/module/components/ImageDetail.js +1 -451
  54. package/lib/module/components/ImageDetailFooter.js +1 -154
  55. package/lib/module/components/ImageRow.js +1 -152
  56. package/lib/module/components/ImagesHeader.js +1 -59
  57. package/lib/module/components/ImagesIcon.js +1 -12
  58. package/lib/module/components/ImagesListFooter.js +1 -122
  59. package/lib/module/components/ImagesModal.js +1 -235
  60. package/lib/module/components/ImagesRoot.js +1 -20
  61. package/lib/module/components/ImagesRoot.web.js +1 -9
  62. package/lib/module/components/InsightsBar.js +1 -55
  63. package/lib/module/export.js +1 -76
  64. package/lib/module/format.js +1 -108
  65. package/lib/module/hooks/useImageRecords.js +1 -16
  66. package/lib/module/index.js +1 -79
  67. package/lib/module/preset.js +1 -35
  68. package/lib/module/register.js +1 -19
  69. package/lib/module/registerEarly.js +1 -14
  70. package/lib/module/remote.js +1 -36
  71. package/lib/module/state.js +1 -54
  72. package/lib/module/store/imageEventStore.js +1 -221
  73. package/lib/module/store/insights.js +1 -71
  74. package/lib/module/sync/imagesSyncAdapter.js +1 -356
  75. package/lib/module/types.js +0 -1
  76. package/lib/web/chunks/chunk-TTS5EH4R.mjs +1 -2
  77. package/lib/web/index.mjs +3 -4
  78. package/lib/web/register.mjs +1 -2
  79. package/package.json +3 -7
  80. package/register.js +1 -15
  81. package/lib/commonjs/autoCapture.js.map +0 -1
  82. package/lib/commonjs/autoCapture.web.js.map +0 -1
  83. package/lib/commonjs/capture/actions.js.map +0 -1
  84. package/lib/commonjs/capture/install.js.map +0 -1
  85. package/lib/commonjs/capture/install.web.js.map +0 -1
  86. package/lib/commonjs/capture/installExpoImage.js.map +0 -1
  87. package/lib/commonjs/capture/installRnImage.js.map +0 -1
  88. package/lib/commonjs/capture/nativeImageModules.js.map +0 -1
  89. package/lib/commonjs/capture/nativeImageModules.web.js.map +0 -1
  90. package/lib/commonjs/capture/overrides.js.map +0 -1
  91. package/lib/commonjs/capture/rnDecoratorEarly.js.map +0 -1
  92. package/lib/commonjs/capture/savings.js.map +0 -1
  93. package/lib/commonjs/capture/savings.web.js.map +0 -1
  94. package/lib/commonjs/capture/shared.js.map +0 -1
  95. package/lib/commonjs/components/ImageDetail.js.map +0 -1
  96. package/lib/commonjs/components/ImageDetailFooter.js.map +0 -1
  97. package/lib/commonjs/components/ImageRow.js.map +0 -1
  98. package/lib/commonjs/components/ImagesHeader.js.map +0 -1
  99. package/lib/commonjs/components/ImagesIcon.js.map +0 -1
  100. package/lib/commonjs/components/ImagesListFooter.js.map +0 -1
  101. package/lib/commonjs/components/ImagesModal.js.map +0 -1
  102. package/lib/commonjs/components/ImagesRoot.js.map +0 -1
  103. package/lib/commonjs/components/ImagesRoot.web.js.map +0 -1
  104. package/lib/commonjs/components/InsightsBar.js.map +0 -1
  105. package/lib/commonjs/export.js.map +0 -1
  106. package/lib/commonjs/format.js.map +0 -1
  107. package/lib/commonjs/hooks/useImageRecords.js.map +0 -1
  108. package/lib/commonjs/index.js.map +0 -1
  109. package/lib/commonjs/preset.js.map +0 -1
  110. package/lib/commonjs/register.js.map +0 -1
  111. package/lib/commonjs/registerEarly.js.map +0 -1
  112. package/lib/commonjs/remote.js.map +0 -1
  113. package/lib/commonjs/state.js.map +0 -1
  114. package/lib/commonjs/store/imageEventStore.js.map +0 -1
  115. package/lib/commonjs/store/insights.js.map +0 -1
  116. package/lib/commonjs/sync/imagesSyncAdapter.js.map +0 -1
  117. package/lib/commonjs/types.js.map +0 -1
  118. package/lib/module/autoCapture.js.map +0 -1
  119. package/lib/module/autoCapture.web.js.map +0 -1
  120. package/lib/module/capture/actions.js.map +0 -1
  121. package/lib/module/capture/install.js.map +0 -1
  122. package/lib/module/capture/install.web.js.map +0 -1
  123. package/lib/module/capture/installExpoImage.js.map +0 -1
  124. package/lib/module/capture/installRnImage.js.map +0 -1
  125. package/lib/module/capture/nativeImageModules.js.map +0 -1
  126. package/lib/module/capture/nativeImageModules.web.js.map +0 -1
  127. package/lib/module/capture/overrides.js.map +0 -1
  128. package/lib/module/capture/rnDecoratorEarly.js.map +0 -1
  129. package/lib/module/capture/savings.js.map +0 -1
  130. package/lib/module/capture/savings.web.js.map +0 -1
  131. package/lib/module/capture/shared.js.map +0 -1
  132. package/lib/module/components/ImageDetail.js.map +0 -1
  133. package/lib/module/components/ImageDetailFooter.js.map +0 -1
  134. package/lib/module/components/ImageRow.js.map +0 -1
  135. package/lib/module/components/ImagesHeader.js.map +0 -1
  136. package/lib/module/components/ImagesIcon.js.map +0 -1
  137. package/lib/module/components/ImagesListFooter.js.map +0 -1
  138. package/lib/module/components/ImagesModal.js.map +0 -1
  139. package/lib/module/components/ImagesRoot.js.map +0 -1
  140. package/lib/module/components/ImagesRoot.web.js.map +0 -1
  141. package/lib/module/components/InsightsBar.js.map +0 -1
  142. package/lib/module/export.js.map +0 -1
  143. package/lib/module/format.js.map +0 -1
  144. package/lib/module/hooks/useImageRecords.js.map +0 -1
  145. package/lib/module/index.js.map +0 -1
  146. package/lib/module/preset.js.map +0 -1
  147. package/lib/module/register.js.map +0 -1
  148. package/lib/module/registerEarly.js.map +0 -1
  149. package/lib/module/remote.js.map +0 -1
  150. package/lib/module/state.js.map +0 -1
  151. package/lib/module/store/imageEventStore.js.map +0 -1
  152. package/lib/module/store/insights.js.map +0 -1
  153. package/lib/module/sync/imagesSyncAdapter.js.map +0 -1
  154. package/lib/module/types.js.map +0 -1
  155. package/lib/typescript/autoCapture.d.ts.map +0 -1
  156. package/lib/typescript/autoCapture.web.d.ts.map +0 -1
  157. package/lib/typescript/capture/actions.d.ts.map +0 -1
  158. package/lib/typescript/capture/install.d.ts.map +0 -1
  159. package/lib/typescript/capture/install.web.d.ts.map +0 -1
  160. package/lib/typescript/capture/installExpoImage.d.ts.map +0 -1
  161. package/lib/typescript/capture/installRnImage.d.ts.map +0 -1
  162. package/lib/typescript/capture/nativeImageModules.d.ts.map +0 -1
  163. package/lib/typescript/capture/nativeImageModules.web.d.ts.map +0 -1
  164. package/lib/typescript/capture/overrides.d.ts.map +0 -1
  165. package/lib/typescript/capture/rnDecoratorEarly.d.ts.map +0 -1
  166. package/lib/typescript/capture/savings.d.ts.map +0 -1
  167. package/lib/typescript/capture/savings.web.d.ts.map +0 -1
  168. package/lib/typescript/capture/shared.d.ts.map +0 -1
  169. package/lib/typescript/components/ImageDetail.d.ts.map +0 -1
  170. package/lib/typescript/components/ImageDetailFooter.d.ts.map +0 -1
  171. package/lib/typescript/components/ImageRow.d.ts.map +0 -1
  172. package/lib/typescript/components/ImagesHeader.d.ts.map +0 -1
  173. package/lib/typescript/components/ImagesIcon.d.ts.map +0 -1
  174. package/lib/typescript/components/ImagesListFooter.d.ts.map +0 -1
  175. package/lib/typescript/components/ImagesModal.d.ts.map +0 -1
  176. package/lib/typescript/components/ImagesRoot.d.ts.map +0 -1
  177. package/lib/typescript/components/ImagesRoot.web.d.ts.map +0 -1
  178. package/lib/typescript/components/InsightsBar.d.ts.map +0 -1
  179. package/lib/typescript/export.d.ts.map +0 -1
  180. package/lib/typescript/format.d.ts.map +0 -1
  181. package/lib/typescript/hooks/useImageRecords.d.ts.map +0 -1
  182. package/lib/typescript/index.d.ts.map +0 -1
  183. package/lib/typescript/preset.d.ts.map +0 -1
  184. package/lib/typescript/register.d.ts.map +0 -1
  185. package/lib/typescript/registerEarly.d.ts.map +0 -1
  186. package/lib/typescript/remote.d.ts.map +0 -1
  187. package/lib/typescript/state.d.ts.map +0 -1
  188. package/lib/typescript/store/imageEventStore.d.ts.map +0 -1
  189. package/lib/typescript/store/insights.d.ts.map +0 -1
  190. package/lib/typescript/sync/imagesSyncAdapter.d.ts.map +0 -1
  191. package/lib/typescript/types.d.ts.map +0 -1
  192. package/lib/web/chunks/chunk-7CWLRQ2L.mjs +0 -2
  193. package/lib/web/chunks/chunk-B5A6CYSS.mjs +0 -2
  194. package/lib/web/chunks/chunk-LKTR6X2V.mjs +0 -2
@@ -1,55 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * InsightsBar — compact warning chips above the list when cross-record
5
- * findings exist (duplicates, retry storms, queue saturation, missing alt,
6
- * layout shifts). Renders nothing when all clear.
7
- *
8
- * A wrapping row (not a horizontal ScrollView — that under-measures its
9
- * height inside the modal's flex column and clips the chips).
10
- */
11
-
12
- import { StyleSheet, Text, View } from "react-native";
13
- import { night } from "@buoy-gg/shared-ui";
14
- import { insightChips } from "../store/insights";
15
- import { jsx as _jsx } from "react/jsx-runtime";
16
- export function InsightsBar({
17
- insights
18
- }) {
19
- const chips = insightChips(insights);
20
- if (chips.length === 0) return null;
21
- return /*#__PURE__*/_jsx(View, {
22
- style: styles.bar,
23
- children: chips.map(chip => /*#__PURE__*/_jsx(View, {
24
- style: styles.chip,
25
- children: /*#__PURE__*/_jsx(Text, {
26
- style: styles.chipText,
27
- children: chip
28
- })
29
- }, chip))
30
- });
31
- }
32
- const styles = StyleSheet.create({
33
- bar: {
34
- flexDirection: "row",
35
- flexWrap: "wrap",
36
- gap: 6,
37
- paddingHorizontal: 10,
38
- paddingVertical: 8,
39
- borderBottomWidth: StyleSheet.hairlineWidth,
40
- borderBottomColor: night.color.border
41
- },
42
- chip: {
43
- backgroundColor: night.color.warningSoft,
44
- borderRadius: 999,
45
- paddingHorizontal: 10,
46
- paddingVertical: 5
47
- },
48
- chipText: {
49
- color: night.color.warning,
50
- fontSize: 10,
51
- fontWeight: "600",
52
- lineHeight: 13
53
- }
54
- });
55
- //# sourceMappingURL=InsightsBar.js.map
1
+ "use strict";import{StyleSheet as n,Text as c,View as l}from"react-native";import{night as r}from"@buoy-gg/shared-ui";import{insightChips as d}from"../store/insights";import{jsx as o}from"react/jsx-runtime";export function InsightsBar({insights:a}){const i=d(a);if(i.length===0)return null;return o(l,{style:t.bar,children:i.map(e=>o(l,{style:t.chip,children:o(c,{style:t.chipText,children:e})},e))})}const t=n.create({bar:{flexDirection:"row",flexWrap:"wrap",gap:6,paddingHorizontal:10,paddingVertical:8,borderBottomWidth:n.hairlineWidth,borderBottomColor:r.color.border},chip:{backgroundColor:r.color.warningSoft,borderRadius:999,paddingHorizontal:10,paddingVertical:5},chipText:{color:r.color.warning,fontSize:10,fontWeight:"600",lineHeight:13}});
@@ -1,76 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Copy-friendly markdown reports — paste-ready context for an issue, PR, or
5
- * an AI chat. One for the whole registry (list header copy) and one for a
6
- * single record (detail header copy).
7
- */
8
-
9
- import { PixelRatio } from "react-native";
10
- import { estDecodedBytes, estWastedBytes, neededPixels } from "./store/imageEventStore";
11
- import { insightChips } from "./store/insights";
12
- import { cacheBadge, formatBytes, formatMs, sizeVerdict, uriTail } from "./format";
13
- export function formatRecordMarkdown(record) {
14
- const verdict = sizeVerdict(record);
15
- const cache = cacheBadge(record);
16
- const needed = neededPixels(record);
17
- const decoded = estDecodedBytes(record);
18
- const wasted = estWastedBytes(record);
19
- const lines = [];
20
- lines.push(`## Image report — ${uriTail(record.uri)}`);
21
- lines.push("");
22
- lines.push(`- URI: ${record.uri || "(none)"}`);
23
- lines.push(`- Library: ${record.lib === "expo" ? "expo-image" : "RN <Image>"} · kind: ${record.sourceKind} · mounted: ${record.mounted ? "yes" : "no"}`);
24
- lines.push(`- Status: ${record.status}${record.errorCode ? ` (HTTP ${record.errorCode})` : ""} · load cycles: ${record.loadCount}`);
25
- lines.push(`- Cache: ${cache.label}${record.cacheVerdictSource ? ` (via ${record.cacheVerdictSource === "event" ? "expo onLoad" : "Image.queryCache"})` : ""}`);
26
- lines.push(`- Load time: ${formatMs(record.durationMs)}${record.displayedAt && record.loadedAt ? ` · decode→display ${formatMs(Math.max(0, record.displayedAt - record.loadedAt))}` : ""}`);
27
- if (record.intrinsic) {
28
- lines.push(`- Decoded: ${record.intrinsic.width}×${record.intrinsic.height}px${record.mediaType ? ` (${record.mediaType})` : ""}${record.isAnimated ? " animated" : ""} ≈ ${formatBytes(decoded)} decoded memory`);
29
- }
30
- if (record.layout) {
31
- lines.push(`- Displayed: ${Math.round(record.layout.width)}×${Math.round(record.layout.height)}dp @${PixelRatio.get()}x (needs ${needed ? `${needed.width}×${needed.height}px` : "?"})`);
32
- }
33
- if (verdict.label) {
34
- lines.push(`- Size verdict: ${verdict.label}${wasted > 0 && needed ? ` — wasting ≈${formatBytes(wasted)}; serve ${needed.width}×${needed.height}` : ""}`);
35
- }
36
- if (record.progressSeen) {
37
- lines.push(`- Network transfer: ${record.bytesTotal ? formatBytes(record.bytesTotal) : "observed"}`);
38
- }
39
- if (record.hasAltText === false) lines.push(`- Accessibility: MISSING alt/accessibilityLabel`);
40
- if ((record.layoutShifts ?? 0) > 0) lines.push(`- Layout shifts after load: ${record.layoutShifts} (reserve explicit dimensions)`);
41
- if (record.error) {
42
- lines.push(`- Error: ${record.error}`);
43
- if (record.errorHeaders) {
44
- lines.push(`- Response headers: ${JSON.stringify(record.errorHeaders)}`);
45
- }
46
- }
47
- if (record.overrideLabel) lines.push(`- Simulation active: ${record.overrideLabel}`);
48
- return lines.join("\n");
49
- }
50
- export function formatRegistryMarkdown(records, stats, insights, captureStatus, modes) {
51
- const lines = [];
52
- lines.push(`## Buoy Images registry (${stats.total} records)`);
53
- lines.push("");
54
- lines.push(`${stats.loaded} loaded · ${stats.errors} failed · ${stats.loading} in flight · ≈${formatBytes(stats.estDecodedBytes)} decoded` + (stats.estWastedBytes > 0 ? ` · ${formatBytes(stats.estWastedBytes)} wasted on oversized sources` : ""));
55
- const chips = insightChips(insights);
56
- if (chips.length > 0) lines.push(`Insights: ${chips.join(" · ")}`);
57
- if (modes.network !== "normal" || modes.blank) {
58
- lines.push(`Simulation active: network=${modes.network}${modes.blank ? ", blank images" : ""}`);
59
- }
60
- if (captureStatus.rnDecoratorTooLate) {
61
- lines.push(`⚠ RN <Image> capture inactive (register import too late)`);
62
- }
63
- lines.push("");
64
- lines.push("| image | lib | status | cache | ms | decoded px | shown dp | verdict | notes |");
65
- lines.push("|---|---|---|---|---|---|---|---|---|");
66
- for (const r of records) {
67
- const verdict = sizeVerdict(r);
68
- const cache = cacheBadge(r);
69
- const dims = r.intrinsic ? `${r.intrinsic.width}×${r.intrinsic.height}` : "–";
70
- const layout = r.layout ? `${Math.round(r.layout.width)}×${Math.round(r.layout.height)}` : "–";
71
- const notes = [r.error ? `error: ${r.error}` : null, r.overrideLabel ? `sim: ${r.overrideLabel}` : null, r.hasAltText === false ? "no alt" : null, (r.layoutShifts ?? 0) > 0 ? `${r.layoutShifts} layout shifts` : null, r.mounted ? null : "unmounted"].filter(Boolean).join("; ");
72
- lines.push(`| ${uriTail(r.uri)} | ${r.lib} | ${r.status} | ${cache.label} | ${r.durationMs != null ? Math.round(r.durationMs) : "–"} | ${dims} | ${layout} | ${verdict.label || "–"} | ${notes || "–"} |`);
73
- }
74
- return lines.join("\n");
75
- }
76
- //# sourceMappingURL=export.js.map
1
+ "use strict";import{PixelRatio as g}from"react-native";import{estDecodedBytes as b,estWastedBytes as v,neededPixels as w}from"./store/imageEventStore";import{insightChips as x}from"./store/insights";import{cacheBadge as h,formatBytes as l,formatMs as $,sizeVerdict as d,uriTail as p}from"./format";export function formatRecordMarkdown(e){const a=d(e);const u=h(e);const n=w(e);const o=b(e);const s=v(e);const i=[];i.push(`## Image report \u2014 ${p(e.uri)}`);i.push("");i.push(`- URI: ${e.uri||"(none)"}`);i.push(`- Library: ${e.lib==="expo"?"expo-image":"RN <Image>"} \xB7 kind: ${e.sourceKind} \xB7 mounted: ${e.mounted?"yes":"no"}`);i.push(`- Status: ${e.status}${e.errorCode?` (HTTP ${e.errorCode})`:""} \xB7 load cycles: ${e.loadCount}`);i.push(`- Cache: ${u.label}${e.cacheVerdictSource?` (via ${e.cacheVerdictSource==="event"?"expo onLoad":"Image.queryCache"})`:""}`);i.push(`- Load time: ${$(e.durationMs)}${e.displayedAt&&e.loadedAt?` \xB7 decode\u2192display ${$(Math.max(0,e.displayedAt-e.loadedAt))}`:""}`);if(e.intrinsic){i.push(`- Decoded: ${e.intrinsic.width}\xD7${e.intrinsic.height}px${e.mediaType?` (${e.mediaType})`:""}${e.isAnimated?" animated":""} \u2248 ${l(o)} decoded memory`)}if(e.layout){i.push(`- Displayed: ${Math.round(e.layout.width)}\xD7${Math.round(e.layout.height)}dp @${g.get()}x (needs ${n?`${n.width}\xD7${n.height}px`:"?"})`)}if(a.label){i.push(`- Size verdict: ${a.label}${s>0&&n?` \u2014 wasting \u2248${l(s)}; serve ${n.width}\xD7${n.height}`:""}`)}if(e.progressSeen){i.push(`- Network transfer: ${e.bytesTotal?l(e.bytesTotal):"observed"}`)}if(e.hasAltText===false)i.push(`- Accessibility: MISSING alt/accessibilityLabel`);if((e.layoutShifts??0)>0)i.push(`- Layout shifts after load: ${e.layoutShifts} (reserve explicit dimensions)`);if(e.error){i.push(`- Error: ${e.error}`);if(e.errorHeaders){i.push(`- Response headers: ${JSON.stringify(e.errorHeaders)}`)}}if(e.overrideLabel)i.push(`- Simulation active: ${e.overrideLabel}`);return i.join("\n")}export function formatRegistryMarkdown(e,a,u,n,o){const s=[];s.push(`## Buoy Images registry (${a.total} records)`);s.push("");s.push(`${a.loaded} loaded \xB7 ${a.errors} failed \xB7 ${a.loading} in flight \xB7 \u2248${l(a.estDecodedBytes)} decoded`+(a.estWastedBytes>0?` \xB7 ${l(a.estWastedBytes)} wasted on oversized sources`:""));const i=x(u);if(i.length>0)s.push(`Insights: ${i.join(" \xB7 ")}`);if(o.network!=="normal"||o.blank){s.push(`Simulation active: network=${o.network}${o.blank?", blank images":""}`)}if(n.rnDecoratorTooLate){s.push(`\u26A0 RN <Image> capture inactive (register import too late)`)}s.push("");s.push("| image | lib | status | cache | ms | decoded px | shown dp | verdict | notes |");s.push("|---|---|---|---|---|---|---|---|---|");for(const t of e){const r=d(t);const f=h(t);const y=t.intrinsic?`${t.intrinsic.width}\xD7${t.intrinsic.height}`:"\u2013";const m=t.layout?`${Math.round(t.layout.width)}\xD7${Math.round(t.layout.height)}`:"\u2013";const c=[t.error?`error: ${t.error}`:null,t.overrideLabel?`sim: ${t.overrideLabel}`:null,t.hasAltText===false?"no alt":null,(t.layoutShifts??0)>0?`${t.layoutShifts} layout shifts`:null,t.mounted?null:"unmounted"].filter(Boolean).join("; ");s.push(`| ${p(t.uri)} | ${t.lib} | ${t.status} | ${f.label} | ${t.durationMs!=null?Math.round(t.durationMs):"\u2013"} | ${y} | ${m} | ${r.label||"\u2013"} | ${c||"\u2013"} |`)}return s.join("\n")}
@@ -1,108 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Formatting + verdict helpers shared by list rows and the detail view.
5
- */
6
-
7
- import { macOSColors, night } from "@buoy-gg/shared-ui";
8
- import { oversizeFactor } from "./store/imageEventStore";
9
- export function formatBytes(bytes) {
10
- if (bytes <= 0) return "0 B";
11
- if (bytes < 1024) return `${bytes} B`;
12
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
13
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
14
- }
15
- export function formatMs(ms) {
16
- if (ms == null) return "—";
17
- if (ms < 1000) return `${Math.round(ms)}ms`;
18
- return `${(ms / 1000).toFixed(2)}s`;
19
- }
20
-
21
- /** Last path segment of a URI, for compact row display. */
22
- export function uriTail(uri) {
23
- if (!uri) return "(no source)";
24
- // Metro dev-server asset URLs put the real path in ?unstable_path=…
25
- const unstable = uri.match(/[?&]unstable_path=([^&?]+)/);
26
- const effective = unstable ? decodeURIComponent(unstable[1]) : uri;
27
- const withoutQuery = effective.split("?")[0] ?? effective;
28
- const segments = withoutQuery.split("/").filter(Boolean);
29
- return segments[segments.length - 1] ?? effective;
30
- }
31
- /**
32
- * Fresco-style fit verdict: green within 10%, yellow within 50%, red beyond.
33
- * Undersized sources (upscaled, likely blurry) get their own callout.
34
- */
35
- export function sizeVerdict(record) {
36
- const factor = oversizeFactor(record);
37
- if (factor == null) return {
38
- label: "",
39
- color: night.color.textTertiary,
40
- factor
41
- };
42
- if (factor < 0.9) {
43
- return {
44
- label: `${factor.toFixed(1)}× upscaled`,
45
- color: macOSColors.semantic.info,
46
- factor
47
- };
48
- }
49
- if (factor <= 1.1) {
50
- return {
51
- label: "right-sized",
52
- color: macOSColors.semantic.success,
53
- factor
54
- };
55
- }
56
- if (factor <= 1.5) {
57
- return {
58
- label: `${factor.toFixed(1)}× oversized`,
59
- color: macOSColors.semantic.warning,
60
- factor
61
- };
62
- }
63
- return {
64
- label: `${factor.toFixed(1)}× oversized`,
65
- color: macOSColors.semantic.error,
66
- factor
67
- };
68
- }
69
- export function statusColor(record) {
70
- switch (record.status) {
71
- case "loaded":
72
- return macOSColors.semantic.success;
73
- case "error":
74
- return macOSColors.semantic.error;
75
- case "loading":
76
- return macOSColors.semantic.warning;
77
- default:
78
- return night.color.textTertiary;
79
- }
80
- }
81
-
82
- /** Cache verdict badge text + tint (memory=green, disk=yellow, network=red). */
83
- export function cacheBadge(record) {
84
- const verdict = record.cacheVerdict;
85
- if (verdict === "memory" || verdict === "disk/memory") {
86
- return {
87
- label: verdict.toUpperCase(),
88
- color: macOSColors.semantic.success
89
- };
90
- }
91
- if (verdict === "disk") {
92
- return {
93
- label: "DISK",
94
- color: macOSColors.semantic.warning
95
- };
96
- }
97
- if (verdict === "none" || record.progressSeen) {
98
- return {
99
- label: "NETWORK",
100
- color: macOSColors.semantic.error
101
- };
102
- }
103
- return {
104
- label: "?",
105
- color: night.color.textTertiary
106
- };
107
- }
108
- //# sourceMappingURL=format.js.map
1
+ "use strict";import{macOSColors as t,night as n}from"@buoy-gg/shared-ui";import{oversizeFactor as a}from"./store/imageEventStore";export function formatBytes(r){if(r<=0)return"0 B";if(r<1024)return`${r} B`;if(r<1024*1024)return`${(r/1024).toFixed(1)} KB`;return`${(r/(1024*1024)).toFixed(1)} MB`}export function formatMs(r){if(r==null)return"\u2014";if(r<1e3)return`${Math.round(r)}ms`;return`${(r/1e3).toFixed(2)}s`}export function uriTail(r){if(!r)return"(no source)";const e=r.match(/[?&]unstable_path=([^&?]+)/);const o=e?decodeURIComponent(e[1]):r;const c=o.split("?")[0]??o;const i=c.split("/").filter(Boolean);return i[i.length-1]??o}export function sizeVerdict(r){const e=a(r);if(e==null)return{label:"",color:n.color.textTertiary,factor:e};if(e<.9){return{label:`${e.toFixed(1)}\xD7 upscaled`,color:t.semantic.info,factor:e}}if(e<=1.1){return{label:"right-sized",color:t.semantic.success,factor:e}}if(e<=1.5){return{label:`${e.toFixed(1)}\xD7 oversized`,color:t.semantic.warning,factor:e}}return{label:`${e.toFixed(1)}\xD7 oversized`,color:t.semantic.error,factor:e}}export function statusColor(r){switch(r.status){case"loaded":return t.semantic.success;case"error":return t.semantic.error;case"loading":return t.semantic.warning;default:return n.color.textTertiary}}export function cacheBadge(r){const e=r.cacheVerdict;if(e==="memory"||e==="disk/memory"){return{label:e.toUpperCase(),color:t.semantic.success}}if(e==="disk"){return{label:"DISK",color:t.semantic.warning}}if(e==="none"||r.progressSeen){return{label:"NETWORK",color:t.semantic.error}}return{label:"?",color:n.color.textTertiary}}
@@ -1,16 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * React bindings for the image event store.
5
- */
6
-
7
- import { useMemo, useSyncExternalStore } from "react";
8
- import { computeStats, getSnapshot, subscribe } from "../store/imageEventStore";
9
- export function useImageRecords() {
10
- const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
11
- return useMemo(() => ({
12
- records: [...snapshot].reverse(),
13
- stats: computeStats(snapshot)
14
- }), [snapshot]);
15
- }
16
- //# sourceMappingURL=useImageRecords.js.map
1
+ "use strict";import{useMemo as s,useSyncExternalStore as r}from"react";import{computeStats as o,getSnapshot as t,subscribe as c}from"../store/imageEventStore";export function useImageRecords(){const e=r(c,t,t);return s(()=>({records:[...e].reverse(),stats:o(e)}),[e])}
@@ -1,79 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * @buoy-gg/images
5
- *
6
- * Image debugger for React Native: a live registry of every image the app
7
- * loads — RN core <Image> (via the official component-decorator hook) and
8
- * expo-image (via a timing-immune class patch) — with cache verdicts
9
- * (memory/disk/network), load timings, decoded-vs-displayed oversize checks,
10
- * estimated decoded/wasted memory, and a failure log with HTTP details where
11
- * the platform provides them.
12
- *
13
- * Image HTTP traffic never touches the JS network stack, so network devtools
14
- * cannot see it — this tool is the visibility layer for images.
15
- */
16
-
17
- // Side-effect: install capture as early as this package is imported. For full
18
- // RN-core coverage, import "@buoy-gg/images/register" FIRST in your entry file
19
- // (the RN decorator must beat React Native's Image module evaluation).
20
- import "./autoCapture";
21
-
22
- // =============================================================================
23
- // PRESET (Primary entry point — pass to <FloatingDevTools apps={[...]} />)
24
- // =============================================================================
25
- export { imagesToolPreset, createImagesTool } from "./preset";
26
-
27
- // =============================================================================
28
- // ROOT (optional; capture also auto-installs on package import)
29
- // =============================================================================
30
- export { ImagesRoot } from "./components/ImagesRoot";
31
-
32
- // =============================================================================
33
- // COMPONENTS
34
- // =============================================================================
35
- export { ImagesModal } from "./components/ImagesModal";
36
- export { ImagesIcon, IMAGES_ICON_COLOR } from "./components/ImagesIcon";
37
-
38
- // =============================================================================
39
- // CAPTURE
40
- // =============================================================================
41
- export { installImageCapture, getCaptureStatus } from "./capture/install";
42
-
43
- // =============================================================================
44
- // ACTIONS
45
- // =============================================================================
46
- export { hardReloadRecord, retryRecord, evictExpoDiskEntry } from "./capture/actions";
47
- // =============================================================================
48
- // SIMULATION OVERRIDES
49
- // =============================================================================
50
- export { setOverride, clearOverride, getOverride, flashRecord, setNetworkMode, setBlankImages, getGlobalModes, setOverrideForAllMounted, clearAllOverrides, flashAllMounted } from "./capture/overrides";
51
- export { hardReloadAllMounted } from "./capture/actions";
52
- // =============================================================================
53
- // SAVINGS PROVER + INSIGHTS
54
- // =============================================================================
55
- export { proveSavings } from "./capture/savings";
56
- export { computeInsights, insightChips } from "./store/insights";
57
- export { formatRecordMarkdown, formatRegistryMarkdown } from "./export";
58
-
59
- // =============================================================================
60
- // EXTERNAL SYNC (device → desktop dashboard / MCP)
61
- // =============================================================================
62
- export { imagesSyncAdapter } from "./sync/imagesSyncAdapter";
63
-
64
- // =============================================================================
65
- // DASHBOARD MIRROR (Buoy Desktop renders ImagesToolView fed by these)
66
- // =============================================================================
67
- export { ImagesToolView } from "./components/ImagesModal";
68
- export { disableImagesCapture, replaceImagesFromSnapshot } from "./store/imageEventStore";
69
- export { setRemoteImagesHandler } from "./remote";
70
- // =============================================================================
71
- // STORE + HOOKS
72
- // =============================================================================
73
- export { useImageRecords } from "./hooks/useImageRecords";
74
- export { clearRecords, getSnapshot as getImageRecords, subscribe as subscribeImageRecords, computeStats, oversizeFactor, estDecodedBytes, estWastedBytes } from "./store/imageEventStore";
75
-
76
- // =============================================================================
77
- // TYPES
78
- // =============================================================================
79
- //# sourceMappingURL=index.js.map
1
+ "use strict";import"./autoCapture";export{imagesToolPreset,createImagesTool}from"./preset";export{ImagesRoot}from"./components/ImagesRoot";export{ImagesModal}from"./components/ImagesModal";export{ImagesIcon,IMAGES_ICON_COLOR}from"./components/ImagesIcon";export{installImageCapture,getCaptureStatus}from"./capture/install";export{hardReloadRecord,retryRecord,evictExpoDiskEntry}from"./capture/actions";export{setOverride,clearOverride,getOverride,flashRecord,setNetworkMode,setBlankImages,getGlobalModes,setOverrideForAllMounted,clearAllOverrides,flashAllMounted}from"./capture/overrides";export{hardReloadAllMounted}from"./capture/actions";export{proveSavings}from"./capture/savings";export{computeInsights,insightChips}from"./store/insights";export{formatRecordMarkdown,formatRegistryMarkdown}from"./export";export{imagesSyncAdapter}from"./sync/imagesSyncAdapter";export{ImagesToolView}from"./components/ImagesModal";export{disableImagesCapture,replaceImagesFromSnapshot}from"./store/imageEventStore";export{setRemoteImagesHandler}from"./remote";export{useImageRecords}from"./hooks/useImageRecords";export{clearRecords,getSnapshot as getImageRecords,subscribe as subscribeImageRecords,computeStats,oversizeFactor,estDecodedBytes,estWastedBytes}from"./store/imageEventStore";
@@ -1,35 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Pre-configured Images tool for FloatingDevTools.
5
- *
6
- * @example
7
- * ```tsx
8
- * import { imagesToolPreset } from '@buoy-gg/images';
9
- *
10
- * <FloatingDevTools apps={[imagesToolPreset]} />
11
- * ```
12
- */
13
-
14
- import { ImagesIcon, IMAGES_ICON_COLOR } from "./components/ImagesIcon";
15
- import { ImagesModal } from "./components/ImagesModal";
16
- import { createToolFactory, defineToolPreset } from "@buoy-gg/shared-ui";
17
- import { jsx as _jsx } from "react/jsx-runtime";
18
- export const imagesToolPreset = defineToolPreset({
19
- id: "images",
20
- name: "IMAGES",
21
- description: "Image loads, caching, failures, and oversize checks",
22
- slot: "both",
23
- icon: ({
24
- size,
25
- color
26
- }) => /*#__PURE__*/_jsx(ImagesIcon, {
27
- size: size,
28
- color: color || IMAGES_ICON_COLOR
29
- }),
30
- component: ImagesModal
31
- });
32
-
33
- /** Create a custom Images tool configuration. */
34
- export const createImagesTool = createToolFactory(imagesToolPreset);
35
- //# sourceMappingURL=preset.js.map
1
+ "use strict";import{ImagesIcon as s,IMAGES_ICON_COLOR as r}from"./components/ImagesIcon";import{ImagesModal as t}from"./components/ImagesModal";import{createToolFactory as a,defineToolPreset as i}from"@buoy-gg/shared-ui";import{jsx as m}from"react/jsx-runtime";export const imagesToolPreset=i({id:"images",name:"IMAGES",description:"Image loads, caching, failures, and oversize checks",slot:"both",icon:({size:o,color:e})=>m(s,{size:o,color:e||r}),component:t});export const createImagesTool=a(imagesToolPreset);
@@ -1,19 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Side-effect entry: installs image capture on import.
5
- *
6
- * Import this FIRST in your app entry file so the RN-core <Image> decorator
7
- * lands before React Native's Image module is evaluated:
8
- *
9
- * ```ts
10
- * import "@buoy-gg/images/register";
11
- * ```
12
- *
13
- * This module intentionally imports nothing that touches react-native's Image
14
- * (directly or transitively) before installing.
15
- */
16
-
17
- import { installImageCapture } from "./capture/install";
18
- installImageCapture();
19
- //# sourceMappingURL=register.js.map
1
+ "use strict";import{installImageCapture as t}from"./capture/install";t();
@@ -1,14 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Pre-InitializeCore entry: registers the RN <Image> decorator only.
5
- *
6
- * Use when `@buoy-gg/images/register` reports "missed the module-load race"
7
- * (development builds load <Image> inside InitializeCore via LogBox). Add it as
8
- * a Metro pre-main module ahead of InitializeCore, and keep the regular
9
- * `register` import in the entry file for the rest of the capture setup.
10
- */
11
-
12
- import { installRnImageDecoratorEarly } from "./capture/rnDecoratorEarly";
13
- installRnImageDecoratorEarly();
14
- //# sourceMappingURL=registerEarly.js.map
1
+ "use strict";import{installRnImageDecoratorEarly as r}from"./capture/rnDecoratorEarly";r();
@@ -1,36 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Remote-dispatch seam for dashboard mirrors (Buoy Desktop).
5
- *
6
- * On device this stays null and every action in capture/ runs locally. A
7
- * dashboard sets a handler that forwards the action name + params over the
8
- * external-sync protocol to the SAME adapter actions the MCP uses
9
- * (sync/imagesSyncAdapter.ts), so one action vocabulary serves phone UI,
10
- * desktop UI, and LLM automation.
11
- */
12
-
13
- import { imagesState } from "./state";
14
- export function setRemoteImagesHandler(handler) {
15
- imagesState().remoteDispatch = handler;
16
- }
17
- export function remoteImagesDispatch() {
18
- return imagesState().remoteDispatch;
19
- }
20
-
21
- /** Coerce an adapter action's `{ ok, message }` reply into an ActionResult. */
22
- export async function remoteActionResult(call) {
23
- try {
24
- const result = await call;
25
- return {
26
- ok: !!result?.ok,
27
- message: String(result?.message ?? "")
28
- };
29
- } catch (error) {
30
- return {
31
- ok: false,
32
- message: String(error?.message ?? error)
33
- };
34
- }
35
- }
36
- //# sourceMappingURL=remote.js.map
1
+ "use strict";import{imagesState as r}from"./state";export function setRemoteImagesHandler(t){r().remoteDispatch=t}export function remoteImagesDispatch(){return r().remoteDispatch}export async function remoteActionResult(t){try{const e=await t;return{ok:!!e?.ok,message:String(e?.message??"")}}catch(e){return{ok:false,message:String(e?.message??e)}}}
@@ -1,54 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Global singleton state for the Images tool.
5
- *
6
- * The package can get evaluated twice as two separate module instances (e.g.
7
- * the `/register` entry shim resolving to one copy while the package root
8
- * import resolves to another — lib vs src). If capture state lived in module
9
- * scope, the early copy would install the RN decorator and collect records
10
- * while the UI copy read an empty store and a false "decorator never ran"
11
- * flag. Keying all mutable state on globalThis under a well-known symbol makes
12
- * every copy operate on the same data.
13
- */
14
-
15
- const KEY = Symbol.for("buoy.images.globalState.v1");
16
- export function imagesState() {
17
- const g = globalThis;
18
- if (!g[KEY]) {
19
- g[KEY] = {
20
- records: [],
21
- byId: new Map(),
22
- nextId: 1,
23
- listeners: new Set(),
24
- snapshot: [],
25
- emitScheduled: false,
26
- captureInstalled: false,
27
- rnInstalled: false,
28
- expoInstalled: false,
29
- decoratorRegistered: false,
30
- decoratorInvoked: false,
31
- attachSeen: 0,
32
- expoAvailable: false,
33
- expoPatched: false,
34
- reloadRequests: new Map(),
35
- actionListeners: new Set(),
36
- expoInstances: new Map(),
37
- overrides: new Map(),
38
- flashUntil: new Map(),
39
- recordVersions: new Map(),
40
- globalVersion: 0,
41
- versionCounter: 0,
42
- globalModes: {
43
- network: "normal",
44
- blank: false
45
- },
46
- captureDisabled: false,
47
- remoteDispatch: null,
48
- mirrorPixelRatio: null,
49
- mirrorCaptureStatus: null
50
- };
51
- }
52
- return g[KEY];
53
- }
54
- //# sourceMappingURL=state.js.map
1
+ "use strict";const a=Symbol.for("buoy.images.globalState.v1");export function imagesState(){const e=globalThis;if(!e[a]){e[a]={records:[],byId:new Map,nextId:1,listeners:new Set,snapshot:[],emitScheduled:false,captureInstalled:false,rnInstalled:false,expoInstalled:false,decoratorRegistered:false,decoratorInvoked:false,attachSeen:0,expoAvailable:false,expoPatched:false,reloadRequests:new Map,actionListeners:new Set,expoInstances:new Map,overrides:new Map,flashUntil:new Map,recordVersions:new Map,globalVersion:0,versionCounter:0,globalModes:{network:"normal",blank:false},captureDisabled:false,remoteDispatch:null,mirrorPixelRatio:null,mirrorCaptureStatus:null}}return e[a]}