@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
package/README.md CHANGED
@@ -1,14 +1,16 @@
1
+ <div align="center">
2
+
1
3
  # @buoy-gg/images
2
4
 
3
- [![npm version](https://img.shields.io/npm/v/@buoy-gg/images?style=flat-square&labelColor=1c1c1c&color=10B981)](https://www.npmjs.com/package/@buoy-gg/images) [![npm downloads](https://img.shields.io/npm/dm/@buoy-gg/images?style=flat-square&labelColor=1c1c1c&color=10B981)](https://www.npmjs.com/package/@buoy-gg/images)
5
+ Inspect image loads observed by Buoy's supported image hooks, including timing, dimensions and estimated decoded memory.
4
6
 
5
- Inspect image loads observed by Buoy’s supported image hooks, including timing, dimensions, and estimated decoded memory.
7
+ <a href="https://buoy.gg/buoy/latest/docs/tools/images"><b>Images guide</b></a> &nbsp;·&nbsp; <a href="https://buoy.gg">buoy.gg</a> &nbsp;·&nbsp; <a href="https://github.com/Buoy-gg/buoy">All tools</a>
6
8
 
7
- Part of [Buoy](https://github.com/Buoy-gg/buoy). Install the package, complete account setup, and follow the integration steps below.
9
+ [![npm version](https://img.shields.io/npm/v/@buoy-gg/images?style=flat-square&labelColor=10302a&color=2a9d78)](https://www.npmjs.com/package/@buoy-gg/images) [![npm downloads](https://img.shields.io/npm/dm/@buoy-gg/images?style=flat-square&labelColor=10302a&color=2a9d78&label=downloads%2Fmonth)](https://www.npmjs.com/package/@buoy-gg/images)
8
10
 
9
- Buoy's own icons, backgrounds and tool previews are excluded from image capture. App images remain visible, including app views that load the same URL as a tool preview.
11
+ <a href="https://buoy.gg/buoy/latest/docs/tools/images"><img src="https://raw.githubusercontent.com/Buoy-gg/buoy/main/.github/readme/tools/images.png" alt="Watch the Images film on buoy.gg" width="640" /></a>
10
12
 
11
- Native image loading can bypass JavaScript network capture. This package instruments supported React Native `Image` and `expo-image` paths to provide image-specific details.
13
+ </div>
12
14
 
13
15
  ## Install
14
16
 
@@ -16,71 +18,10 @@ Native image loading can bypass JavaScript network capture. This package instrum
16
18
  npm install @buoy-gg/core @buoy-gg/images
17
19
  ```
18
20
 
19
- Then add the register import as the **first line** of your app entry file (`index.js` / `index.ts`):
20
-
21
- ```ts
22
- import "@buoy-gg/images/register";
23
- ```
24
-
25
- > Why first? RN core's `<Image>` instrumentation uses React Native's official component-decorator hook, which must be installed before the Image module first evaluates. expo-image capture has no such constraint — it works no matter when the tool loads. If you skip the import, the tool tells you what it's missing instead of sitting silently empty.
26
-
27
- ## Before you start
28
-
29
- Use a development build with `@buoy-gg/core` and a Free or Pro Buoy account key. From your app’s directory, sign in:
30
-
31
- ```bash
32
- npx --package=@buoy-gg/core buoy login
33
- ```
34
-
35
- For Expo, initialize Buoy before rendering the menu:
36
-
37
- ```tsx
38
- import { Buoy } from "@buoy-gg/core";
39
-
40
- Buoy.init({ licenseKey: process.env.EXPO_PUBLIC_BUOY_KEY });
41
- ```
42
-
43
- The login command writes the Expo key to `.env.local`. For React Native CLI, pass the key from your app’s environment configuration; React Native does not load `.env.local` automatically. Mount `FloatingDevTools` inside the same providers as your screens and restart the development server after installation. The [Quick Start](https://buoy.gg/buoy/latest/docs/quick-start) shows the complete root component setup.
44
-
45
- ## Quick start
46
-
47
- ```tsx
48
- import { FloatingDevTools } from "@buoy-gg/core";
49
-
50
- export default function App() {
51
- return (
52
- <>
53
- <YourApp />
54
- <FloatingDevTools />
55
- </>
56
- );
57
- }
58
- ```
59
-
60
- The IMAGES tool appears in the menu. Open it and browse image loads observed during the session.
61
-
62
- ## Check the integration
63
-
64
- Load a supported image after the capture hook is installed and inspect the entry. Treat cache results according to the image library’s available signals and decoded memory as an estimate. Native image paths outside those hooks may not appear.
65
-
66
- ## What you get
67
-
68
- - **Live image registry** — observed RN `<Image>` and expo-image loads: thumbnail, source, status, load time, decoded dimensions
69
- - **Cache verdicts** — memory / disk / network per load (expo-image reports it directly; RN core is classified via `Image.queryCache`)
70
- - **Oversize auditing** — decoded size vs displayed size × device pixel ratio, Lighthouse-style: green within 10%, red beyond 50%, with estimated wasted decoded memory and the exact size you should serve
71
- - **Memory accounting** — estimated decoded-bitmap bytes per image and totals across the session (catch ballooning before the OOM)
72
- - **Failure log** — captured `onError` events with the message, and on iOS the HTTP status code + response headers
73
- - **Cache actions** — clear expo-image memory/disk caches from the detail view
74
- - **Upscale detection** — tiny sources stretched into big boxes (blurry images) get flagged too
75
-
76
- ## Desktop & AI
77
-
78
- To connect a React Native app to [Buoy Desktop](https://github.com/Buoy-gg/Buoy-Desktop) or MCP, install `@buoy-gg/external-sync` and follow the [Desktop connection guide](https://buoy.gg/buoy/latest/docs/desktop). Sign in to Desktop separately. [MCP setup](https://buoy.gg/buoy/latest/docs/mcp) also requires a process account and Pro access. Available remote actions depend on the tool and app integration.
79
-
80
- ## Account and plan requirements
21
+ Images appears in the menu once installed. Open it to browse the image loads seen during the session.
81
22
 
82
- Use a Free or Pro Buoy account. History limits and paid features vary by tool; see [pricing](https://buoy.gg/pricing). Production access requires Pro where supported. Development-only hooks and actions remain unavailable in release builds.
23
+ The [Images guide](https://buoy.gg/buoy/latest/docs/tools/images) covers setup, what it captures and its limits. New to Buoy? Start with the [Quick start](https://buoy.gg/buoy/latest/docs/quick-start).
83
24
 
84
- ## Web support (unreleased)
25
+ ---
85
26
 
86
- Browser capture observes DOM images and supports shared overrides and size analysis. Savings previews use Canvas; cross-origin reads require permission from the image server. The browser build is available in this checkout and has not been published yet. See the [web setup guide](https://buoy.gg/buoy/latest/docs/web-preview) for registration, dependencies, and browser boundaries.
27
+ <sub>Part of <a href="https://buoy.gg">Buoy</a>, developer tools that live inside your app. Proprietary software. © Buoy LLC. <a href="https://buoy.gg/terms">Terms</a></sub>
@@ -1,4 +1 @@
1
- "use strict";
2
-
3
- require("./register");
4
- //# sourceMappingURL=autoCapture.js.map
1
+ "use strict";require("./register");
@@ -1,6 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- //# sourceMappingURL=autoCapture.web.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});
@@ -1,243 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.dropActionState = dropActionState;
7
- exports.evictExpoDiskEntry = evictExpoDiskEntry;
8
- exports.getReloadNonce = getReloadNonce;
9
- exports.getReloadRequest = getReloadRequest;
10
- exports.hardReloadAllMounted = hardReloadAllMounted;
11
- exports.hardReloadRecord = hardReloadRecord;
12
- exports.registerExpoInstance = registerExpoInstance;
13
- exports.retryRecord = retryRecord;
14
- exports.settleReloadRequest = settleReloadRequest;
15
- exports.subscribeActions = subscribeActions;
16
- var _nativeImageModules = require("./nativeImageModules");
17
- var _remote = require("../remote");
18
- var _state = require("../state");
19
- var _overrides = require("./overrides");
20
- /**
21
- * Per-image actions: hard reload (bypass cache) and retry.
22
- *
23
- * RN core path: the decorator wrapper owns every mounted <Image>'s props, so a
24
- * reload request re-renders the wrapper with a bumped `key` (native remount →
25
- * fresh load cycle) and, for cache-busting, `source.cache: 'reload'` injected
26
- * — VERIFIED supported on BOTH platforms (iOS NSURLRequest policy;
27
- * Android ReactImageView.kt reads source."cache" → Fresco full-fetch). The
28
- * override stays applied until the load settles, then reverts lazily on the
29
- * app's next natural re-render (avoids an extra cache round-trip).
30
- *
31
- * expo-image path: the patched class instance exposes the public
32
- * `reloadAsync()`. Cache-busting first evicts the disk entry (cache path +
33
- * expo-file-system delete) and clears expo's memory cache (global — no
34
- * per-entry memory eviction exists), so the reload is a true refetch that
35
- * rewrites both cache tiers.
36
- */
37
-
38
- // ---------------------------------------------------------------------------
39
- // RN reload-request bus (consumed by the decorator wrapper)
40
- // ---------------------------------------------------------------------------
41
-
42
- function subscribeActions(listener) {
43
- const s = (0, _state.imagesState)();
44
- s.actionListeners.add(listener);
45
- return () => (0, _state.imagesState)().actionListeners.delete(listener);
46
- }
47
- function getReloadRequest(recordId) {
48
- if (recordId == null) return undefined;
49
- return (0, _state.imagesState)().reloadRequests.get(recordId);
50
- }
51
-
52
- /** Reload nonce for a record (0 = never requested). Snapshot for the wrapper. */
53
- function getReloadNonce(recordId) {
54
- return getReloadRequest(recordId)?.nonce ?? 0;
55
- }
56
- function requestRnReload(recordId, bust) {
57
- const s = (0, _state.imagesState)();
58
- const prev = s.reloadRequests.get(recordId);
59
- s.reloadRequests.set(recordId, {
60
- nonce: (prev?.nonce ?? 0) + 1,
61
- bust
62
- });
63
- // touchRecord bumps the render version (the wrapper's snapshot) and emits.
64
- (0, _overrides.touchRecord)(recordId);
65
- }
66
-
67
- /**
68
- * Mark a request consumed once its load settles (called from the tracker on
69
- * load/error). Silent — the wrapper reverts the prop override on the app's
70
- * next natural re-render instead of forcing an immediate one.
71
- */
72
- function settleReloadRequest(recordId) {
73
- const s = (0, _state.imagesState)();
74
- const req = s.reloadRequests.get(recordId);
75
- if (req?.bust) {
76
- s.reloadRequests.set(recordId, {
77
- nonce: req.nonce,
78
- bust: false
79
- });
80
- }
81
- }
82
- function dropActionState(recordId) {
83
- const s = (0, _state.imagesState)();
84
- s.reloadRequests.delete(recordId);
85
- s.expoInstances.delete(recordId);
86
- s.overrides.delete(recordId);
87
- s.flashUntil.delete(recordId);
88
- s.recordVersions.delete(recordId);
89
- }
90
-
91
- // ---------------------------------------------------------------------------
92
- // expo instance registry (populated by the render patch)
93
- // ---------------------------------------------------------------------------
94
-
95
- function registerExpoInstance(recordId, instance) {
96
- if (recordId == null) return;
97
- (0, _state.imagesState)().expoInstances.set(recordId, instance);
98
- }
99
- function expoImageStatics() {
100
- try {
101
- return (0, _nativeImageModules.loadExpoImage)().Image ?? null;
102
- } catch {
103
- return null;
104
- }
105
- }
106
- /**
107
- * expo-file-system, legacy path first (v19+/SDK 54+ moved the function API
108
- * there) then the main import — same pattern as shared-ui's persistentStorage.
109
- */
110
- function loadFileSystem() {
111
- try {
112
- const mod = (0, _nativeImageModules.loadLegacyFileSystem)();
113
- const fs = mod?.default || mod;
114
- if (fs?.deleteAsync) return fs;
115
- } catch {
116
- // try main import
117
- }
118
- try {
119
- const mod = (0, _nativeImageModules.loadFileSystemModule)();
120
- const fs = mod?.default || mod;
121
- if (fs?.deleteAsync) return fs;
122
- } catch {
123
- // not installed
124
- }
125
- return null;
126
- }
127
-
128
- /**
129
- * Delete an expo-image disk-cache entry (JS-only: cache path + file delete).
130
- * Returns true if an entry existed and was deleted.
131
- */
132
- async function evictExpoDiskEntry(record) {
133
- const statics = expoImageStatics();
134
- const fileSystem = loadFileSystem();
135
- if (!statics?.getCachePathAsync || !fileSystem?.deleteAsync || !record.uri) return false;
136
- try {
137
- const path = await statics.getCachePathAsync(record.uri);
138
- if (!path) return false;
139
- const uri = path.startsWith("file://") ? path : `file://${path}`;
140
- await fileSystem.deleteAsync(uri, {
141
- idempotent: true
142
- });
143
- return true;
144
- } catch {
145
- return false;
146
- }
147
- }
148
-
149
- // ---------------------------------------------------------------------------
150
- // High-level dispatchers (used by the detail view)
151
- // ---------------------------------------------------------------------------
152
-
153
- /** Fresh load attempt for a mounted image (no cache bypass). */
154
- async function retryRecord(record) {
155
- const remote = (0, _remote.remoteImagesDispatch)();
156
- if (remote) return (0, _remote.remoteActionResult)(remote("retry", {
157
- id: record.id
158
- }));
159
- if (!record.mounted) {
160
- return {
161
- ok: false,
162
- message: "Instance unmounted — cannot reload"
163
- };
164
- }
165
- if (record.lib === "expo") {
166
- const instance = (0, _state.imagesState)().expoInstances.get(record.id);
167
- if (!instance?.reloadAsync) {
168
- return {
169
- ok: false,
170
- message: "Live instance not reachable"
171
- };
172
- }
173
- await instance.reloadAsync();
174
- return {
175
- ok: true,
176
- message: "Reload requested"
177
- };
178
- }
179
- requestRnReload(record.id, false);
180
- return {
181
- ok: true,
182
- message: "Remounting image"
183
- };
184
- }
185
-
186
- /** Hard-reload every mounted image (mass cache-bust). Returns count started. */
187
- async function hardReloadAllMounted() {
188
- const remote = (0, _remote.remoteImagesDispatch)();
189
- if (remote) {
190
- return (0, _remote.remoteActionResult)(remote("massAction", {
191
- kind: "reload"
192
- }));
193
- }
194
- const {
195
- getSnapshot
196
- } = require("../store/imageEventStore");
197
- let count = 0;
198
- for (const record of getSnapshot()) {
199
- if (!record.mounted) continue;
200
- const result = await hardReloadRecord(record);
201
- if (result.ok) count++;
202
- }
203
- return {
204
- ok: count > 0,
205
- message: `Hard-reloading ${count} mounted image${count === 1 ? "" : "s"}`
206
- };
207
- }
208
-
209
- /** Bypass-cache reload: refetches from network and rewrites the caches. */
210
- async function hardReloadRecord(record) {
211
- const remote = (0, _remote.remoteImagesDispatch)();
212
- if (remote) return (0, _remote.remoteActionResult)(remote("hardReload", {
213
- id: record.id
214
- }));
215
- if (!record.mounted) {
216
- return {
217
- ok: false,
218
- message: "Instance unmounted — cannot reload"
219
- };
220
- }
221
- if (record.sourceKind !== "network") {
222
- // Local/asset sources have no HTTP cache to bust — plain remount instead.
223
- return retryRecord(record);
224
- }
225
- if (record.lib === "expo") {
226
- const evicted = await evictExpoDiskEntry(record);
227
- const statics = expoImageStatics();
228
- // No per-entry memory eviction exists — global clear is the honest option.
229
- await statics?.clearMemoryCache?.().catch?.(() => false);
230
- const result = await retryRecord(record);
231
- if (!result.ok) return result;
232
- return {
233
- ok: true,
234
- message: evicted ? "Disk entry evicted, memory cache cleared, refetching" : "Memory cache cleared, refetching (no disk entry found)"
235
- };
236
- }
237
- requestRnReload(record.id, true);
238
- return {
239
- ok: true,
240
- message: "Refetching with cache bypassed"
241
- };
242
- }
243
- //# sourceMappingURL=actions.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.dropActionState=dropActionState;exports.evictExpoDiskEntry=evictExpoDiskEntry;exports.getReloadNonce=getReloadNonce;exports.getReloadRequest=getReloadRequest;exports.hardReloadAllMounted=hardReloadAllMounted;exports.hardReloadRecord=hardReloadRecord;exports.registerExpoInstance=registerExpoInstance;exports.retryRecord=retryRecord;exports.settleReloadRequest=settleReloadRequest;exports.subscribeActions=subscribeActions;var _nativeImageModules=require("./nativeImageModules");var _remote=require("../remote");var _state=require("../state");var _overrides=require("./overrides");function subscribeActions(e){const t=(0,_state.imagesState)();t.actionListeners.add(e);return()=>(0,_state.imagesState)().actionListeners.delete(e)}function getReloadRequest(e){if(e==null)return void 0;return(0,_state.imagesState)().reloadRequests.get(e)}function getReloadNonce(e){return getReloadRequest(e)?.nonce??0}function requestRnReload(e,t){const s=(0,_state.imagesState)();const n=s.reloadRequests.get(e);s.reloadRequests.set(e,{nonce:(n?.nonce??0)+1,bust:t});(0,_overrides.touchRecord)(e)}function settleReloadRequest(e){const t=(0,_state.imagesState)();const s=t.reloadRequests.get(e);if(s?.bust){t.reloadRequests.set(e,{nonce:s.nonce,bust:false})}}function dropActionState(e){const t=(0,_state.imagesState)();t.reloadRequests.delete(e);t.expoInstances.delete(e);t.overrides.delete(e);t.flashUntil.delete(e);t.recordVersions.delete(e)}function registerExpoInstance(e,t){if(e==null)return;(0,_state.imagesState)().expoInstances.set(e,t)}function expoImageStatics(){try{return(0,_nativeImageModules.loadExpoImage)().Image??null}catch{return null}}function loadFileSystem(){try{const e=(0,_nativeImageModules.loadLegacyFileSystem)();const t=e?.default||e;if(t?.deleteAsync)return t}catch{}try{const e=(0,_nativeImageModules.loadFileSystemModule)();const t=e?.default||e;if(t?.deleteAsync)return t}catch{}return null}async function evictExpoDiskEntry(e){const t=expoImageStatics();const s=loadFileSystem();if(!t?.getCachePathAsync||!s?.deleteAsync||!e.uri)return false;try{const n=await t.getCachePathAsync(e.uri);if(!n)return false;const a=n.startsWith("file://")?n:`file://${n}`;await s.deleteAsync(a,{idempotent:true});return true}catch{return false}}async function retryRecord(e){const t=(0,_remote.remoteImagesDispatch)();if(t)return(0,_remote.remoteActionResult)(t("retry",{id:e.id}));if(!e.mounted){return{ok:false,message:"Instance unmounted \u2014 cannot reload"}}if(e.lib==="expo"){const s=(0,_state.imagesState)().expoInstances.get(e.id);if(!s?.reloadAsync){return{ok:false,message:"Live instance not reachable"}}await s.reloadAsync();return{ok:true,message:"Reload requested"}}requestRnReload(e.id,false);return{ok:true,message:"Remounting image"}}async function hardReloadAllMounted(){const e=(0,_remote.remoteImagesDispatch)();if(e){return(0,_remote.remoteActionResult)(e("massAction",{kind:"reload"}))}const{getSnapshot:t}=require("../store/imageEventStore");let s=0;for(const n of t()){if(!n.mounted)continue;const a=await hardReloadRecord(n);if(a.ok)s++}return{ok:s>0,message:`Hard-reloading ${s} mounted image${s===1?"":"s"}`}}async function hardReloadRecord(e){const t=(0,_remote.remoteImagesDispatch)();if(t)return(0,_remote.remoteActionResult)(t("hardReload",{id:e.id}));if(!e.mounted){return{ok:false,message:"Instance unmounted \u2014 cannot reload"}}if(e.sourceKind!=="network"){return retryRecord(e)}if(e.lib==="expo"){const s=await evictExpoDiskEntry(e);const n=expoImageStatics();await n?.clearMemoryCache?.().catch?.(()=>false);const a=await retryRecord(e);if(!a.ok)return a;return{ok:true,message:s?"Disk entry evicted, memory cache cleared, refetching":"Memory cache cleared, refetching (no disk entry found)"}}requestRnReload(e.id,true);return{ok:true,message:"Refetching with cache bypassed"}}
@@ -1,45 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.getCaptureStatus = getCaptureStatus;
7
- exports.installImageCapture = installImageCapture;
8
- var _state = require("../state");
9
- var _installExpoImage = require("./installExpoImage");
10
- var _installRnImage = require("./installRnImage");
11
- /**
12
- * installImageCapture — idempotent entry point for the capture layer.
13
- *
14
- * IMPORTANT (timing): the RN-core decorator only takes effect if this runs
15
- * before anything evaluates the `Image` module from 'react-native'. The
16
- * recommended integration is `import "@buoy-gg/images/register"` as the FIRST
17
- * import of the app entry file. The expo-image patch has no such constraint.
18
- *
19
- * Idempotency is keyed on the globalThis singleton, so even if this package
20
- * gets evaluated as two module instances, capture installs exactly once.
21
- */
22
-
23
- function installImageCapture() {
24
- const s = (0, _state.imagesState)();
25
- // Mirror mode (desktop dashboard): never instrument the dashboard's own UI.
26
- if (s.captureDisabled || s.captureInstalled) return;
27
- s.captureInstalled = true;
28
- (0, _installRnImage.installRnImageInterceptor)();
29
- (0, _installExpoImage.installExpoImageInterceptor)();
30
- }
31
- function getCaptureStatus() {
32
- // Mirror mode: report the synced DEVICE's capture status, not the local probe.
33
- const mirrored = (0, _state.imagesState)().mirrorCaptureStatus;
34
- if (mirrored) return mirrored;
35
- const rn = (0, _installRnImage.rnCaptureStatus)();
36
- const expo = (0, _installExpoImage.expoCaptureStatus)();
37
- return {
38
- installed: (0, _state.imagesState)().captureInstalled,
39
- rnDecoratorActive: rn.decoratorActive,
40
- rnDecoratorTooLate: rn.tooLate,
41
- expoPatched: expo.patched,
42
- expoAvailable: expo.available
43
- };
44
- }
45
- //# sourceMappingURL=install.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getCaptureStatus=getCaptureStatus;exports.installImageCapture=installImageCapture;var _state=require("../state");var _installExpoImage=require("./installExpoImage");var _installRnImage=require("./installRnImage");function installImageCapture(){const t=(0,_state.imagesState)();if(t.captureDisabled||t.captureInstalled)return;t.captureInstalled=true;(0,_installRnImage.installRnImageInterceptor)();(0,_installExpoImage.installExpoImageInterceptor)()}function getCaptureStatus(){const t=(0,_state.imagesState)().mirrorCaptureStatus;if(t)return t;const e=(0,_installRnImage.rnCaptureStatus)();const a=(0,_installExpoImage.expoCaptureStatus)();return{installed:(0,_state.imagesState)().captureInstalled,rnDecoratorActive:e.decoratorActive,rnDecoratorTooLate:e.tooLate,expoPatched:a.patched,expoAvailable:a.available}}