@buoy-gg/images 7.0.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.
Files changed (195) hide show
  1. package/LICENSE +58 -0
  2. package/README.md +58 -0
  3. package/lib/commonjs/capture/actions.js +227 -0
  4. package/lib/commonjs/capture/actions.js.map +1 -0
  5. package/lib/commonjs/capture/install.js +41 -0
  6. package/lib/commonjs/capture/install.js.map +1 -0
  7. package/lib/commonjs/capture/installExpoImage.js +99 -0
  8. package/lib/commonjs/capture/installExpoImage.js.map +1 -0
  9. package/lib/commonjs/capture/installRnImage.js +128 -0
  10. package/lib/commonjs/capture/installRnImage.js.map +1 -0
  11. package/lib/commonjs/capture/overrides.js +286 -0
  12. package/lib/commonjs/capture/overrides.js.map +1 -0
  13. package/lib/commonjs/capture/savings.js +193 -0
  14. package/lib/commonjs/capture/savings.js.map +1 -0
  15. package/lib/commonjs/capture/shared.js +367 -0
  16. package/lib/commonjs/capture/shared.js.map +1 -0
  17. package/lib/commonjs/components/ImageDetail.js +444 -0
  18. package/lib/commonjs/components/ImageDetail.js.map +1 -0
  19. package/lib/commonjs/components/ImageDetailFooter.js +232 -0
  20. package/lib/commonjs/components/ImageDetailFooter.js.map +1 -0
  21. package/lib/commonjs/components/ImageRow.js +164 -0
  22. package/lib/commonjs/components/ImageRow.js.map +1 -0
  23. package/lib/commonjs/components/ImagesHeader.js +63 -0
  24. package/lib/commonjs/components/ImagesHeader.js.map +1 -0
  25. package/lib/commonjs/components/ImagesIcon.js +59 -0
  26. package/lib/commonjs/components/ImagesIcon.js.map +1 -0
  27. package/lib/commonjs/components/ImagesListFooter.js +194 -0
  28. package/lib/commonjs/components/ImagesListFooter.js.map +1 -0
  29. package/lib/commonjs/components/ImagesModal.js +173 -0
  30. package/lib/commonjs/components/ImagesModal.js.map +1 -0
  31. package/lib/commonjs/components/ImagesRoot.js +24 -0
  32. package/lib/commonjs/components/ImagesRoot.js.map +1 -0
  33. package/lib/commonjs/components/InsightsBar.js +59 -0
  34. package/lib/commonjs/components/InsightsBar.js.map +1 -0
  35. package/lib/commonjs/export.js +81 -0
  36. package/lib/commonjs/export.js.map +1 -0
  37. package/lib/commonjs/format.js +117 -0
  38. package/lib/commonjs/format.js.map +1 -0
  39. package/lib/commonjs/hooks/useImageRecords.js +20 -0
  40. package/lib/commonjs/hooks/useImageRecords.js.map +1 -0
  41. package/lib/commonjs/index.js +236 -0
  42. package/lib/commonjs/index.js.map +1 -0
  43. package/lib/commonjs/package.json +1 -0
  44. package/lib/commonjs/preset.js +45 -0
  45. package/lib/commonjs/preset.js.map +1 -0
  46. package/lib/commonjs/register.js +19 -0
  47. package/lib/commonjs/register.js.map +1 -0
  48. package/lib/commonjs/state.js +54 -0
  49. package/lib/commonjs/state.js.map +1 -0
  50. package/lib/commonjs/store/imageEventStore.js +160 -0
  51. package/lib/commonjs/store/imageEventStore.js.map +1 -0
  52. package/lib/commonjs/store/insights.js +76 -0
  53. package/lib/commonjs/store/insights.js.map +1 -0
  54. package/lib/commonjs/sync/imagesSyncAdapter.js +315 -0
  55. package/lib/commonjs/sync/imagesSyncAdapter.js.map +1 -0
  56. package/lib/commonjs/types.js +2 -0
  57. package/lib/commonjs/types.js.map +1 -0
  58. package/lib/module/capture/actions.js +214 -0
  59. package/lib/module/capture/actions.js.map +1 -0
  60. package/lib/module/capture/install.js +36 -0
  61. package/lib/module/capture/install.js.map +1 -0
  62. package/lib/module/capture/installExpoImage.js +94 -0
  63. package/lib/module/capture/installExpoImage.js.map +1 -0
  64. package/lib/module/capture/installRnImage.js +122 -0
  65. package/lib/module/capture/installRnImage.js.map +1 -0
  66. package/lib/module/capture/overrides.js +269 -0
  67. package/lib/module/capture/overrides.js.map +1 -0
  68. package/lib/module/capture/savings.js +189 -0
  69. package/lib/module/capture/savings.js.map +1 -0
  70. package/lib/module/capture/shared.js +359 -0
  71. package/lib/module/capture/shared.js.map +1 -0
  72. package/lib/module/components/ImageDetail.js +440 -0
  73. package/lib/module/components/ImageDetail.js.map +1 -0
  74. package/lib/module/components/ImageDetailFooter.js +228 -0
  75. package/lib/module/components/ImageDetailFooter.js.map +1 -0
  76. package/lib/module/components/ImageRow.js +160 -0
  77. package/lib/module/components/ImageRow.js.map +1 -0
  78. package/lib/module/components/ImagesHeader.js +59 -0
  79. package/lib/module/components/ImagesHeader.js.map +1 -0
  80. package/lib/module/components/ImagesIcon.js +55 -0
  81. package/lib/module/components/ImagesIcon.js.map +1 -0
  82. package/lib/module/components/ImagesListFooter.js +190 -0
  83. package/lib/module/components/ImagesListFooter.js.map +1 -0
  84. package/lib/module/components/ImagesModal.js +169 -0
  85. package/lib/module/components/ImagesModal.js.map +1 -0
  86. package/lib/module/components/ImagesRoot.js +20 -0
  87. package/lib/module/components/ImagesRoot.js.map +1 -0
  88. package/lib/module/components/InsightsBar.js +55 -0
  89. package/lib/module/components/InsightsBar.js.map +1 -0
  90. package/lib/module/export.js +76 -0
  91. package/lib/module/export.js.map +1 -0
  92. package/lib/module/format.js +108 -0
  93. package/lib/module/format.js.map +1 -0
  94. package/lib/module/hooks/useImageRecords.js +16 -0
  95. package/lib/module/hooks/useImageRecords.js.map +1 -0
  96. package/lib/module/index.js +73 -0
  97. package/lib/module/index.js.map +1 -0
  98. package/lib/module/preset.js +40 -0
  99. package/lib/module/preset.js.map +1 -0
  100. package/lib/module/register.js +19 -0
  101. package/lib/module/register.js.map +1 -0
  102. package/lib/module/state.js +50 -0
  103. package/lib/module/state.js.map +1 -0
  104. package/lib/module/store/imageEventStore.js +146 -0
  105. package/lib/module/store/imageEventStore.js.map +1 -0
  106. package/lib/module/store/insights.js +71 -0
  107. package/lib/module/store/insights.js.map +1 -0
  108. package/lib/module/sync/imagesSyncAdapter.js +311 -0
  109. package/lib/module/sync/imagesSyncAdapter.js.map +1 -0
  110. package/lib/module/types.js +2 -0
  111. package/lib/module/types.js.map +1 -0
  112. package/lib/typescript/capture/actions.d.ts +49 -0
  113. package/lib/typescript/capture/actions.d.ts.map +1 -0
  114. package/lib/typescript/capture/install.d.ts +15 -0
  115. package/lib/typescript/capture/install.d.ts.map +1 -0
  116. package/lib/typescript/capture/installExpoImage.d.ts +23 -0
  117. package/lib/typescript/capture/installExpoImage.d.ts.map +1 -0
  118. package/lib/typescript/capture/installRnImage.d.ts +24 -0
  119. package/lib/typescript/capture/installRnImage.d.ts.map +1 -0
  120. package/lib/typescript/capture/overrides.d.ts +83 -0
  121. package/lib/typescript/capture/overrides.d.ts.map +1 -0
  122. package/lib/typescript/capture/savings.d.ts +37 -0
  123. package/lib/typescript/capture/savings.d.ts.map +1 -0
  124. package/lib/typescript/capture/shared.d.ts +61 -0
  125. package/lib/typescript/capture/shared.d.ts.map +1 -0
  126. package/lib/typescript/components/ImageDetail.d.ts +13 -0
  127. package/lib/typescript/components/ImageDetail.d.ts.map +1 -0
  128. package/lib/typescript/components/ImageDetailFooter.d.ts +19 -0
  129. package/lib/typescript/components/ImageDetailFooter.d.ts.map +1 -0
  130. package/lib/typescript/components/ImageRow.d.ts +15 -0
  131. package/lib/typescript/components/ImageRow.d.ts.map +1 -0
  132. package/lib/typescript/components/ImagesHeader.d.ts +25 -0
  133. package/lib/typescript/components/ImagesHeader.d.ts.map +1 -0
  134. package/lib/typescript/components/ImagesIcon.d.ts +13 -0
  135. package/lib/typescript/components/ImagesIcon.d.ts.map +1 -0
  136. package/lib/typescript/components/ImagesListFooter.d.ts +8 -0
  137. package/lib/typescript/components/ImagesListFooter.d.ts.map +1 -0
  138. package/lib/typescript/components/ImagesModal.d.ts +17 -0
  139. package/lib/typescript/components/ImagesModal.d.ts.map +1 -0
  140. package/lib/typescript/components/ImagesRoot.d.ts +11 -0
  141. package/lib/typescript/components/ImagesRoot.d.ts.map +1 -0
  142. package/lib/typescript/components/InsightsBar.d.ts +13 -0
  143. package/lib/typescript/components/InsightsBar.d.ts.map +1 -0
  144. package/lib/typescript/export.d.ts +12 -0
  145. package/lib/typescript/export.d.ts.map +1 -0
  146. package/lib/typescript/format.d.ts +26 -0
  147. package/lib/typescript/format.d.ts.map +1 -0
  148. package/lib/typescript/hooks/useImageRecords.d.ts +11 -0
  149. package/lib/typescript/hooks/useImageRecords.d.ts.map +1 -0
  150. package/lib/typescript/index.d.ts +33 -0
  151. package/lib/typescript/index.d.ts.map +1 -0
  152. package/lib/typescript/preset.d.ts +38 -0
  153. package/lib/typescript/preset.d.ts.map +1 -0
  154. package/lib/typescript/register.d.ts +15 -0
  155. package/lib/typescript/register.d.ts.map +1 -0
  156. package/lib/typescript/state.d.ts +54 -0
  157. package/lib/typescript/state.d.ts.map +1 -0
  158. package/lib/typescript/store/imageEventStore.d.ts +34 -0
  159. package/lib/typescript/store/imageEventStore.d.ts.map +1 -0
  160. package/lib/typescript/store/insights.d.ts +11 -0
  161. package/lib/typescript/store/insights.d.ts.map +1 -0
  162. package/lib/typescript/sync/imagesSyncAdapter.d.ts +205 -0
  163. package/lib/typescript/sync/imagesSyncAdapter.d.ts.map +1 -0
  164. package/lib/typescript/types.d.ts +121 -0
  165. package/lib/typescript/types.d.ts.map +1 -0
  166. package/package.json +67 -0
  167. package/register.d.ts +1 -0
  168. package/register.js +15 -0
  169. package/src/capture/actions.ts +206 -0
  170. package/src/capture/install.ts +36 -0
  171. package/src/capture/installExpoImage.ts +115 -0
  172. package/src/capture/installRnImage.tsx +133 -0
  173. package/src/capture/overrides.ts +282 -0
  174. package/src/capture/savings.ts +193 -0
  175. package/src/capture/shared.ts +387 -0
  176. package/src/components/ImageDetail.tsx +456 -0
  177. package/src/components/ImageDetailFooter.tsx +270 -0
  178. package/src/components/ImageRow.tsx +148 -0
  179. package/src/components/ImagesHeader.tsx +77 -0
  180. package/src/components/ImagesIcon.tsx +66 -0
  181. package/src/components/ImagesListFooter.tsx +193 -0
  182. package/src/components/ImagesModal.tsx +195 -0
  183. package/src/components/ImagesRoot.tsx +18 -0
  184. package/src/components/InsightsBar.tsx +51 -0
  185. package/src/export.ts +100 -0
  186. package/src/format.ts +85 -0
  187. package/src/hooks/useImageRecords.ts +24 -0
  188. package/src/index.tsx +108 -0
  189. package/src/preset.tsx +35 -0
  190. package/src/register.ts +17 -0
  191. package/src/state.ts +88 -0
  192. package/src/store/imageEventStore.ts +162 -0
  193. package/src/store/insights.ts +66 -0
  194. package/src/sync/imagesSyncAdapter.ts +261 -0
  195. package/src/types.ts +111 -0
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.cacheBadge = cacheBadge;
7
+ exports.formatBytes = formatBytes;
8
+ exports.formatMs = formatMs;
9
+ exports.sizeVerdict = sizeVerdict;
10
+ exports.statusColor = statusColor;
11
+ exports.uriTail = uriTail;
12
+ var _sharedUi = require("@buoy-gg/shared-ui");
13
+ var _imageEventStore = require("./store/imageEventStore");
14
+ /**
15
+ * Formatting + verdict helpers shared by list rows and the detail view.
16
+ */
17
+
18
+ function formatBytes(bytes) {
19
+ if (bytes <= 0) return "0 B";
20
+ if (bytes < 1024) return `${bytes} B`;
21
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
22
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
23
+ }
24
+ function formatMs(ms) {
25
+ if (ms == null) return "—";
26
+ if (ms < 1000) return `${Math.round(ms)}ms`;
27
+ return `${(ms / 1000).toFixed(2)}s`;
28
+ }
29
+
30
+ /** Last path segment of a URI, for compact row display. */
31
+ function uriTail(uri) {
32
+ if (!uri) return "(no source)";
33
+ // Metro dev-server asset URLs put the real path in ?unstable_path=…
34
+ const unstable = uri.match(/[?&]unstable_path=([^&?]+)/);
35
+ const effective = unstable ? decodeURIComponent(unstable[1]) : uri;
36
+ const withoutQuery = effective.split("?")[0] ?? effective;
37
+ const segments = withoutQuery.split("/").filter(Boolean);
38
+ return segments[segments.length - 1] ?? effective;
39
+ }
40
+ /**
41
+ * Fresco-style fit verdict: green within 10%, yellow within 50%, red beyond.
42
+ * Undersized sources (upscaled, likely blurry) get their own callout.
43
+ */
44
+ function sizeVerdict(record) {
45
+ const factor = (0, _imageEventStore.oversizeFactor)(record);
46
+ if (factor == null) return {
47
+ label: "",
48
+ color: _sharedUi.macOSColors.text.muted,
49
+ factor
50
+ };
51
+ if (factor < 0.9) {
52
+ return {
53
+ label: `${factor.toFixed(1)}× upscaled`,
54
+ color: _sharedUi.macOSColors.semantic.info,
55
+ factor
56
+ };
57
+ }
58
+ if (factor <= 1.1) {
59
+ return {
60
+ label: "right-sized",
61
+ color: _sharedUi.macOSColors.semantic.success,
62
+ factor
63
+ };
64
+ }
65
+ if (factor <= 1.5) {
66
+ return {
67
+ label: `${factor.toFixed(1)}× oversized`,
68
+ color: _sharedUi.macOSColors.semantic.warning,
69
+ factor
70
+ };
71
+ }
72
+ return {
73
+ label: `${factor.toFixed(1)}× oversized`,
74
+ color: _sharedUi.macOSColors.semantic.error,
75
+ factor
76
+ };
77
+ }
78
+ function statusColor(record) {
79
+ switch (record.status) {
80
+ case "loaded":
81
+ return _sharedUi.macOSColors.semantic.success;
82
+ case "error":
83
+ return _sharedUi.macOSColors.semantic.error;
84
+ case "loading":
85
+ return _sharedUi.macOSColors.semantic.warning;
86
+ default:
87
+ return _sharedUi.macOSColors.text.muted;
88
+ }
89
+ }
90
+
91
+ /** Cache verdict badge text + tint (memory=green, disk=yellow, network=red). */
92
+ function cacheBadge(record) {
93
+ const verdict = record.cacheVerdict;
94
+ if (verdict === "memory" || verdict === "disk/memory") {
95
+ return {
96
+ label: verdict.toUpperCase(),
97
+ color: _sharedUi.macOSColors.semantic.success
98
+ };
99
+ }
100
+ if (verdict === "disk") {
101
+ return {
102
+ label: "DISK",
103
+ color: _sharedUi.macOSColors.semantic.warning
104
+ };
105
+ }
106
+ if (verdict === "none" || record.progressSeen) {
107
+ return {
108
+ label: "NETWORK",
109
+ color: _sharedUi.macOSColors.semantic.error
110
+ };
111
+ }
112
+ return {
113
+ label: "?",
114
+ color: _sharedUi.macOSColors.text.muted
115
+ };
116
+ }
117
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_sharedUi","require","_imageEventStore","formatBytes","bytes","toFixed","formatMs","ms","Math","round","uriTail","uri","unstable","match","effective","decodeURIComponent","withoutQuery","split","segments","filter","Boolean","length","sizeVerdict","record","factor","oversizeFactor","label","color","macOSColors","text","muted","semantic","info","success","warning","error","statusColor","status","cacheBadge","verdict","cacheVerdict","toUpperCase","progressSeen"],"sourceRoot":"../../src","sources":["format.ts"],"mappings":";;;;;;;;;;;AAIA,IAAAA,SAAA,GAAAC,OAAA;AACA,IAAAC,gBAAA,GAAAD,OAAA;AALA;AACA;AACA;;AAMO,SAASE,WAAWA,CAACC,KAAa,EAAU;EACjD,IAAIA,KAAK,IAAI,CAAC,EAAE,OAAO,KAAK;EAC5B,IAAIA,KAAK,GAAG,IAAI,EAAE,OAAO,GAAGA,KAAK,IAAI;EACrC,IAAIA,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE,OAAO,GAAG,CAACA,KAAK,GAAG,IAAI,EAAEC,OAAO,CAAC,CAAC,CAAC,KAAK;EACjE,OAAO,GAAG,CAACD,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,EAAEC,OAAO,CAAC,CAAC,CAAC,KAAK;AACnD;AAEO,SAASC,QAAQA,CAACC,EAAsB,EAAU;EACvD,IAAIA,EAAE,IAAI,IAAI,EAAE,OAAO,GAAG;EAC1B,IAAIA,EAAE,GAAG,IAAI,EAAE,OAAO,GAAGC,IAAI,CAACC,KAAK,CAACF,EAAE,CAAC,IAAI;EAC3C,OAAO,GAAG,CAACA,EAAE,GAAG,IAAI,EAAEF,OAAO,CAAC,CAAC,CAAC,GAAG;AACrC;;AAEA;AACO,SAASK,OAAOA,CAACC,GAAW,EAAU;EAC3C,IAAI,CAACA,GAAG,EAAE,OAAO,aAAa;EAC9B;EACA,MAAMC,QAAQ,GAAGD,GAAG,CAACE,KAAK,CAAC,4BAA4B,CAAC;EACxD,MAAMC,SAAS,GAAGF,QAAQ,GAAGG,kBAAkB,CAACH,QAAQ,CAAC,CAAC,CAAE,CAAC,GAAGD,GAAG;EACnE,MAAMK,YAAY,GAAGF,SAAS,CAACG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAIH,SAAS;EACzD,MAAMI,QAAQ,GAAGF,YAAY,CAACC,KAAK,CAAC,GAAG,CAAC,CAACE,MAAM,CAACC,OAAO,CAAC;EACxD,OAAOF,QAAQ,CAACA,QAAQ,CAACG,MAAM,GAAG,CAAC,CAAC,IAAIP,SAAS;AACnD;AASA;AACA;AACA;AACA;AACO,SAASQ,WAAWA,CAACC,MAAmB,EAAe;EAC5D,MAAMC,MAAM,GAAG,IAAAC,+BAAc,EAACF,MAAM,CAAC;EACrC,IAAIC,MAAM,IAAI,IAAI,EAAE,OAAO;IAAEE,KAAK,EAAE,EAAE;IAAEC,KAAK,EAAEC,qBAAW,CAACC,IAAI,CAACC,KAAK;IAAEN;EAAO,CAAC;EAC/E,IAAIA,MAAM,GAAG,GAAG,EAAE;IAChB,OAAO;MAAEE,KAAK,EAAE,GAAGF,MAAM,CAACnB,OAAO,CAAC,CAAC,CAAC,YAAY;MAAEsB,KAAK,EAAEC,qBAAW,CAACG,QAAQ,CAACC,IAAI;MAAER;IAAO,CAAC;EAC9F;EACA,IAAIA,MAAM,IAAI,GAAG,EAAE;IACjB,OAAO;MAAEE,KAAK,EAAE,aAAa;MAAEC,KAAK,EAAEC,qBAAW,CAACG,QAAQ,CAACE,OAAO;MAAET;IAAO,CAAC;EAC9E;EACA,IAAIA,MAAM,IAAI,GAAG,EAAE;IACjB,OAAO;MAAEE,KAAK,EAAE,GAAGF,MAAM,CAACnB,OAAO,CAAC,CAAC,CAAC,aAAa;MAAEsB,KAAK,EAAEC,qBAAW,CAACG,QAAQ,CAACG,OAAO;MAAEV;IAAO,CAAC;EAClG;EACA,OAAO;IAAEE,KAAK,EAAE,GAAGF,MAAM,CAACnB,OAAO,CAAC,CAAC,CAAC,aAAa;IAAEsB,KAAK,EAAEC,qBAAW,CAACG,QAAQ,CAACI,KAAK;IAAEX;EAAO,CAAC;AAChG;AAEO,SAASY,WAAWA,CAACb,MAAmB,EAAU;EACvD,QAAQA,MAAM,CAACc,MAAM;IACnB,KAAK,QAAQ;MACX,OAAOT,qBAAW,CAACG,QAAQ,CAACE,OAAO;IACrC,KAAK,OAAO;MACV,OAAOL,qBAAW,CAACG,QAAQ,CAACI,KAAK;IACnC,KAAK,SAAS;MACZ,OAAOP,qBAAW,CAACG,QAAQ,CAACG,OAAO;IACrC;MACE,OAAON,qBAAW,CAACC,IAAI,CAACC,KAAK;EACjC;AACF;;AAEA;AACO,SAASQ,UAAUA,CAACf,MAAmB,EAAoC;EAChF,MAAMgB,OAAO,GAAGhB,MAAM,CAACiB,YAAY;EACnC,IAAID,OAAO,KAAK,QAAQ,IAAIA,OAAO,KAAK,aAAa,EAAE;IACrD,OAAO;MAAEb,KAAK,EAAEa,OAAO,CAACE,WAAW,CAAC,CAAC;MAAEd,KAAK,EAAEC,qBAAW,CAACG,QAAQ,CAACE;IAAQ,CAAC;EAC9E;EACA,IAAIM,OAAO,KAAK,MAAM,EAAE;IACtB,OAAO;MAAEb,KAAK,EAAE,MAAM;MAAEC,KAAK,EAAEC,qBAAW,CAACG,QAAQ,CAACG;IAAQ,CAAC;EAC/D;EACA,IAAIK,OAAO,KAAK,MAAM,IAAIhB,MAAM,CAACmB,YAAY,EAAE;IAC7C,OAAO;MAAEhB,KAAK,EAAE,SAAS;MAAEC,KAAK,EAAEC,qBAAW,CAACG,QAAQ,CAACI;IAAM,CAAC;EAChE;EACA,OAAO;IAAET,KAAK,EAAE,GAAG;IAAEC,KAAK,EAAEC,qBAAW,CAACC,IAAI,CAACC;EAAM,CAAC;AACtD","ignoreList":[]}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useImageRecords = useImageRecords;
7
+ var _react = require("react");
8
+ var _imageEventStore = require("../store/imageEventStore");
9
+ /**
10
+ * React bindings for the image event store.
11
+ */
12
+
13
+ function useImageRecords() {
14
+ const snapshot = (0, _react.useSyncExternalStore)(_imageEventStore.subscribe, _imageEventStore.getSnapshot, _imageEventStore.getSnapshot);
15
+ return (0, _react.useMemo)(() => ({
16
+ records: [...snapshot].reverse(),
17
+ stats: (0, _imageEventStore.computeStats)(snapshot)
18
+ }), [snapshot]);
19
+ }
20
+ //# sourceMappingURL=useImageRecords.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_imageEventStore","useImageRecords","snapshot","useSyncExternalStore","subscribe","getSnapshot","useMemo","records","reverse","stats","computeStats"],"sourceRoot":"../../../src","sources":["hooks/useImageRecords.ts"],"mappings":";;;;;;AAIA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,gBAAA,GAAAD,OAAA;AALA;AACA;AACA;;AAYO,SAASE,eAAeA,CAAA,EAA0B;EACvD,MAAMC,QAAQ,GAAG,IAAAC,2BAAoB,EAACC,0BAAS,EAAEC,4BAAW,EAAEA,4BAAW,CAAC;EAC1E,OAAO,IAAAC,cAAO,EACZ,OAAO;IACLC,OAAO,EAAE,CAAC,GAAGL,QAAQ,CAAC,CAACM,OAAO,CAAC,CAAC;IAChCC,KAAK,EAAE,IAAAC,6BAAY,EAACR,QAAQ;EAC9B,CAAC,CAAC,EACF,CAACA,QAAQ,CACX,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "IMAGES_ICON_COLOR", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _ImagesIcon.IMAGES_ICON_COLOR;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "ImagesIcon", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _ImagesIcon.ImagesIcon;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "ImagesModal", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _ImagesModal.ImagesModal;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "ImagesRoot", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _ImagesRoot.ImagesRoot;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "clearAllOverrides", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _overrides.clearAllOverrides;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "clearOverride", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _overrides.clearOverride;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "clearRecords", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _imageEventStore.clearRecords;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "computeInsights", {
49
+ enumerable: true,
50
+ get: function () {
51
+ return _insights.computeInsights;
52
+ }
53
+ });
54
+ Object.defineProperty(exports, "computeStats", {
55
+ enumerable: true,
56
+ get: function () {
57
+ return _imageEventStore.computeStats;
58
+ }
59
+ });
60
+ Object.defineProperty(exports, "createImagesTool", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _preset.createImagesTool;
64
+ }
65
+ });
66
+ Object.defineProperty(exports, "estDecodedBytes", {
67
+ enumerable: true,
68
+ get: function () {
69
+ return _imageEventStore.estDecodedBytes;
70
+ }
71
+ });
72
+ Object.defineProperty(exports, "estWastedBytes", {
73
+ enumerable: true,
74
+ get: function () {
75
+ return _imageEventStore.estWastedBytes;
76
+ }
77
+ });
78
+ Object.defineProperty(exports, "evictExpoDiskEntry", {
79
+ enumerable: true,
80
+ get: function () {
81
+ return _actions.evictExpoDiskEntry;
82
+ }
83
+ });
84
+ Object.defineProperty(exports, "flashAllMounted", {
85
+ enumerable: true,
86
+ get: function () {
87
+ return _overrides.flashAllMounted;
88
+ }
89
+ });
90
+ Object.defineProperty(exports, "flashRecord", {
91
+ enumerable: true,
92
+ get: function () {
93
+ return _overrides.flashRecord;
94
+ }
95
+ });
96
+ Object.defineProperty(exports, "formatRecordMarkdown", {
97
+ enumerable: true,
98
+ get: function () {
99
+ return _export.formatRecordMarkdown;
100
+ }
101
+ });
102
+ Object.defineProperty(exports, "formatRegistryMarkdown", {
103
+ enumerable: true,
104
+ get: function () {
105
+ return _export.formatRegistryMarkdown;
106
+ }
107
+ });
108
+ Object.defineProperty(exports, "getCaptureStatus", {
109
+ enumerable: true,
110
+ get: function () {
111
+ return _install.getCaptureStatus;
112
+ }
113
+ });
114
+ Object.defineProperty(exports, "getGlobalModes", {
115
+ enumerable: true,
116
+ get: function () {
117
+ return _overrides.getGlobalModes;
118
+ }
119
+ });
120
+ Object.defineProperty(exports, "getImageRecords", {
121
+ enumerable: true,
122
+ get: function () {
123
+ return _imageEventStore.getSnapshot;
124
+ }
125
+ });
126
+ Object.defineProperty(exports, "getOverride", {
127
+ enumerable: true,
128
+ get: function () {
129
+ return _overrides.getOverride;
130
+ }
131
+ });
132
+ Object.defineProperty(exports, "hardReloadAllMounted", {
133
+ enumerable: true,
134
+ get: function () {
135
+ return _actions.hardReloadAllMounted;
136
+ }
137
+ });
138
+ Object.defineProperty(exports, "hardReloadRecord", {
139
+ enumerable: true,
140
+ get: function () {
141
+ return _actions.hardReloadRecord;
142
+ }
143
+ });
144
+ Object.defineProperty(exports, "imagesSyncAdapter", {
145
+ enumerable: true,
146
+ get: function () {
147
+ return _imagesSyncAdapter.imagesSyncAdapter;
148
+ }
149
+ });
150
+ Object.defineProperty(exports, "imagesToolPreset", {
151
+ enumerable: true,
152
+ get: function () {
153
+ return _preset.imagesToolPreset;
154
+ }
155
+ });
156
+ Object.defineProperty(exports, "insightChips", {
157
+ enumerable: true,
158
+ get: function () {
159
+ return _insights.insightChips;
160
+ }
161
+ });
162
+ Object.defineProperty(exports, "installImageCapture", {
163
+ enumerable: true,
164
+ get: function () {
165
+ return _install.installImageCapture;
166
+ }
167
+ });
168
+ Object.defineProperty(exports, "oversizeFactor", {
169
+ enumerable: true,
170
+ get: function () {
171
+ return _imageEventStore.oversizeFactor;
172
+ }
173
+ });
174
+ Object.defineProperty(exports, "proveSavings", {
175
+ enumerable: true,
176
+ get: function () {
177
+ return _savings.proveSavings;
178
+ }
179
+ });
180
+ Object.defineProperty(exports, "retryRecord", {
181
+ enumerable: true,
182
+ get: function () {
183
+ return _actions.retryRecord;
184
+ }
185
+ });
186
+ Object.defineProperty(exports, "setBlankImages", {
187
+ enumerable: true,
188
+ get: function () {
189
+ return _overrides.setBlankImages;
190
+ }
191
+ });
192
+ Object.defineProperty(exports, "setNetworkMode", {
193
+ enumerable: true,
194
+ get: function () {
195
+ return _overrides.setNetworkMode;
196
+ }
197
+ });
198
+ Object.defineProperty(exports, "setOverride", {
199
+ enumerable: true,
200
+ get: function () {
201
+ return _overrides.setOverride;
202
+ }
203
+ });
204
+ Object.defineProperty(exports, "setOverrideForAllMounted", {
205
+ enumerable: true,
206
+ get: function () {
207
+ return _overrides.setOverrideForAllMounted;
208
+ }
209
+ });
210
+ Object.defineProperty(exports, "subscribeImageRecords", {
211
+ enumerable: true,
212
+ get: function () {
213
+ return _imageEventStore.subscribe;
214
+ }
215
+ });
216
+ Object.defineProperty(exports, "useImageRecords", {
217
+ enumerable: true,
218
+ get: function () {
219
+ return _useImageRecords.useImageRecords;
220
+ }
221
+ });
222
+ require("./register");
223
+ var _preset = require("./preset");
224
+ var _ImagesRoot = require("./components/ImagesRoot");
225
+ var _ImagesModal = require("./components/ImagesModal");
226
+ var _ImagesIcon = require("./components/ImagesIcon");
227
+ var _install = require("./capture/install");
228
+ var _actions = require("./capture/actions");
229
+ var _overrides = require("./capture/overrides");
230
+ var _savings = require("./capture/savings");
231
+ var _insights = require("./store/insights");
232
+ var _export = require("./export");
233
+ var _imagesSyncAdapter = require("./sync/imagesSyncAdapter");
234
+ var _useImageRecords = require("./hooks/useImageRecords");
235
+ var _imageEventStore = require("./store/imageEventStore");
236
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["require","_preset","_ImagesRoot","_ImagesModal","_ImagesIcon","_install","_actions","_overrides","_savings","_insights","_export","_imagesSyncAdapter","_useImageRecords","_imageEventStore"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBAA,OAAA;AAKA,IAAAC,OAAA,GAAAD,OAAA;AAKA,IAAAE,WAAA,GAAAF,OAAA;AAKA,IAAAG,YAAA,GAAAH,OAAA;AACA,IAAAI,WAAA,GAAAJ,OAAA;AAKA,IAAAK,QAAA,GAAAL,OAAA;AAKA,IAAAM,QAAA,GAAAN,OAAA;AAUA,IAAAO,UAAA,GAAAP,OAAA;AAkBA,IAAAQ,QAAA,GAAAR,OAAA;AAEA,IAAAS,SAAA,GAAAT,OAAA;AACA,IAAAU,OAAA,GAAAV,OAAA;AAKA,IAAAW,kBAAA,GAAAX,OAAA;AAKA,IAAAY,gBAAA,GAAAZ,OAAA;AACA,IAAAa,gBAAA,GAAAb,OAAA","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createImagesTool = createImagesTool;
7
+ exports.imagesToolPreset = void 0;
8
+ var _ImagesIcon = require("./components/ImagesIcon");
9
+ var _ImagesModal = require("./components/ImagesModal");
10
+ var _jsxRuntime = require("react/jsx-runtime");
11
+ /**
12
+ * Pre-configured Images tool for FloatingDevTools.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * import { imagesToolPreset } from '@buoy-gg/images';
17
+ *
18
+ * <FloatingDevTools apps={[imagesToolPreset]} />
19
+ * ```
20
+ */
21
+
22
+ const imagesToolPreset = exports.imagesToolPreset = {
23
+ id: "images",
24
+ name: "IMAGES",
25
+ description: "Image loads, caching, failures, and oversize checks",
26
+ slot: "both",
27
+ icon: ({
28
+ size,
29
+ color
30
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_ImagesIcon.ImagesIcon, {
31
+ size: size,
32
+ color: color || _ImagesIcon.IMAGES_ICON_COLOR
33
+ }),
34
+ component: _ImagesModal.ImagesModal
35
+ };
36
+
37
+ /** Create a custom Images tool configuration. */
38
+ function createImagesTool(options = {}) {
39
+ return {
40
+ ...imagesToolPreset,
41
+ name: options.name ?? imagesToolPreset.name,
42
+ description: options.description ?? imagesToolPreset.description
43
+ };
44
+ }
45
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_ImagesIcon","require","_ImagesModal","_jsxRuntime","imagesToolPreset","exports","id","name","description","slot","icon","size","color","jsx","ImagesIcon","IMAGES_ICON_COLOR","component","ImagesModal","createImagesTool","options"],"sourceRoot":"../../src","sources":["preset.tsx"],"mappings":";;;;;;;AAWA,IAAAA,WAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAAuD,IAAAE,WAAA,GAAAF,OAAA;AAZvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKO,MAAMG,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,GAAG;EAC9BE,EAAE,EAAE,QAAQ;EACZC,IAAI,EAAE,QAAQ;EACdC,WAAW,EAAE,qDAAqD;EAClEC,IAAI,EAAE,MAAe;EACrBC,IAAI,EAAEA,CAAC;IAAEC,IAAI;IAAEC;EAAwC,CAAC,kBACtD,IAAAT,WAAA,CAAAU,GAAA,EAACb,WAAA,CAAAc,UAAU;IAACH,IAAI,EAAEA,IAAK;IAACC,KAAK,EAAEA,KAAK,IAAIG;EAAkB,CAAE,CAC7D;EACDC,SAAS,EAAEC;AACb,CAAC;;AAED;AACO,SAASC,gBAAgBA,CAC9BC,OAAgD,GAAG,CAAC,CAAC,EACrD;EACA,OAAO;IACL,GAAGf,gBAAgB;IACnBG,IAAI,EAAEY,OAAO,CAACZ,IAAI,IAAIH,gBAAgB,CAACG,IAAI;IAC3CC,WAAW,EAAEW,OAAO,CAACX,WAAW,IAAIJ,gBAAgB,CAACI;EACvD,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ var _install = require("./capture/install");
4
+ /**
5
+ * Side-effect entry: installs image capture on import.
6
+ *
7
+ * Import this FIRST in your app entry file so the RN-core <Image> decorator
8
+ * lands before React Native's Image module is evaluated:
9
+ *
10
+ * ```ts
11
+ * import "@buoy-gg/images/register";
12
+ * ```
13
+ *
14
+ * This module intentionally imports nothing that touches react-native's Image
15
+ * (directly or transitively) before installing.
16
+ */
17
+
18
+ (0, _install.installImageCapture)();
19
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_install","require","installImageCapture"],"sourceRoot":"../../src","sources":["register.ts"],"mappings":";;AAcA,IAAAA,QAAA,GAAAC,OAAA;AAdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA,IAAAC,4BAAmB,EAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.imagesState = imagesState;
7
+ /**
8
+ * Global singleton state for the Images tool.
9
+ *
10
+ * The package can get evaluated twice as two separate module instances (e.g.
11
+ * the `/register` entry shim resolving to one copy while the package root
12
+ * import resolves to another — lib vs src). If capture state lived in module
13
+ * scope, the early copy would install the RN decorator and collect records
14
+ * while the UI copy read an empty store and a false "decorator never ran"
15
+ * flag. Keying all mutable state on globalThis under a well-known symbol makes
16
+ * every copy operate on the same data.
17
+ */
18
+
19
+ const KEY = Symbol.for("buoy.images.globalState.v1");
20
+ function imagesState() {
21
+ const g = globalThis;
22
+ if (!g[KEY]) {
23
+ g[KEY] = {
24
+ records: [],
25
+ byId: new Map(),
26
+ nextId: 1,
27
+ listeners: new Set(),
28
+ snapshot: [],
29
+ emitScheduled: false,
30
+ captureInstalled: false,
31
+ rnInstalled: false,
32
+ expoInstalled: false,
33
+ decoratorRegistered: false,
34
+ decoratorInvoked: false,
35
+ attachSeen: 0,
36
+ expoAvailable: false,
37
+ expoPatched: false,
38
+ reloadRequests: new Map(),
39
+ actionListeners: new Set(),
40
+ expoInstances: new Map(),
41
+ overrides: new Map(),
42
+ flashUntil: new Map(),
43
+ recordVersions: new Map(),
44
+ globalVersion: 0,
45
+ versionCounter: 0,
46
+ globalModes: {
47
+ network: "normal",
48
+ blank: false
49
+ }
50
+ };
51
+ }
52
+ return g[KEY];
53
+ }
54
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["KEY","Symbol","for","imagesState","g","globalThis","records","byId","Map","nextId","listeners","Set","snapshot","emitScheduled","captureInstalled","rnInstalled","expoInstalled","decoratorRegistered","decoratorInvoked","attachSeen","expoAvailable","expoPatched","reloadRequests","actionListeners","expoInstances","overrides","flashUntil","recordVersions","globalVersion","versionCounter","globalModes","network","blank"],"sourceRoot":"../../src","sources":["state.ts"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA6CA,MAAMA,GAAG,GAAGC,MAAM,CAACC,GAAG,CAAC,4BAA4B,CAAC;AAE7C,SAASC,WAAWA,CAAA,EAAsB;EAC/C,MAAMC,CAAC,GAAGC,UAA2D;EACrE,IAAI,CAACD,CAAC,CAACJ,GAAG,CAAC,EAAE;IACXI,CAAC,CAACJ,GAAG,CAAC,GAAG;MACPM,OAAO,EAAE,EAAE;MACXC,IAAI,EAAE,IAAIC,GAAG,CAAC,CAAC;MACfC,MAAM,EAAE,CAAC;MACTC,SAAS,EAAE,IAAIC,GAAG,CAAC,CAAC;MACpBC,QAAQ,EAAE,EAAE;MACZC,aAAa,EAAE,KAAK;MACpBC,gBAAgB,EAAE,KAAK;MACvBC,WAAW,EAAE,KAAK;MAClBC,aAAa,EAAE,KAAK;MACpBC,mBAAmB,EAAE,KAAK;MAC1BC,gBAAgB,EAAE,KAAK;MACvBC,UAAU,EAAE,CAAC;MACbC,aAAa,EAAE,KAAK;MACpBC,WAAW,EAAE,KAAK;MAClBC,cAAc,EAAE,IAAId,GAAG,CAAC,CAAC;MACzBe,eAAe,EAAE,IAAIZ,GAAG,CAAC,CAAC;MAC1Ba,aAAa,EAAE,IAAIhB,GAAG,CAAC,CAAC;MACxBiB,SAAS,EAAE,IAAIjB,GAAG,CAAC,CAAC;MACpBkB,UAAU,EAAE,IAAIlB,GAAG,CAAC,CAAC;MACrBmB,cAAc,EAAE,IAAInB,GAAG,CAAC,CAAC;MACzBoB,aAAa,EAAE,CAAC;MAChBC,cAAc,EAAE,CAAC;MACjBC,WAAW,EAAE;QAAEC,OAAO,EAAE,QAAQ;QAAEC,KAAK,EAAE;MAAM;IACjD,CAAC;EACH;EACA,OAAO5B,CAAC,CAACJ,GAAG,CAAC;AACf","ignoreList":[]}
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.clearRecords = clearRecords;
7
+ exports.computeStats = computeStats;
8
+ exports.createRecord = createRecord;
9
+ exports.estDecodedBytes = estDecodedBytes;
10
+ exports.estWastedBytes = estWastedBytes;
11
+ exports.getRecord = getRecord;
12
+ exports.getSnapshot = getSnapshot;
13
+ exports.neededPixels = neededPixels;
14
+ exports.oversizeFactor = oversizeFactor;
15
+ exports.subscribe = subscribe;
16
+ exports.updateRecord = updateRecord;
17
+ var _reactNative = require("react-native");
18
+ var _state = require("../state");
19
+ /**
20
+ * imageEventStore
21
+ *
22
+ * Bounded buffer of ImageRecords fed by the capture layer (installRnImage /
23
+ * installExpoImage). Follows the console tool's store shape — Set of
24
+ * listeners, frame-coalesced emit so bursty image grids don't turn every
25
+ * event into its own React commit — but ALL mutable state lives on the
26
+ * globalThis singleton (see ../state.ts) so a dual module instance of this
27
+ * package still reads/writes one shared store.
28
+ */
29
+
30
+ /** Max records retained before the oldest are dropped. */
31
+ const MAX_RECORDS = 500;
32
+ function emit() {
33
+ const s = (0, _state.imagesState)();
34
+ if (s.emitScheduled) return;
35
+ s.emitScheduled = true;
36
+ requestAnimationFrame(() => {
37
+ s.emitScheduled = false;
38
+ for (const listener of s.listeners) listener();
39
+ });
40
+ }
41
+
42
+ /** Snapshot identity only changes on emit, so useSyncExternalStore stays cheap. */
43
+ function invalidate() {
44
+ const s = (0, _state.imagesState)();
45
+ s.snapshot = [...s.records];
46
+ emit();
47
+ }
48
+ function createRecord(partial) {
49
+ const s = (0, _state.imagesState)();
50
+ const record = {
51
+ ...partial,
52
+ id: s.nextId++,
53
+ createdAt: Date.now(),
54
+ status: "pending",
55
+ mounted: true,
56
+ loadCount: 0
57
+ };
58
+ s.records.push(record);
59
+ s.byId.set(record.id, record);
60
+ if (s.records.length > MAX_RECORDS) {
61
+ const dropped = s.records.splice(0, s.records.length - MAX_RECORDS);
62
+ for (const d of dropped) s.byId.delete(d.id);
63
+ }
64
+ invalidate();
65
+ return record;
66
+ }
67
+
68
+ /** Mutate a record in place (records are owned by the store) and notify. */
69
+ function updateRecord(id, patch) {
70
+ const s = (0, _state.imagesState)();
71
+ const record = s.byId.get(id);
72
+ if (!record) return undefined;
73
+ Object.assign(record, patch);
74
+ invalidate();
75
+ return record;
76
+ }
77
+ function getRecord(id) {
78
+ return (0, _state.imagesState)().byId.get(id);
79
+ }
80
+ function getSnapshot() {
81
+ return (0, _state.imagesState)().snapshot;
82
+ }
83
+ function subscribe(listener) {
84
+ const s = (0, _state.imagesState)();
85
+ s.listeners.add(listener);
86
+ return () => (0, _state.imagesState)().listeners.delete(listener);
87
+ }
88
+ function clearRecords() {
89
+ const s = (0, _state.imagesState)();
90
+ // Keep records still actively loading so in-flight events don't orphan.
91
+ s.records = s.records.filter(r => r.mounted && r.status !== "loaded" && r.status !== "error");
92
+ s.byId = new Map(s.records.map(r => [r.id, r]));
93
+ invalidate();
94
+ }
95
+
96
+ // ---------------------------------------------------------------------------
97
+ // Derived math (shared by rows, detail view, and stats)
98
+ // ---------------------------------------------------------------------------
99
+
100
+ /** Physical pixels actually needed to fill the laid-out view 1:1. */
101
+ function neededPixels(record) {
102
+ if (!record.layout || record.layout.width <= 0 || record.layout.height <= 0) return null;
103
+ const scale = _reactNative.PixelRatio.get();
104
+ return {
105
+ width: Math.round(record.layout.width * scale),
106
+ height: Math.round(record.layout.height * scale)
107
+ };
108
+ }
109
+
110
+ /**
111
+ * Linear oversize factor: how many times larger (per axis, area-normalized)
112
+ * the decoded bitmap is vs what the view needs. 1 = perfect, 2 = 4× the pixels.
113
+ */
114
+ function oversizeFactor(record) {
115
+ const needed = neededPixels(record);
116
+ if (!needed || !record.intrinsic) return null;
117
+ const neededArea = needed.width * needed.height;
118
+ const intrinsicArea = record.intrinsic.width * record.intrinsic.height;
119
+ if (neededArea <= 0 || intrinsicArea <= 0) return null;
120
+ return Math.sqrt(intrinsicArea / neededArea);
121
+ }
122
+
123
+ /** Estimated decoded-bitmap memory for a loaded record (RGBA8888). */
124
+ function estDecodedBytes(record) {
125
+ if (!record.intrinsic) return 0;
126
+ return record.intrinsic.width * record.intrinsic.height * 4;
127
+ }
128
+
129
+ /** Decoded bytes beyond what the laid-out size needs (0 if not oversized). */
130
+ function estWastedBytes(record) {
131
+ const needed = neededPixels(record);
132
+ if (!needed || !record.intrinsic) return 0;
133
+ const wasted = (record.intrinsic.width * record.intrinsic.height - needed.width * needed.height) * 4;
134
+ return Math.max(0, wasted);
135
+ }
136
+ function computeStats(list) {
137
+ const stats = {
138
+ total: list.length,
139
+ loading: 0,
140
+ loaded: 0,
141
+ errors: 0,
142
+ networkLoads: 0,
143
+ estDecodedBytes: 0,
144
+ estWastedBytes: 0
145
+ };
146
+ for (const r of list) {
147
+ // Unmounted in-flight records are stale (the instance died mid-load) —
148
+ // they must not count as live in-flight work.
149
+ if ((r.status === "loading" || r.status === "pending") && r.mounted) stats.loading++;
150
+ if (r.status === "loaded") stats.loaded++;
151
+ if (r.status === "error") stats.errors++;
152
+ if (r.progressSeen || r.cacheVerdict === "none") stats.networkLoads++;
153
+ if (r.mounted && r.status === "loaded") {
154
+ stats.estDecodedBytes += estDecodedBytes(r);
155
+ stats.estWastedBytes += estWastedBytes(r);
156
+ }
157
+ }
158
+ return stats;
159
+ }
160
+ //# sourceMappingURL=imageEventStore.js.map