@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,189 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Savings prover — Squoosh-style, on device.
5
+ *
6
+ * Instead of estimating what an oversized source wastes, PROVE it: re-encode
7
+ * the image at the displayed size (× pixel ratio) as WebP via
8
+ * expo-image-manipulator (verified: chainable resize → saveAsync WebP on BOTH
9
+ * platforms, available in Expo Go), stat the output file, and report real
10
+ * bytes vs the original. The optimized file:// URI can then be A/B'd in place
11
+ * through the existing swap-url override.
12
+ *
13
+ * Original size is resolved in tiers: observed download bytes (onProgress
14
+ * total) → expo disk-cache file size → HEAD Content-Length.
15
+ */
16
+
17
+ import { neededPixels } from "../store/imageEventStore";
18
+ function loadLegacyFs() {
19
+ try {
20
+ const mod = require("expo-file-system/legacy");
21
+ const fs = mod?.default || mod;
22
+ if (fs?.getInfoAsync) return fs;
23
+ } catch {
24
+ // try main import
25
+ }
26
+ try {
27
+ const mod = require("expo-file-system");
28
+ const fs = mod?.default || mod;
29
+ if (fs?.getInfoAsync) return fs;
30
+ } catch {
31
+ // not installed
32
+ }
33
+ return null;
34
+ }
35
+ async function fileSize(uri) {
36
+ const fs = loadLegacyFs();
37
+ if (!fs?.getInfoAsync) return null;
38
+ try {
39
+ const normalized = uri.startsWith("file://") ? uri : `file://${uri}`;
40
+ const info = await fs.getInfoAsync(normalized, {
41
+ size: true
42
+ });
43
+ return info.exists && typeof info.size === "number" ? info.size : null;
44
+ } catch {
45
+ return null;
46
+ }
47
+ }
48
+ async function resolveOriginalBytes(record) {
49
+ if (record.bytesTotal && record.bytesTotal > 0) {
50
+ return {
51
+ bytes: record.bytesTotal,
52
+ source: "download"
53
+ };
54
+ }
55
+ // expo disk cache file
56
+ if (record.lib === "expo") {
57
+ try {
58
+ const expo = require("expo-image");
59
+ const path = await expo.Image.getCachePathAsync(record.uri);
60
+ if (path) {
61
+ const size = await fileSize(path);
62
+ if (size != null) return {
63
+ bytes: size,
64
+ source: "cacheFile"
65
+ };
66
+ }
67
+ } catch {
68
+ // fall through
69
+ }
70
+ }
71
+ // HEAD request (network sources only)
72
+ if (record.sourceKind === "network") {
73
+ try {
74
+ const response = await fetch(record.uri, {
75
+ method: "HEAD"
76
+ });
77
+ const length = Number(response.headers.get("content-length"));
78
+ if (Number.isFinite(length) && length > 0) return {
79
+ bytes: length,
80
+ source: "head"
81
+ };
82
+ } catch {
83
+ // unknown original size is fine
84
+ }
85
+ }
86
+ return null;
87
+ }
88
+
89
+ /**
90
+ * Re-encode `record`'s source at its displayed size as WebP and measure it.
91
+ * Requires expo-image-manipulator (graceful message when absent).
92
+ */
93
+ export async function proveSavings(record) {
94
+ if (!record.uri || record.sourceKind !== "network" && record.sourceKind !== "asset" && record.sourceKind !== "file") {
95
+ return {
96
+ ok: false,
97
+ message: "No loadable source URI on this record"
98
+ };
99
+ }
100
+ const needed = neededPixels(record);
101
+ if (!needed) {
102
+ return {
103
+ ok: false,
104
+ message: "No layout yet — the image must render once to know its displayed size"
105
+ };
106
+ }
107
+ let manipulator;
108
+ try {
109
+ manipulator = require("expo-image-manipulator");
110
+ } catch {
111
+ return {
112
+ ok: false,
113
+ message: "expo-image-manipulator not installed — add it to enable real savings measurement"
114
+ };
115
+ }
116
+ const webp = manipulator.SaveFormat?.WEBP ?? "webp";
117
+ const targetWidth = Math.min(needed.width, record.intrinsic?.width ?? needed.width);
118
+ let original = null;
119
+ let optimized = null;
120
+ try {
121
+ [original, optimized] = await Promise.all([resolveOriginalBytes(record), (async () => {
122
+ // Preferred: context API (current). Fallback: deprecated manipulateAsync.
123
+ if (manipulator.ImageManipulator?.manipulate) {
124
+ const context = manipulator.ImageManipulator.manipulate(record.uri);
125
+ try {
126
+ const ref = await context.resize({
127
+ width: targetWidth
128
+ }).renderAsync();
129
+ try {
130
+ return await ref.saveAsync({
131
+ format: webp,
132
+ compress: 0.8
133
+ });
134
+ } finally {
135
+ ref.release?.();
136
+ }
137
+ } finally {
138
+ context.release?.();
139
+ }
140
+ }
141
+ if (manipulator.manipulateAsync) {
142
+ return manipulator.manipulateAsync(record.uri, [{
143
+ resize: {
144
+ width: targetWidth
145
+ }
146
+ }], {
147
+ compress: 0.8,
148
+ format: webp
149
+ });
150
+ }
151
+ return null;
152
+ })()]);
153
+ } catch (error) {
154
+ return {
155
+ ok: false,
156
+ message: `Re-encode failed: ${String(error?.message ?? error)}`
157
+ };
158
+ }
159
+ if (!optimized?.uri) {
160
+ return {
161
+ ok: false,
162
+ message: "Re-encode produced no output (unsupported source?)"
163
+ };
164
+ }
165
+ const optimizedBytes = await fileSize(optimized.uri);
166
+ const result = {
167
+ ok: true,
168
+ message: "",
169
+ optimizedUri: optimized.uri,
170
+ optimizedBytes: optimizedBytes ?? undefined,
171
+ optimizedDims: {
172
+ width: optimized.width,
173
+ height: optimized.height
174
+ },
175
+ originalBytes: original?.bytes,
176
+ originalBytesSource: original?.source
177
+ };
178
+ if (original?.bytes != null && optimizedBytes != null) {
179
+ result.savedBytes = Math.max(0, original.bytes - optimizedBytes);
180
+ result.savedPct = original.bytes > 0 ? Math.round(result.savedBytes / original.bytes * 100) : 0;
181
+ result.message = `Right-sized WebP is ${result.savedPct}% smaller (real bytes, encoded on device)`;
182
+ } else if (optimizedBytes != null) {
183
+ result.message = "Optimized variant encoded — original size unknown (no download bytes, cache entry, or Content-Length)";
184
+ } else {
185
+ result.message = "Optimized variant encoded — could not stat the output file";
186
+ }
187
+ return result;
188
+ }
189
+ //# sourceMappingURL=savings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["neededPixels","loadLegacyFs","mod","require","fs","default","getInfoAsync","fileSize","uri","normalized","startsWith","info","size","exists","resolveOriginalBytes","record","bytesTotal","bytes","source","lib","expo","path","Image","getCachePathAsync","sourceKind","response","fetch","method","length","Number","headers","get","isFinite","proveSavings","ok","message","needed","manipulator","webp","SaveFormat","WEBP","targetWidth","Math","min","width","intrinsic","original","optimized","Promise","all","ImageManipulator","manipulate","context","ref","resize","renderAsync","saveAsync","format","compress","release","manipulateAsync","error","String","optimizedBytes","result","optimizedUri","undefined","optimizedDims","height","originalBytes","originalBytesSource","savedBytes","max","savedPct","round"],"sourceRoot":"../../../src","sources":["capture/savings.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,359 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Capture core shared by the RN <Image> decorator and the expo-image patch.
5
+ *
6
+ * ImageInstanceTracker: one per live image component instance. It rolls a new
7
+ * ImageRecord whenever the instance's source URI changes, and exposes wrapped
8
+ * event handlers that feed the store while still calling through to whatever
9
+ * handlers the app passed.
10
+ */
11
+
12
+ import { imagesState } from "../state";
13
+ import { dropActionState, settleReloadRequest } from "./actions";
14
+ import { createRecord, getRecord, updateRecord } from "../store/imageEventStore";
15
+
16
+ /**
17
+ * Images rendered by Buoy's own UI (e.g. thumbnails inside the Images modal)
18
+ * carry this testID prefix and are excluded from capture, so the tool doesn't
19
+ * pollute its own registry.
20
+ */
21
+ export const INTERNAL_TEST_ID_PREFIX = "buoy-internal";
22
+ export function isInternalImage(testID) {
23
+ return typeof testID === "string" && testID.startsWith(INTERNAL_TEST_ID_PREFIX);
24
+ }
25
+
26
+ /**
27
+ * React Native's own devtools UI loads images too (LogBox icons resolve to
28
+ * Metro asset URLs under Libraries/LogBox). They're noise in an app-focused
29
+ * registry — skip them.
30
+ */
31
+ export function isNoiseUri(uri) {
32
+ return uri.includes("Libraries%2FLogBox") || uri.includes("Libraries/LogBox") || uri.includes("LogBoxImages");
33
+ }
34
+ export function classifyUri(uri) {
35
+ if (uri.startsWith("http://") || uri.startsWith("https://")) return "network";
36
+ if (uri.startsWith("file://") || uri.startsWith("asset://")) return "file";
37
+ if (uri.startsWith("data:")) return "data";
38
+ return "other";
39
+ }
40
+
41
+ /**
42
+ * Best-effort URI extraction from any source prop shape (RN or expo-image):
43
+ * string, number (Metro asset), {uri}, arrays of those, ImageRef.
44
+ */
45
+ export function resolveSourceUri(source) {
46
+ if (source == null) return {
47
+ uri: "",
48
+ kind: "other"
49
+ };
50
+ if (Array.isArray(source)) {
51
+ return resolveSourceUri(source.length > 0 ? source[0] : null);
52
+ }
53
+ if (typeof source === "string") {
54
+ return {
55
+ uri: source,
56
+ kind: classifyUri(source)
57
+ };
58
+ }
59
+ if (typeof source === "number") {
60
+ // Metro asset id. Image is guaranteed evaluated by the time an instance
61
+ // renders, so requiring it lazily here can never latch the decorator late.
62
+ try {
63
+ const rn = require("react-native");
64
+ const resolved = rn.Image?.resolveAssetSource?.(source);
65
+ if (resolved?.uri) return {
66
+ uri: resolved.uri,
67
+ kind: "asset"
68
+ };
69
+ } catch {
70
+ // fall through
71
+ }
72
+ return {
73
+ uri: `asset:#${source}`,
74
+ kind: "asset"
75
+ };
76
+ }
77
+ if (typeof source === "object") {
78
+ const uri = source.uri;
79
+ if (typeof uri === "string") {
80
+ const kind = classifyUri(uri);
81
+ // require()'d assets resolve to Metro dev-server URLs in dev — still
82
+ // report them as assets when they carry the packager marker.
83
+ if (source.__packager_asset) {
84
+ return {
85
+ uri,
86
+ kind: "asset"
87
+ };
88
+ }
89
+ return {
90
+ uri,
91
+ kind
92
+ };
93
+ }
94
+ // expo-image ImageRef (native shared object) has width/height but no uri.
95
+ const width = source.width;
96
+ if (typeof width === "number") return {
97
+ uri: "(ImageRef)",
98
+ kind: "other"
99
+ };
100
+ }
101
+ return {
102
+ uri: "",
103
+ kind: "other"
104
+ };
105
+ }
106
+
107
+ /** The event-handler subset we intercept, normalized across both libraries. */
108
+
109
+ /** RN events arrive as {nativeEvent}; expo-image passes the payload directly. */
110
+ function payloadOf(event) {
111
+ if (event && typeof event === "object") {
112
+ const native = event.nativeEvent;
113
+ if (native && typeof native === "object") {
114
+ return native;
115
+ }
116
+ return event;
117
+ }
118
+ return {};
119
+ }
120
+
121
+ /**
122
+ * After an RN-core load, classify the cache via Image.queryCache.
123
+ *
124
+ * Delayed + retried: NSURLCache commits fresh downloads asynchronously, so a
125
+ * query at the instant of onLoad reports a miss for images that ARE being
126
+ * cached (observed live). First probe after 600ms, one re-probe at 3s to
127
+ * catch slow cache writes.
128
+ */
129
+ function queryRnCache(recordId, uri) {
130
+ const probe = () => {
131
+ try {
132
+ const rn = require("react-native");
133
+ const queryCache = rn.Image?.queryCache;
134
+ if (typeof queryCache !== "function" || !uri) return;
135
+ queryCache([uri]).then(result => {
136
+ const verdict = result?.[uri];
137
+ if (verdict) {
138
+ updateRecord(recordId, {
139
+ cacheVerdict: verdict,
140
+ cacheVerdictSource: "queryCache"
141
+ });
142
+ }
143
+ }).catch(() => {});
144
+ } catch {
145
+ // queryCache unavailable (web) — leave verdict unknown.
146
+ }
147
+ };
148
+ setTimeout(probe, 600);
149
+ setTimeout(() => {
150
+ const record = getRecord(recordId);
151
+ if (record && record.cacheVerdictSource !== "queryCache") probe();
152
+ }, 3000);
153
+ }
154
+ export class ImageInstanceTracker {
155
+ recordId = null;
156
+ uri = null;
157
+ handlerCache = null;
158
+ constructor(lib) {
159
+ this.lib = lib;
160
+ }
161
+ getRecordId() {
162
+ return this.recordId;
163
+ }
164
+
165
+ /** Record accessibility presence (called per render; writes only on change). */
166
+ noteA11y(hasAltText) {
167
+ if (this.recordId == null) return;
168
+ const record = getRecord(this.recordId);
169
+ if (record && record.hasAltText !== hasAltText) {
170
+ updateRecord(this.recordId, {
171
+ hasAltText
172
+ });
173
+ }
174
+ }
175
+
176
+ /** Call on every render with the current source prop. Rolls records on change. */
177
+ syncSource(source) {
178
+ const {
179
+ uri,
180
+ kind
181
+ } = resolveSourceUri(source);
182
+ if (uri === this.uri) return;
183
+ this.uri = uri;
184
+ this.handlerCache = null; // handlers close over recordId via getter, but roll anyway
185
+ if (this.recordId != null) dropActionState(this.recordId);
186
+ if (!uri || isNoiseUri(uri)) {
187
+ this.recordId = null;
188
+ return;
189
+ }
190
+ const record = createRecord({
191
+ lib: this.lib,
192
+ uri,
193
+ sourceKind: kind
194
+ });
195
+ this.recordId = record.id;
196
+ }
197
+ unmount() {
198
+ if (this.recordId != null) {
199
+ updateRecord(this.recordId, {
200
+ mounted: false
201
+ });
202
+ dropActionState(this.recordId);
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Wrapped handlers for the current originals. Cached by handler identity so
208
+ * re-renders with unchanged props reuse the same functions.
209
+ */
210
+ handlers(orig) {
211
+ const key = [orig.onLoadStart, orig.onProgress, orig.onLoad, orig.onError, orig.onLoadEnd, orig.onDisplay, orig.onLayout, this.recordId];
212
+ const cached = this.handlerCache;
213
+ if (cached && cached.key.length === key.length && cached.key.every((k, i) => k === key[i])) {
214
+ return cached.out;
215
+ }
216
+ const recordId = this.recordId;
217
+ const lib = this.lib;
218
+ const uri = this.uri ?? "";
219
+ const out = {
220
+ onLoadStart: event => {
221
+ if (recordId != null) {
222
+ const record = getRecord(recordId);
223
+ const now = Date.now();
224
+ // Out-of-order defense (seen live on iOS remounts/cache hits AND
225
+ // instant file:// failures): the native onLoadStart of a burst can
226
+ // arrive AFTER its onLoad/onError. A "start" right after a settled
227
+ // outcome belongs to that same burst — don't regress the record.
228
+ const settledAt = Math.max(record?.loadedAt ?? 0, record?.erroredAt ?? 0);
229
+ const settledJustNow = settledAt > 0 && now - settledAt < 300;
230
+ updateRecord(recordId, {
231
+ ...(settledJustNow ? {} : {
232
+ status: "loading",
233
+ error: undefined,
234
+ errorCode: undefined,
235
+ errorHeaders: undefined
236
+ }),
237
+ startedAt: now,
238
+ loadCount: (record?.loadCount ?? 0) + 1
239
+ });
240
+ }
241
+ orig.onLoadStart?.(event);
242
+ },
243
+ onProgress: event => {
244
+ if (recordId != null) {
245
+ const p = payloadOf(event);
246
+ updateRecord(recordId, {
247
+ progressSeen: true,
248
+ bytesLoaded: typeof p.loaded === "number" ? p.loaded : undefined,
249
+ bytesTotal: typeof p.total === "number" ? p.total : undefined
250
+ });
251
+ }
252
+ orig.onProgress?.(event);
253
+ },
254
+ onLoad: event => {
255
+ if (recordId != null) {
256
+ const p = payloadOf(event);
257
+ const source = p.source ?? {};
258
+ const now = Date.now();
259
+ const record = getRecord(recordId);
260
+ // Duration only counts from a start belonging to THIS load cycle: a
261
+ // start newer than the previous completion. Without one (instant
262
+ // cache hit whose onLoadStart arrives late/never), report 0ms.
263
+ const start = record?.startedAt != null && record.startedAt <= now && record.startedAt > (record.loadedAt ?? record.createdAt - 1) ? record.startedAt : record?.loadedAt == null ? record?.startedAt ?? record?.createdAt ?? now : now;
264
+ const width = typeof source.width === "number" ? source.width : 0;
265
+ const height = typeof source.height === "number" ? source.height : 0;
266
+ updateRecord(recordId, {
267
+ status: "loaded",
268
+ loadedAt: now,
269
+ durationMs: Math.max(0, now - start),
270
+ error: undefined,
271
+ errorCode: undefined,
272
+ errorHeaders: undefined,
273
+ intrinsic: width > 0 && height > 0 ? {
274
+ width,
275
+ height
276
+ } : record?.intrinsic,
277
+ cacheVerdict: typeof p.cacheType === "string" ? p.cacheType : record?.cacheVerdict,
278
+ cacheVerdictSource: typeof p.cacheType === "string" ? "event" : record?.cacheVerdictSource,
279
+ mediaType: typeof source.mediaType === "string" || source.mediaType === null ? source.mediaType : record?.mediaType,
280
+ isAnimated: typeof source.isAnimated === "boolean" ? source.isAnimated : record?.isAnimated
281
+ });
282
+ settleReloadRequest(recordId);
283
+ if (lib === "rn") queryRnCache(recordId, uri);
284
+ }
285
+ orig.onLoad?.(event);
286
+ },
287
+ onError: event => {
288
+ if (recordId != null) {
289
+ const p = payloadOf(event);
290
+ let message = typeof p.error === "string" ? p.error : String(p.error?.message ?? "unknown error");
291
+ // Simulation sources produce raw file-not-found noise — translate to
292
+ // an honest label (state-based, so it works for both libs' error
293
+ // texts), in our record AND in the event the app receives.
294
+ const record0 = getRecord(recordId);
295
+ const s = imagesState();
296
+ const activeOverride = s.overrides.get(recordId);
297
+ if (activeOverride?.source?.type === "error") {
298
+ message = "Forced error (Buoy Images simulation)";
299
+ if (typeof p.error === "string") p.error = message;
300
+ } else if (s.globalModes.network === "offline" && record0?.sourceKind === "network") {
301
+ message = "Offline simulation (Buoy Images): network image blocked";
302
+ if (typeof p.error === "string") p.error = message;
303
+ }
304
+ updateRecord(recordId, {
305
+ status: "error",
306
+ erroredAt: Date.now(),
307
+ error: message,
308
+ errorCode: typeof p.responseCode === "number" ? p.responseCode : undefined,
309
+ errorHeaders: p.httpResponseHeaders && typeof p.httpResponseHeaders === "object" ? p.httpResponseHeaders : undefined
310
+ });
311
+ settleReloadRequest(recordId);
312
+ }
313
+ orig.onError?.(event);
314
+ },
315
+ onLayout: event => {
316
+ if (recordId != null) {
317
+ const layout = payloadOf(event).layout ?? {};
318
+ const width = typeof layout.width === "number" ? layout.width : 0;
319
+ const height = typeof layout.height === "number" ? layout.height : 0;
320
+ if (width > 0 && height > 0) {
321
+ const record = getRecord(recordId);
322
+ const prev = record?.layout;
323
+ // Size change AFTER the image loaded = layout-shift suspect (the
324
+ // image arriving resized its box — reserve explicit dimensions).
325
+ const shifted = prev != null && record?.loadedAt != null && (Math.abs(prev.width - width) > 1 || Math.abs(prev.height - height) > 1);
326
+ updateRecord(recordId, {
327
+ layout: {
328
+ width,
329
+ height
330
+ },
331
+ ...(shifted ? {
332
+ layoutShifts: (record?.layoutShifts ?? 0) + 1
333
+ } : {})
334
+ });
335
+ }
336
+ }
337
+ orig.onLayout?.(event);
338
+ }
339
+ };
340
+
341
+ // Only forward-wrap the optional ones so we don't attach handlers a
342
+ // library doesn't support (onDisplay is expo-only; onLoadEnd is RN-only).
343
+ out.onLoadEnd = orig.onLoadEnd ? event => orig.onLoadEnd?.(event) : undefined;
344
+ if (this.lib === "expo") {
345
+ out.onDisplay = event => {
346
+ if (recordId != null) updateRecord(recordId, {
347
+ displayedAt: Date.now()
348
+ });
349
+ orig.onDisplay?.(event);
350
+ };
351
+ }
352
+ this.handlerCache = {
353
+ key,
354
+ out
355
+ };
356
+ return out;
357
+ }
358
+ }
359
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["imagesState","dropActionState","settleReloadRequest","createRecord","getRecord","updateRecord","INTERNAL_TEST_ID_PREFIX","isInternalImage","testID","startsWith","isNoiseUri","uri","includes","classifyUri","resolveSourceUri","source","kind","Array","isArray","length","rn","require","resolved","Image","resolveAssetSource","__packager_asset","width","payloadOf","event","native","nativeEvent","queryRnCache","recordId","probe","queryCache","then","result","verdict","cacheVerdict","cacheVerdictSource","catch","setTimeout","record","ImageInstanceTracker","handlerCache","constructor","lib","getRecordId","noteA11y","hasAltText","syncSource","sourceKind","id","unmount","mounted","handlers","orig","key","onLoadStart","onProgress","onLoad","onError","onLoadEnd","onDisplay","onLayout","cached","every","k","i","out","now","Date","settledAt","Math","max","loadedAt","erroredAt","settledJustNow","status","error","undefined","errorCode","errorHeaders","startedAt","loadCount","p","progressSeen","bytesLoaded","loaded","bytesTotal","total","start","createdAt","height","durationMs","intrinsic","cacheType","mediaType","isAnimated","message","String","record0","s","activeOverride","overrides","get","type","globalModes","network","responseCode","httpResponseHeaders","layout","prev","shifted","abs","layoutShifts","displayedAt"],"sourceRoot":"../../../src","sources":["capture/shared.ts"],"mappings":"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","ignoreList":[]}