@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.
- package/README.md +11 -70
- package/lib/commonjs/autoCapture.js +1 -4
- package/lib/commonjs/autoCapture.web.js +1 -6
- package/lib/commonjs/capture/actions.js +1 -243
- package/lib/commonjs/capture/install.js +1 -45
- package/lib/commonjs/capture/install.web.js +1 -250
- package/lib/commonjs/capture/installExpoImage.js +1 -99
- package/lib/commonjs/capture/installRnImage.js +1 -132
- package/lib/commonjs/capture/nativeImageModules.js +1 -30
- package/lib/commonjs/capture/nativeImageModules.web.js +1 -18
- package/lib/commonjs/capture/overrides.js +1 -346
- package/lib/commonjs/capture/rnDecoratorEarly.js +1 -55
- package/lib/commonjs/capture/savings.js +1 -209
- package/lib/commonjs/capture/savings.web.js +1 -71
- package/lib/commonjs/capture/shared.js +1 -378
- package/lib/commonjs/components/ImageDetail.js +1 -455
- package/lib/commonjs/components/ImageDetailFooter.js +1 -158
- package/lib/commonjs/components/ImageRow.js +1 -156
- package/lib/commonjs/components/ImagesHeader.js +1 -63
- package/lib/commonjs/components/ImagesIcon.js +1 -19
- package/lib/commonjs/components/ImagesListFooter.js +1 -126
- package/lib/commonjs/components/ImagesModal.js +1 -240
- package/lib/commonjs/components/ImagesRoot.js +1 -24
- package/lib/commonjs/components/ImagesRoot.web.js +1 -13
- package/lib/commonjs/components/InsightsBar.js +1 -59
- package/lib/commonjs/export.js +1 -81
- package/lib/commonjs/format.js +1 -117
- package/lib/commonjs/hooks/useImageRecords.js +1 -20
- package/lib/commonjs/index.js +1 -261
- package/lib/commonjs/preset.js +1 -39
- package/lib/commonjs/register.js +1 -19
- package/lib/commonjs/registerEarly.js +1 -14
- package/lib/commonjs/remote.js +1 -42
- package/lib/commonjs/state.js +1 -58
- package/lib/commonjs/store/imageEventStore.js +1 -238
- package/lib/commonjs/store/insights.js +1 -76
- package/lib/commonjs/sync/imagesSyncAdapter.js +1 -361
- package/lib/commonjs/types.js +0 -1
- package/lib/module/autoCapture.js +1 -4
- package/lib/module/autoCapture.web.js +1 -5
- package/lib/module/capture/actions.js +1 -230
- package/lib/module/capture/install.js +1 -40
- package/lib/module/capture/install.web.js +1 -243
- package/lib/module/capture/installExpoImage.js +1 -94
- package/lib/module/capture/installRnImage.js +1 -125
- package/lib/module/capture/nativeImageModules.js +1 -24
- package/lib/module/capture/nativeImageModules.web.js +1 -12
- package/lib/module/capture/overrides.js +1 -329
- package/lib/module/capture/rnDecoratorEarly.js +1 -50
- package/lib/module/capture/savings.js +1 -205
- package/lib/module/capture/savings.web.js +1 -67
- package/lib/module/capture/shared.js +1 -369
- package/lib/module/components/ImageDetail.js +1 -451
- package/lib/module/components/ImageDetailFooter.js +1 -154
- package/lib/module/components/ImageRow.js +1 -152
- package/lib/module/components/ImagesHeader.js +1 -59
- package/lib/module/components/ImagesIcon.js +1 -12
- package/lib/module/components/ImagesListFooter.js +1 -122
- package/lib/module/components/ImagesModal.js +1 -235
- package/lib/module/components/ImagesRoot.js +1 -20
- package/lib/module/components/ImagesRoot.web.js +1 -9
- package/lib/module/components/InsightsBar.js +1 -55
- package/lib/module/export.js +1 -76
- package/lib/module/format.js +1 -108
- package/lib/module/hooks/useImageRecords.js +1 -16
- package/lib/module/index.js +1 -79
- package/lib/module/preset.js +1 -35
- package/lib/module/register.js +1 -19
- package/lib/module/registerEarly.js +1 -14
- package/lib/module/remote.js +1 -36
- package/lib/module/state.js +1 -54
- package/lib/module/store/imageEventStore.js +1 -221
- package/lib/module/store/insights.js +1 -71
- package/lib/module/sync/imagesSyncAdapter.js +1 -356
- package/lib/module/types.js +0 -1
- package/lib/web/chunks/chunk-TTS5EH4R.mjs +1 -2
- package/lib/web/index.mjs +3 -4
- package/lib/web/register.mjs +1 -2
- package/package.json +3 -7
- package/register.js +1 -15
- package/lib/commonjs/autoCapture.js.map +0 -1
- package/lib/commonjs/autoCapture.web.js.map +0 -1
- package/lib/commonjs/capture/actions.js.map +0 -1
- package/lib/commonjs/capture/install.js.map +0 -1
- package/lib/commonjs/capture/install.web.js.map +0 -1
- package/lib/commonjs/capture/installExpoImage.js.map +0 -1
- package/lib/commonjs/capture/installRnImage.js.map +0 -1
- package/lib/commonjs/capture/nativeImageModules.js.map +0 -1
- package/lib/commonjs/capture/nativeImageModules.web.js.map +0 -1
- package/lib/commonjs/capture/overrides.js.map +0 -1
- package/lib/commonjs/capture/rnDecoratorEarly.js.map +0 -1
- package/lib/commonjs/capture/savings.js.map +0 -1
- package/lib/commonjs/capture/savings.web.js.map +0 -1
- package/lib/commonjs/capture/shared.js.map +0 -1
- package/lib/commonjs/components/ImageDetail.js.map +0 -1
- package/lib/commonjs/components/ImageDetailFooter.js.map +0 -1
- package/lib/commonjs/components/ImageRow.js.map +0 -1
- package/lib/commonjs/components/ImagesHeader.js.map +0 -1
- package/lib/commonjs/components/ImagesIcon.js.map +0 -1
- package/lib/commonjs/components/ImagesListFooter.js.map +0 -1
- package/lib/commonjs/components/ImagesModal.js.map +0 -1
- package/lib/commonjs/components/ImagesRoot.js.map +0 -1
- package/lib/commonjs/components/ImagesRoot.web.js.map +0 -1
- package/lib/commonjs/components/InsightsBar.js.map +0 -1
- package/lib/commonjs/export.js.map +0 -1
- package/lib/commonjs/format.js.map +0 -1
- package/lib/commonjs/hooks/useImageRecords.js.map +0 -1
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/preset.js.map +0 -1
- package/lib/commonjs/register.js.map +0 -1
- package/lib/commonjs/registerEarly.js.map +0 -1
- package/lib/commonjs/remote.js.map +0 -1
- package/lib/commonjs/state.js.map +0 -1
- package/lib/commonjs/store/imageEventStore.js.map +0 -1
- package/lib/commonjs/store/insights.js.map +0 -1
- package/lib/commonjs/sync/imagesSyncAdapter.js.map +0 -1
- package/lib/commonjs/types.js.map +0 -1
- package/lib/module/autoCapture.js.map +0 -1
- package/lib/module/autoCapture.web.js.map +0 -1
- package/lib/module/capture/actions.js.map +0 -1
- package/lib/module/capture/install.js.map +0 -1
- package/lib/module/capture/install.web.js.map +0 -1
- package/lib/module/capture/installExpoImage.js.map +0 -1
- package/lib/module/capture/installRnImage.js.map +0 -1
- package/lib/module/capture/nativeImageModules.js.map +0 -1
- package/lib/module/capture/nativeImageModules.web.js.map +0 -1
- package/lib/module/capture/overrides.js.map +0 -1
- package/lib/module/capture/rnDecoratorEarly.js.map +0 -1
- package/lib/module/capture/savings.js.map +0 -1
- package/lib/module/capture/savings.web.js.map +0 -1
- package/lib/module/capture/shared.js.map +0 -1
- package/lib/module/components/ImageDetail.js.map +0 -1
- package/lib/module/components/ImageDetailFooter.js.map +0 -1
- package/lib/module/components/ImageRow.js.map +0 -1
- package/lib/module/components/ImagesHeader.js.map +0 -1
- package/lib/module/components/ImagesIcon.js.map +0 -1
- package/lib/module/components/ImagesListFooter.js.map +0 -1
- package/lib/module/components/ImagesModal.js.map +0 -1
- package/lib/module/components/ImagesRoot.js.map +0 -1
- package/lib/module/components/ImagesRoot.web.js.map +0 -1
- package/lib/module/components/InsightsBar.js.map +0 -1
- package/lib/module/export.js.map +0 -1
- package/lib/module/format.js.map +0 -1
- package/lib/module/hooks/useImageRecords.js.map +0 -1
- package/lib/module/index.js.map +0 -1
- package/lib/module/preset.js.map +0 -1
- package/lib/module/register.js.map +0 -1
- package/lib/module/registerEarly.js.map +0 -1
- package/lib/module/remote.js.map +0 -1
- package/lib/module/state.js.map +0 -1
- package/lib/module/store/imageEventStore.js.map +0 -1
- package/lib/module/store/insights.js.map +0 -1
- package/lib/module/sync/imagesSyncAdapter.js.map +0 -1
- package/lib/module/types.js.map +0 -1
- package/lib/typescript/autoCapture.d.ts.map +0 -1
- package/lib/typescript/autoCapture.web.d.ts.map +0 -1
- package/lib/typescript/capture/actions.d.ts.map +0 -1
- package/lib/typescript/capture/install.d.ts.map +0 -1
- package/lib/typescript/capture/install.web.d.ts.map +0 -1
- package/lib/typescript/capture/installExpoImage.d.ts.map +0 -1
- package/lib/typescript/capture/installRnImage.d.ts.map +0 -1
- package/lib/typescript/capture/nativeImageModules.d.ts.map +0 -1
- package/lib/typescript/capture/nativeImageModules.web.d.ts.map +0 -1
- package/lib/typescript/capture/overrides.d.ts.map +0 -1
- package/lib/typescript/capture/rnDecoratorEarly.d.ts.map +0 -1
- package/lib/typescript/capture/savings.d.ts.map +0 -1
- package/lib/typescript/capture/savings.web.d.ts.map +0 -1
- package/lib/typescript/capture/shared.d.ts.map +0 -1
- package/lib/typescript/components/ImageDetail.d.ts.map +0 -1
- package/lib/typescript/components/ImageDetailFooter.d.ts.map +0 -1
- package/lib/typescript/components/ImageRow.d.ts.map +0 -1
- package/lib/typescript/components/ImagesHeader.d.ts.map +0 -1
- package/lib/typescript/components/ImagesIcon.d.ts.map +0 -1
- package/lib/typescript/components/ImagesListFooter.d.ts.map +0 -1
- package/lib/typescript/components/ImagesModal.d.ts.map +0 -1
- package/lib/typescript/components/ImagesRoot.d.ts.map +0 -1
- package/lib/typescript/components/ImagesRoot.web.d.ts.map +0 -1
- package/lib/typescript/components/InsightsBar.d.ts.map +0 -1
- package/lib/typescript/export.d.ts.map +0 -1
- package/lib/typescript/format.d.ts.map +0 -1
- package/lib/typescript/hooks/useImageRecords.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/register.d.ts.map +0 -1
- package/lib/typescript/registerEarly.d.ts.map +0 -1
- package/lib/typescript/remote.d.ts.map +0 -1
- package/lib/typescript/state.d.ts.map +0 -1
- package/lib/typescript/store/imageEventStore.d.ts.map +0 -1
- package/lib/typescript/store/insights.d.ts.map +0 -1
- package/lib/typescript/sync/imagesSyncAdapter.d.ts.map +0 -1
- package/lib/typescript/types.d.ts.map +0 -1
- package/lib/web/chunks/chunk-7CWLRQ2L.mjs +0 -2
- package/lib/web/chunks/chunk-B5A6CYSS.mjs +0 -2
- 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
|
-
|
|
5
|
+
Inspect image loads observed by Buoy's supported image hooks, including timing, dimensions and estimated decoded memory.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<a href="https://buoy.gg/buoy/latest/docs/tools/images"><b>Images guide</b></a> · <a href="https://buoy.gg">buoy.gg</a> · <a href="https://github.com/Buoy-gg/buoy">All tools</a>
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/@buoy-gg/images) [](https://www.npmjs.com/package/@buoy-gg/images)
|
|
8
10
|
|
|
9
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
25
|
+
---
|
|
85
26
|
|
|
86
|
-
|
|
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,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}}
|