@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.
- package/LICENSE +58 -0
- package/README.md +58 -0
- package/lib/commonjs/capture/actions.js +227 -0
- package/lib/commonjs/capture/actions.js.map +1 -0
- package/lib/commonjs/capture/install.js +41 -0
- package/lib/commonjs/capture/install.js.map +1 -0
- package/lib/commonjs/capture/installExpoImage.js +99 -0
- package/lib/commonjs/capture/installExpoImage.js.map +1 -0
- package/lib/commonjs/capture/installRnImage.js +128 -0
- package/lib/commonjs/capture/installRnImage.js.map +1 -0
- package/lib/commonjs/capture/overrides.js +286 -0
- package/lib/commonjs/capture/overrides.js.map +1 -0
- package/lib/commonjs/capture/savings.js +193 -0
- package/lib/commonjs/capture/savings.js.map +1 -0
- package/lib/commonjs/capture/shared.js +367 -0
- package/lib/commonjs/capture/shared.js.map +1 -0
- package/lib/commonjs/components/ImageDetail.js +444 -0
- package/lib/commonjs/components/ImageDetail.js.map +1 -0
- package/lib/commonjs/components/ImageDetailFooter.js +232 -0
- package/lib/commonjs/components/ImageDetailFooter.js.map +1 -0
- package/lib/commonjs/components/ImageRow.js +164 -0
- package/lib/commonjs/components/ImageRow.js.map +1 -0
- package/lib/commonjs/components/ImagesHeader.js +63 -0
- package/lib/commonjs/components/ImagesHeader.js.map +1 -0
- package/lib/commonjs/components/ImagesIcon.js +59 -0
- package/lib/commonjs/components/ImagesIcon.js.map +1 -0
- package/lib/commonjs/components/ImagesListFooter.js +194 -0
- package/lib/commonjs/components/ImagesListFooter.js.map +1 -0
- package/lib/commonjs/components/ImagesModal.js +173 -0
- package/lib/commonjs/components/ImagesModal.js.map +1 -0
- package/lib/commonjs/components/ImagesRoot.js +24 -0
- package/lib/commonjs/components/ImagesRoot.js.map +1 -0
- package/lib/commonjs/components/InsightsBar.js +59 -0
- package/lib/commonjs/components/InsightsBar.js.map +1 -0
- package/lib/commonjs/export.js +81 -0
- package/lib/commonjs/export.js.map +1 -0
- package/lib/commonjs/format.js +117 -0
- package/lib/commonjs/format.js.map +1 -0
- package/lib/commonjs/hooks/useImageRecords.js +20 -0
- package/lib/commonjs/hooks/useImageRecords.js.map +1 -0
- package/lib/commonjs/index.js +236 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/preset.js +45 -0
- package/lib/commonjs/preset.js.map +1 -0
- package/lib/commonjs/register.js +19 -0
- package/lib/commonjs/register.js.map +1 -0
- package/lib/commonjs/state.js +54 -0
- package/lib/commonjs/state.js.map +1 -0
- package/lib/commonjs/store/imageEventStore.js +160 -0
- package/lib/commonjs/store/imageEventStore.js.map +1 -0
- package/lib/commonjs/store/insights.js +76 -0
- package/lib/commonjs/store/insights.js.map +1 -0
- package/lib/commonjs/sync/imagesSyncAdapter.js +315 -0
- package/lib/commonjs/sync/imagesSyncAdapter.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/capture/actions.js +214 -0
- package/lib/module/capture/actions.js.map +1 -0
- package/lib/module/capture/install.js +36 -0
- package/lib/module/capture/install.js.map +1 -0
- package/lib/module/capture/installExpoImage.js +94 -0
- package/lib/module/capture/installExpoImage.js.map +1 -0
- package/lib/module/capture/installRnImage.js +122 -0
- package/lib/module/capture/installRnImage.js.map +1 -0
- package/lib/module/capture/overrides.js +269 -0
- package/lib/module/capture/overrides.js.map +1 -0
- package/lib/module/capture/savings.js +189 -0
- package/lib/module/capture/savings.js.map +1 -0
- package/lib/module/capture/shared.js +359 -0
- package/lib/module/capture/shared.js.map +1 -0
- package/lib/module/components/ImageDetail.js +440 -0
- package/lib/module/components/ImageDetail.js.map +1 -0
- package/lib/module/components/ImageDetailFooter.js +228 -0
- package/lib/module/components/ImageDetailFooter.js.map +1 -0
- package/lib/module/components/ImageRow.js +160 -0
- package/lib/module/components/ImageRow.js.map +1 -0
- package/lib/module/components/ImagesHeader.js +59 -0
- package/lib/module/components/ImagesHeader.js.map +1 -0
- package/lib/module/components/ImagesIcon.js +55 -0
- package/lib/module/components/ImagesIcon.js.map +1 -0
- package/lib/module/components/ImagesListFooter.js +190 -0
- package/lib/module/components/ImagesListFooter.js.map +1 -0
- package/lib/module/components/ImagesModal.js +169 -0
- package/lib/module/components/ImagesModal.js.map +1 -0
- package/lib/module/components/ImagesRoot.js +20 -0
- package/lib/module/components/ImagesRoot.js.map +1 -0
- package/lib/module/components/InsightsBar.js +55 -0
- package/lib/module/components/InsightsBar.js.map +1 -0
- package/lib/module/export.js +76 -0
- package/lib/module/export.js.map +1 -0
- package/lib/module/format.js +108 -0
- package/lib/module/format.js.map +1 -0
- package/lib/module/hooks/useImageRecords.js +16 -0
- package/lib/module/hooks/useImageRecords.js.map +1 -0
- package/lib/module/index.js +73 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/preset.js +40 -0
- package/lib/module/preset.js.map +1 -0
- package/lib/module/register.js +19 -0
- package/lib/module/register.js.map +1 -0
- package/lib/module/state.js +50 -0
- package/lib/module/state.js.map +1 -0
- package/lib/module/store/imageEventStore.js +146 -0
- package/lib/module/store/imageEventStore.js.map +1 -0
- package/lib/module/store/insights.js +71 -0
- package/lib/module/store/insights.js.map +1 -0
- package/lib/module/sync/imagesSyncAdapter.js +311 -0
- package/lib/module/sync/imagesSyncAdapter.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/capture/actions.d.ts +49 -0
- package/lib/typescript/capture/actions.d.ts.map +1 -0
- package/lib/typescript/capture/install.d.ts +15 -0
- package/lib/typescript/capture/install.d.ts.map +1 -0
- package/lib/typescript/capture/installExpoImage.d.ts +23 -0
- package/lib/typescript/capture/installExpoImage.d.ts.map +1 -0
- package/lib/typescript/capture/installRnImage.d.ts +24 -0
- package/lib/typescript/capture/installRnImage.d.ts.map +1 -0
- package/lib/typescript/capture/overrides.d.ts +83 -0
- package/lib/typescript/capture/overrides.d.ts.map +1 -0
- package/lib/typescript/capture/savings.d.ts +37 -0
- package/lib/typescript/capture/savings.d.ts.map +1 -0
- package/lib/typescript/capture/shared.d.ts +61 -0
- package/lib/typescript/capture/shared.d.ts.map +1 -0
- package/lib/typescript/components/ImageDetail.d.ts +13 -0
- package/lib/typescript/components/ImageDetail.d.ts.map +1 -0
- package/lib/typescript/components/ImageDetailFooter.d.ts +19 -0
- package/lib/typescript/components/ImageDetailFooter.d.ts.map +1 -0
- package/lib/typescript/components/ImageRow.d.ts +15 -0
- package/lib/typescript/components/ImageRow.d.ts.map +1 -0
- package/lib/typescript/components/ImagesHeader.d.ts +25 -0
- package/lib/typescript/components/ImagesHeader.d.ts.map +1 -0
- package/lib/typescript/components/ImagesIcon.d.ts +13 -0
- package/lib/typescript/components/ImagesIcon.d.ts.map +1 -0
- package/lib/typescript/components/ImagesListFooter.d.ts +8 -0
- package/lib/typescript/components/ImagesListFooter.d.ts.map +1 -0
- package/lib/typescript/components/ImagesModal.d.ts +17 -0
- package/lib/typescript/components/ImagesModal.d.ts.map +1 -0
- package/lib/typescript/components/ImagesRoot.d.ts +11 -0
- package/lib/typescript/components/ImagesRoot.d.ts.map +1 -0
- package/lib/typescript/components/InsightsBar.d.ts +13 -0
- package/lib/typescript/components/InsightsBar.d.ts.map +1 -0
- package/lib/typescript/export.d.ts +12 -0
- package/lib/typescript/export.d.ts.map +1 -0
- package/lib/typescript/format.d.ts +26 -0
- package/lib/typescript/format.d.ts.map +1 -0
- package/lib/typescript/hooks/useImageRecords.d.ts +11 -0
- package/lib/typescript/hooks/useImageRecords.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +33 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/preset.d.ts +38 -0
- package/lib/typescript/preset.d.ts.map +1 -0
- package/lib/typescript/register.d.ts +15 -0
- package/lib/typescript/register.d.ts.map +1 -0
- package/lib/typescript/state.d.ts +54 -0
- package/lib/typescript/state.d.ts.map +1 -0
- package/lib/typescript/store/imageEventStore.d.ts +34 -0
- package/lib/typescript/store/imageEventStore.d.ts.map +1 -0
- package/lib/typescript/store/insights.d.ts +11 -0
- package/lib/typescript/store/insights.d.ts.map +1 -0
- package/lib/typescript/sync/imagesSyncAdapter.d.ts +205 -0
- package/lib/typescript/sync/imagesSyncAdapter.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +121 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/package.json +67 -0
- package/register.d.ts +1 -0
- package/register.js +15 -0
- package/src/capture/actions.ts +206 -0
- package/src/capture/install.ts +36 -0
- package/src/capture/installExpoImage.ts +115 -0
- package/src/capture/installRnImage.tsx +133 -0
- package/src/capture/overrides.ts +282 -0
- package/src/capture/savings.ts +193 -0
- package/src/capture/shared.ts +387 -0
- package/src/components/ImageDetail.tsx +456 -0
- package/src/components/ImageDetailFooter.tsx +270 -0
- package/src/components/ImageRow.tsx +148 -0
- package/src/components/ImagesHeader.tsx +77 -0
- package/src/components/ImagesIcon.tsx +66 -0
- package/src/components/ImagesListFooter.tsx +193 -0
- package/src/components/ImagesModal.tsx +195 -0
- package/src/components/ImagesRoot.tsx +18 -0
- package/src/components/InsightsBar.tsx +51 -0
- package/src/export.ts +100 -0
- package/src/format.ts +85 -0
- package/src/hooks/useImageRecords.ts +24 -0
- package/src/index.tsx +108 -0
- package/src/preset.tsx +35 -0
- package/src/register.ts +17 -0
- package/src/state.ts +88 -0
- package/src/store/imageEventStore.ts +162 -0
- package/src/store/insights.ts +66 -0
- package/src/sync/imagesSyncAdapter.ts +261 -0
- package/src/types.ts +111 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sync adapter for the Images tool, consumed by @buoy-gg/external-sync's
|
|
5
|
+
* `useExternalSync` (structurally matches its ToolSyncAdapter interface so
|
|
6
|
+
* this package doesn't need a dependency on it — same pattern as js-top's
|
|
7
|
+
* adapter). Exposes the live image registry to the desktop dashboard and the
|
|
8
|
+
* MCP server, plus every action the on-device UI has: reload/retry,
|
|
9
|
+
* simulation overrides (force error/loading/blank/URL swap), locate-flash,
|
|
10
|
+
* global modes, and cache clears.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { evictExpoDiskEntry, hardReloadAllMounted, hardReloadRecord, retryRecord } from "../capture/actions";
|
|
14
|
+
import { getCaptureStatus } from "../capture/install";
|
|
15
|
+
import { clearAllOverrides, clearOverride, flashAllMounted, flashRecord, getGlobalModes, setBlankImages, setNetworkMode, setOverride, setOverrideForAllMounted } from "../capture/overrides";
|
|
16
|
+
import { proveSavings } from "../capture/savings";
|
|
17
|
+
import { computeInsights } from "../store/insights";
|
|
18
|
+
import { clearRecords, computeStats, estDecodedBytes, estWastedBytes, getRecord, getSnapshot, neededPixels, oversizeFactor, subscribe } from "../store/imageEventStore";
|
|
19
|
+
/** Slim wire form of a record (heavy/derived fields precomputed + rounded). */
|
|
20
|
+
function toWire(record) {
|
|
21
|
+
const factor = oversizeFactor(record);
|
|
22
|
+
return {
|
|
23
|
+
id: record.id,
|
|
24
|
+
lib: record.lib,
|
|
25
|
+
uri: record.uri,
|
|
26
|
+
kind: record.sourceKind,
|
|
27
|
+
status: record.status,
|
|
28
|
+
mounted: record.mounted,
|
|
29
|
+
cache: record.cacheVerdict ?? null,
|
|
30
|
+
cacheSource: record.cacheVerdictSource ?? null,
|
|
31
|
+
ms: record.durationMs != null ? Math.round(record.durationMs) : null,
|
|
32
|
+
intrinsic: record.intrinsic ?? null,
|
|
33
|
+
layout: record.layout ? {
|
|
34
|
+
width: Math.round(record.layout.width),
|
|
35
|
+
height: Math.round(record.layout.height)
|
|
36
|
+
} : null,
|
|
37
|
+
neededPx: neededPixels(record),
|
|
38
|
+
oversizeFactor: factor != null ? Math.round(factor * 100) / 100 : null,
|
|
39
|
+
decodedKB: Math.round(estDecodedBytes(record) / 1024),
|
|
40
|
+
wastedKB: Math.round(estWastedBytes(record) / 1024),
|
|
41
|
+
progressSeen: record.progressSeen === true,
|
|
42
|
+
bytesTotal: record.bytesTotal ?? null,
|
|
43
|
+
error: record.error ?? null,
|
|
44
|
+
errorCode: record.errorCode ?? null,
|
|
45
|
+
loadCount: record.loadCount,
|
|
46
|
+
overrideLabel: record.overrideLabel ?? null,
|
|
47
|
+
hasAltText: record.hasAltText ?? null,
|
|
48
|
+
layoutShifts: record.layoutShifts ?? 0,
|
|
49
|
+
ageMs: Date.now() - record.createdAt
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function requireRecord(params) {
|
|
53
|
+
const id = params?.id;
|
|
54
|
+
if (typeof id !== "number") throw new Error("Missing numeric `id` param");
|
|
55
|
+
const record = getRecord(id);
|
|
56
|
+
if (!record) {
|
|
57
|
+
throw new Error(`Image record ${id} not found (cleared or evicted) — re-run the list action for current ids.`);
|
|
58
|
+
}
|
|
59
|
+
return record;
|
|
60
|
+
}
|
|
61
|
+
function overview() {
|
|
62
|
+
const snapshot = getSnapshot();
|
|
63
|
+
return {
|
|
64
|
+
stats: computeStats(snapshot),
|
|
65
|
+
captureStatus: getCaptureStatus(),
|
|
66
|
+
globalModes: getGlobalModes(),
|
|
67
|
+
insights: computeInsights(snapshot),
|
|
68
|
+
records: [...snapshot].reverse() // newest first
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export const imagesSyncAdapter = {
|
|
72
|
+
version: 1,
|
|
73
|
+
getSnapshot: () => {
|
|
74
|
+
const {
|
|
75
|
+
records,
|
|
76
|
+
...rest
|
|
77
|
+
} = overview();
|
|
78
|
+
return {
|
|
79
|
+
...rest,
|
|
80
|
+
records: records.slice(0, 100).map(toWire)
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
subscribe: onChange => subscribe(onChange),
|
|
84
|
+
actions: {
|
|
85
|
+
/** List records (newest first). Params: { limit?, status? }. */
|
|
86
|
+
list: params => {
|
|
87
|
+
const p = params ?? {};
|
|
88
|
+
const limit = Math.min(Math.max(p.limit ?? 50, 1), 200);
|
|
89
|
+
const {
|
|
90
|
+
records,
|
|
91
|
+
...rest
|
|
92
|
+
} = overview();
|
|
93
|
+
const filtered = p.status ? records.filter(r => r.status === p.status) : records;
|
|
94
|
+
return {
|
|
95
|
+
...rest,
|
|
96
|
+
total: filtered.length,
|
|
97
|
+
records: filtered.slice(0, limit).map(toWire)
|
|
98
|
+
};
|
|
99
|
+
},
|
|
100
|
+
/** Full detail for one record. Params: { id }. */
|
|
101
|
+
getDetail: params => {
|
|
102
|
+
const record = requireRecord(params);
|
|
103
|
+
return {
|
|
104
|
+
...toWire(record),
|
|
105
|
+
errorHeaders: record.errorHeaders ?? null
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
/** Bypass-cache reload. Params: { id }. */
|
|
109
|
+
hardReload: params => hardReloadRecord(requireRecord(params)),
|
|
110
|
+
/** Re-encode at displayed size as WebP, return real byte savings. Params: { id }. */
|
|
111
|
+
proveSavings: params => proveSavings(requireRecord(params)),
|
|
112
|
+
/** Plain fresh load attempt. Params: { id }. */
|
|
113
|
+
retry: params => retryRecord(requireRecord(params)),
|
|
114
|
+
/** Evict the expo-image disk entry for this record. Params: { id }. */
|
|
115
|
+
evictDisk: async params => {
|
|
116
|
+
const record = requireRecord(params);
|
|
117
|
+
const evicted = await evictExpoDiskEntry(record);
|
|
118
|
+
return {
|
|
119
|
+
ok: evicted,
|
|
120
|
+
message: evicted ? "Disk cache entry deleted" : "No disk entry found (expo-image + expo-file-system required)"
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
/** Flash a red border on the on-screen image. Params: { id }. */
|
|
124
|
+
flash: params => {
|
|
125
|
+
flashRecord(requireRecord(params).id);
|
|
126
|
+
return {
|
|
127
|
+
ok: true,
|
|
128
|
+
message: "Flashing for 2.5s"
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
/**
|
|
132
|
+
* Apply a simulation override. Params: { id, kind, uri? } where kind is
|
|
133
|
+
* 'error' | 'hang' | 'blank' | 'url' ('url' requires uri).
|
|
134
|
+
*/
|
|
135
|
+
setOverride: params => {
|
|
136
|
+
const record = requireRecord(params);
|
|
137
|
+
const p = params;
|
|
138
|
+
const kinds = {
|
|
139
|
+
error: {
|
|
140
|
+
source: {
|
|
141
|
+
type: "error"
|
|
142
|
+
},
|
|
143
|
+
label: "Forced error"
|
|
144
|
+
},
|
|
145
|
+
hang: {
|
|
146
|
+
source: {
|
|
147
|
+
type: "hang"
|
|
148
|
+
},
|
|
149
|
+
label: "Forced loading"
|
|
150
|
+
},
|
|
151
|
+
blank: {
|
|
152
|
+
source: {
|
|
153
|
+
type: "blank"
|
|
154
|
+
},
|
|
155
|
+
label: "Blanked"
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
if (p.kind === "url") {
|
|
159
|
+
if (!p.uri) throw new Error("kind 'url' requires a `uri` param");
|
|
160
|
+
setOverride(record.id, {
|
|
161
|
+
source: {
|
|
162
|
+
type: "url",
|
|
163
|
+
uri: p.uri
|
|
164
|
+
},
|
|
165
|
+
label: "URL swapped"
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
ok: true,
|
|
169
|
+
message: `Source overridden to ${p.uri}`
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const entry = p.kind ? kinds[p.kind] : undefined;
|
|
173
|
+
if (!entry) throw new Error(`Unknown override kind: ${String(p.kind)}`);
|
|
174
|
+
if (!record.mounted) {
|
|
175
|
+
return {
|
|
176
|
+
ok: false,
|
|
177
|
+
message: "Instance unmounted — overrides need the image on screen"
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
setOverride(record.id, entry);
|
|
181
|
+
return {
|
|
182
|
+
ok: true,
|
|
183
|
+
message: `${entry.label} applied`
|
|
184
|
+
};
|
|
185
|
+
},
|
|
186
|
+
/** Remove a simulation override. Params: { id }. */
|
|
187
|
+
clearOverride: params => {
|
|
188
|
+
clearOverride(requireRecord(params).id);
|
|
189
|
+
return {
|
|
190
|
+
ok: true,
|
|
191
|
+
message: "Override removed — original source restored"
|
|
192
|
+
};
|
|
193
|
+
},
|
|
194
|
+
/**
|
|
195
|
+
* Mass action on every mounted image. Params: { kind } where kind is
|
|
196
|
+
* 'error' | 'loading' | 'blank' | 'reload' | 'flash' | 'restore'.
|
|
197
|
+
*/
|
|
198
|
+
massAction: async params => {
|
|
199
|
+
const kind = params?.kind;
|
|
200
|
+
switch (kind) {
|
|
201
|
+
case "error":
|
|
202
|
+
{
|
|
203
|
+
const n = setOverrideForAllMounted({
|
|
204
|
+
type: "error"
|
|
205
|
+
}, "Forced error");
|
|
206
|
+
return {
|
|
207
|
+
ok: n > 0,
|
|
208
|
+
message: `Forced error on ${n} images`
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
case "loading":
|
|
212
|
+
{
|
|
213
|
+
const n = setOverrideForAllMounted({
|
|
214
|
+
type: "hang"
|
|
215
|
+
}, "Forced loading");
|
|
216
|
+
return {
|
|
217
|
+
ok: n > 0,
|
|
218
|
+
message: `Forced loading on ${n} images`
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
case "blank":
|
|
222
|
+
{
|
|
223
|
+
const n = setOverrideForAllMounted({
|
|
224
|
+
type: "blank"
|
|
225
|
+
}, "Blanked");
|
|
226
|
+
return {
|
|
227
|
+
ok: n > 0,
|
|
228
|
+
message: `Blanked ${n} images`
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
case "reload":
|
|
232
|
+
return hardReloadAllMounted();
|
|
233
|
+
case "flash":
|
|
234
|
+
{
|
|
235
|
+
const n = flashAllMounted();
|
|
236
|
+
return {
|
|
237
|
+
ok: n > 0,
|
|
238
|
+
message: `Flashing ${n} images`
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
case "restore":
|
|
242
|
+
{
|
|
243
|
+
const n = clearAllOverrides();
|
|
244
|
+
return {
|
|
245
|
+
ok: true,
|
|
246
|
+
message: `Restored ${n} images`
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
default:
|
|
250
|
+
throw new Error(`Unknown mass kind: ${String(kind)}`);
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
/** Global network simulation. Params: { mode: 'normal'|'offline'|'cold' }. */
|
|
254
|
+
setNetworkMode: params => {
|
|
255
|
+
const mode = params?.mode;
|
|
256
|
+
if (mode !== "normal" && mode !== "offline" && mode !== "cold") {
|
|
257
|
+
throw new Error("mode must be 'normal' | 'offline' | 'cold'");
|
|
258
|
+
}
|
|
259
|
+
setNetworkMode(mode);
|
|
260
|
+
return {
|
|
261
|
+
ok: true,
|
|
262
|
+
modes: getGlobalModes()
|
|
263
|
+
};
|
|
264
|
+
},
|
|
265
|
+
/** Chrome-style disable-images. Params: { enabled: boolean }. */
|
|
266
|
+
setBlankImages: params => {
|
|
267
|
+
setBlankImages(params?.enabled === true);
|
|
268
|
+
return {
|
|
269
|
+
ok: true,
|
|
270
|
+
modes: getGlobalModes()
|
|
271
|
+
};
|
|
272
|
+
},
|
|
273
|
+
/** Clear the captured registry (keeps in-flight loads). */
|
|
274
|
+
clearRecords: () => {
|
|
275
|
+
clearRecords();
|
|
276
|
+
return {
|
|
277
|
+
ok: true,
|
|
278
|
+
message: "Registry cleared"
|
|
279
|
+
};
|
|
280
|
+
},
|
|
281
|
+
/** Clear expo-image caches. Params: { memory?, disk? } (default both). */
|
|
282
|
+
clearExpoCaches: async params => {
|
|
283
|
+
const p = params ?? {};
|
|
284
|
+
const doMemory = p.memory !== false;
|
|
285
|
+
const doDisk = p.disk !== false;
|
|
286
|
+
try {
|
|
287
|
+
const expo = require("expo-image");
|
|
288
|
+
const results = [];
|
|
289
|
+
if (doMemory) {
|
|
290
|
+
await expo.Image.clearMemoryCache();
|
|
291
|
+
results.push("memory");
|
|
292
|
+
}
|
|
293
|
+
if (doDisk) {
|
|
294
|
+
await expo.Image.clearDiskCache();
|
|
295
|
+
results.push("disk");
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
ok: true,
|
|
299
|
+
message: `Cleared expo-image ${results.join(" + ")} cache`
|
|
300
|
+
};
|
|
301
|
+
} catch {
|
|
302
|
+
return {
|
|
303
|
+
ok: false,
|
|
304
|
+
message: "expo-image not installed"
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
getCaptureStatus: () => getCaptureStatus()
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
//# sourceMappingURL=imagesSyncAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["evictExpoDiskEntry","hardReloadAllMounted","hardReloadRecord","retryRecord","getCaptureStatus","clearAllOverrides","clearOverride","flashAllMounted","flashRecord","getGlobalModes","setBlankImages","setNetworkMode","setOverride","setOverrideForAllMounted","proveSavings","computeInsights","clearRecords","computeStats","estDecodedBytes","estWastedBytes","getRecord","getSnapshot","neededPixels","oversizeFactor","subscribe","toWire","record","factor","id","lib","uri","kind","sourceKind","status","mounted","cache","cacheVerdict","cacheSource","cacheVerdictSource","ms","durationMs","Math","round","intrinsic","layout","width","height","neededPx","decodedKB","wastedKB","progressSeen","bytesTotal","error","errorCode","loadCount","overrideLabel","hasAltText","layoutShifts","ageMs","Date","now","createdAt","requireRecord","params","Error","overview","snapshot","stats","captureStatus","globalModes","insights","records","reverse","imagesSyncAdapter","version","rest","slice","map","onChange","actions","list","p","limit","min","max","filtered","filter","r","total","length","getDetail","errorHeaders","hardReload","retry","evictDisk","evicted","ok","message","flash","kinds","source","type","label","hang","blank","entry","undefined","String","massAction","n","mode","modes","enabled","clearExpoCaches","doMemory","memory","doDisk","disk","expo","require","results","Image","clearMemoryCache","push","clearDiskCache","join"],"sourceRoot":"../../../src","sources":["sync/imagesSyncAdapter.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-image actions: hard reload (bypass cache) and retry.
|
|
3
|
+
*
|
|
4
|
+
* RN core path: the decorator wrapper owns every mounted <Image>'s props, so a
|
|
5
|
+
* reload request re-renders the wrapper with a bumped `key` (native remount →
|
|
6
|
+
* fresh load cycle) and, for cache-busting, `source.cache: 'reload'` injected
|
|
7
|
+
* — VERIFIED supported on BOTH platforms (iOS NSURLRequest policy;
|
|
8
|
+
* Android ReactImageView.kt reads source."cache" → Fresco full-fetch). The
|
|
9
|
+
* override stays applied until the load settles, then reverts lazily on the
|
|
10
|
+
* app's next natural re-render (avoids an extra cache round-trip).
|
|
11
|
+
*
|
|
12
|
+
* expo-image path: the patched class instance exposes the public
|
|
13
|
+
* `reloadAsync()`. Cache-busting first evicts the disk entry (cache path +
|
|
14
|
+
* expo-file-system delete) and clears expo's memory cache (global — no
|
|
15
|
+
* per-entry memory eviction exists), so the reload is a true refetch that
|
|
16
|
+
* rewrites both cache tiers.
|
|
17
|
+
*/
|
|
18
|
+
import type { ImageRecord } from "../types";
|
|
19
|
+
export declare function subscribeActions(listener: () => void): () => void;
|
|
20
|
+
export declare function getReloadRequest(recordId: number | null): {
|
|
21
|
+
nonce: number;
|
|
22
|
+
bust: boolean;
|
|
23
|
+
} | undefined;
|
|
24
|
+
/** Reload nonce for a record (0 = never requested). Snapshot for the wrapper. */
|
|
25
|
+
export declare function getReloadNonce(recordId: number | null): number;
|
|
26
|
+
/**
|
|
27
|
+
* Mark a request consumed once its load settles (called from the tracker on
|
|
28
|
+
* load/error). Silent — the wrapper reverts the prop override on the app's
|
|
29
|
+
* next natural re-render instead of forcing an immediate one.
|
|
30
|
+
*/
|
|
31
|
+
export declare function settleReloadRequest(recordId: number): void;
|
|
32
|
+
export declare function dropActionState(recordId: number): void;
|
|
33
|
+
export declare function registerExpoInstance(recordId: number | null, instance: unknown): void;
|
|
34
|
+
/**
|
|
35
|
+
* Delete an expo-image disk-cache entry (JS-only: cache path + file delete).
|
|
36
|
+
* Returns true if an entry existed and was deleted.
|
|
37
|
+
*/
|
|
38
|
+
export declare function evictExpoDiskEntry(record: ImageRecord): Promise<boolean>;
|
|
39
|
+
export type ActionResult = {
|
|
40
|
+
ok: boolean;
|
|
41
|
+
message: string;
|
|
42
|
+
};
|
|
43
|
+
/** Fresh load attempt for a mounted image (no cache bypass). */
|
|
44
|
+
export declare function retryRecord(record: ImageRecord): Promise<ActionResult>;
|
|
45
|
+
/** Hard-reload every mounted image (mass cache-bust). Returns count started. */
|
|
46
|
+
export declare function hardReloadAllMounted(): Promise<ActionResult>;
|
|
47
|
+
/** Bypass-cache reload: refetches from network and rewrites the caches. */
|
|
48
|
+
export declare function hardReloadRecord(record: ImageRecord): Promise<ActionResult>;
|
|
49
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/capture/actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAM5C,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAIjE;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAG9C;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE9D;AAUD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAM1D;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAOtD;AAMD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGrF;AAyCD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAa9E;AAMD,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D,gEAAgE;AAChE,wBAAsB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAgB5E;AAED,gFAAgF;AAChF,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,YAAY,CAAC,CAWlE;AAED,2EAA2E;AAC3E,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAwBjF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* installImageCapture — idempotent entry point for the capture layer.
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT (timing): the RN-core decorator only takes effect if this runs
|
|
5
|
+
* before anything evaluates the `Image` module from 'react-native'. The
|
|
6
|
+
* recommended integration is `import "@buoy-gg/images/register"` as the FIRST
|
|
7
|
+
* import of the app entry file. The expo-image patch has no such constraint.
|
|
8
|
+
*
|
|
9
|
+
* Idempotency is keyed on the globalThis singleton, so even if this package
|
|
10
|
+
* gets evaluated as two module instances, capture installs exactly once.
|
|
11
|
+
*/
|
|
12
|
+
import type { CaptureStatus } from "../types";
|
|
13
|
+
export declare function installImageCapture(): void;
|
|
14
|
+
export declare function getCaptureStatus(): CaptureStatus;
|
|
15
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/capture/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,mBAAmB,IAAI,IAAI,CAM1C;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAUhD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* expo-image interception via class-prototype patch.
|
|
3
|
+
*
|
|
4
|
+
* expo-image's <Image> is a class component (React.PureComponent) whose
|
|
5
|
+
* render() reads `this.props`, so wrapping the prototype's render and swapping
|
|
6
|
+
* `this.props` for an instrumented copy for the duration of the original
|
|
7
|
+
* render is timing-immune (prototype methods are looked up dynamically — no
|
|
8
|
+
* import-order race like the RN core decorator). Props are restored in
|
|
9
|
+
* `finally`, so PureComponent's shouldComponentUpdate still compares the
|
|
10
|
+
* app's real props.
|
|
11
|
+
*
|
|
12
|
+
* Double-patch safety: install flags live on the globalThis singleton AND a
|
|
13
|
+
* marker is stamped on the prototype itself, so even two module instances of
|
|
14
|
+
* this package can't wrap render() twice.
|
|
15
|
+
*
|
|
16
|
+
* expo-image is an optional peer: if it isn't installed, this is a no-op.
|
|
17
|
+
*/
|
|
18
|
+
export declare function installExpoImageInterceptor(): void;
|
|
19
|
+
export declare function expoCaptureStatus(): {
|
|
20
|
+
available: boolean;
|
|
21
|
+
patched: boolean;
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=installExpoImage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installExpoImage.d.ts","sourceRoot":"","sources":["../../../src/capture/installExpoImage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAyBH,wBAAgB,2BAA2B,IAAI,IAAI,CAoElD;AAED,wBAAgB,iBAAiB,IAAI;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAG5E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RN core <Image> interception via the official injection hook.
|
|
3
|
+
*
|
|
4
|
+
* `unstable_setImageComponentDecorator` wraps EVERY RN <Image> app-wide — but
|
|
5
|
+
* the decorator is latched ONCE, at Image module evaluation
|
|
6
|
+
* (`Image.ios.js` / `Image.android.js` read it at module scope). So install
|
|
7
|
+
* order matters: this must run before anything touches `Image` from
|
|
8
|
+
* 'react-native' — hence the `@buoy-gg/images/register` first-import.
|
|
9
|
+
*
|
|
10
|
+
* Detection strategy: the decorator sets `decoratorInvoked` when RN's Image
|
|
11
|
+
* module applies it. `unstable_registerImageAttachedCallback` is a live Set
|
|
12
|
+
* (never latched), so image mounts are always visible — if mounts happen but
|
|
13
|
+
* the decorator never ran, we were too late and CaptureStatus reports it.
|
|
14
|
+
*
|
|
15
|
+
* All flags live on the globalThis singleton (../state.ts) so a second module
|
|
16
|
+
* instance of this package neither re-installs nor reports a stale status.
|
|
17
|
+
*/
|
|
18
|
+
export declare function installRnImageInterceptor(): void;
|
|
19
|
+
export declare function rnCaptureStatus(): {
|
|
20
|
+
decoratorRegistered: boolean;
|
|
21
|
+
decoratorActive: boolean;
|
|
22
|
+
tooLate: boolean;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=installRnImage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installRnImage.d.ts","sourceRoot":"","sources":["../../../src/capture/installRnImage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA6DH,wBAAgB,yBAAyB,IAAI,IAAI,CAyChD;AAED,wBAAgB,eAAe,IAAI;IACjC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB,CAQA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simulation overrides — the "we own the props" tier of actions.
|
|
3
|
+
*
|
|
4
|
+
* Because the RN decorator and the expo-image render patch control every
|
|
5
|
+
* mounted image's props, anything the component accepts is a simulation:
|
|
6
|
+
* forced errors (instant, offline-safe file:// source), forced loading
|
|
7
|
+
* (blackhole-IP source that never resolves), URL swaps, blanking, style
|
|
8
|
+
* merges (locate-flash border), and app-wide modes (offline images /
|
|
9
|
+
* cold-start / blank images).
|
|
10
|
+
*
|
|
11
|
+
* Re-render plumbing: every mutation bumps a per-record or global version.
|
|
12
|
+
* RN wrappers subscribe via useSyncExternalStore with a per-record snapshot
|
|
13
|
+
* (only the touched image re-renders); expo class instances are re-rendered
|
|
14
|
+
* directly via forceUpdate() from the per-record instance registry.
|
|
15
|
+
*/
|
|
16
|
+
import type { ImageLib } from "../types";
|
|
17
|
+
export type OverrideSource = {
|
|
18
|
+
type: "url";
|
|
19
|
+
uri: string;
|
|
20
|
+
}
|
|
21
|
+
/** Nonexistent file:// — native fires onError immediately, no network needed. */
|
|
22
|
+
| {
|
|
23
|
+
type: "error";
|
|
24
|
+
}
|
|
25
|
+
/** Blackhole IP — the request hangs, onLoad never fires (loading forever). */
|
|
26
|
+
| {
|
|
27
|
+
type: "hang";
|
|
28
|
+
}
|
|
29
|
+
/** No source at all (expo keeps showing its placeholder). */
|
|
30
|
+
| {
|
|
31
|
+
type: "blank";
|
|
32
|
+
};
|
|
33
|
+
export interface ImageOverride {
|
|
34
|
+
source?: OverrideSource;
|
|
35
|
+
/** Merged over the app's style (size experiments etc.). */
|
|
36
|
+
style?: Record<string, unknown>;
|
|
37
|
+
/** Extra props merged last (expo contentFit, priority, cachePolicy…). */
|
|
38
|
+
extraProps?: Record<string, unknown>;
|
|
39
|
+
/** Shown as the record's override badge, e.g. "Forced error". */
|
|
40
|
+
label: string;
|
|
41
|
+
}
|
|
42
|
+
export type NetworkMode = "normal" | "offline" | "cold";
|
|
43
|
+
/** Bump one record's render version (re-renders just that image). */
|
|
44
|
+
export declare function touchRecord(recordId: number): void;
|
|
45
|
+
/** Bump the global render version (re-renders every wrapped image). */
|
|
46
|
+
export declare function touchGlobal(): void;
|
|
47
|
+
/** Snapshot for the RN wrapper's useSyncExternalStore. */
|
|
48
|
+
export declare function getRenderVersion(recordId: number | null): number;
|
|
49
|
+
export declare function setOverride(recordId: number, override: ImageOverride): void;
|
|
50
|
+
export declare function clearOverride(recordId: number): void;
|
|
51
|
+
export declare function getOverride(recordId: number | null): ImageOverride | undefined;
|
|
52
|
+
/** Apply one override to every mounted record. Returns how many were hit. */
|
|
53
|
+
export declare function setOverrideForAllMounted(source: OverrideSource, label: string): number;
|
|
54
|
+
/** Remove every active override. Returns how many were cleared. */
|
|
55
|
+
export declare function clearAllOverrides(): number;
|
|
56
|
+
/** Flash every mounted image (locate everything the tool tracks). */
|
|
57
|
+
export declare function flashAllMounted(durationMs?: number): number;
|
|
58
|
+
/** Flash a border on the on-screen image so it can be located visually. */
|
|
59
|
+
export declare function flashRecord(recordId: number, durationMs?: number): void;
|
|
60
|
+
/**
|
|
61
|
+
* offline — every NETWORK image load fails immediately (both libs, cache or
|
|
62
|
+
* not); bundled/local assets still load, like a real offline device showing
|
|
63
|
+
* shipped images. Blunt on purpose: toggle + reload = images visibly gone.
|
|
64
|
+
* (The subtler `only-if-cached` variant was correct-but-confusing, and its
|
|
65
|
+
* uncached requests HANG on iOS instead of erroring — bad for QA.)
|
|
66
|
+
* cold — every image bypasses caches (RN `cache:'reload'`, expo
|
|
67
|
+
* `cachePolicy:'none'`): first-launch behavior without clearing anything.
|
|
68
|
+
*/
|
|
69
|
+
export declare function setNetworkMode(mode: NetworkMode): void;
|
|
70
|
+
/** Chrome-style "disable images": render every image without a source. */
|
|
71
|
+
export declare function setBlankImages(enabled: boolean): void;
|
|
72
|
+
export declare function getGlobalModes(): {
|
|
73
|
+
network: NetworkMode;
|
|
74
|
+
blank: boolean;
|
|
75
|
+
};
|
|
76
|
+
/** Inject a `cache` policy into an RN source (object or array shape). */
|
|
77
|
+
export declare function patchSourceCache(source: unknown, cache: string): unknown;
|
|
78
|
+
/**
|
|
79
|
+
* Merge global modes + per-record override + locate-flash into an
|
|
80
|
+
* already-copied props object. Mutates and returns `out`.
|
|
81
|
+
*/
|
|
82
|
+
export declare function applyOverrides(out: Record<string, unknown>, recordId: number | null, lib: ImageLib): Record<string, unknown>;
|
|
83
|
+
//# sourceMappingURL=overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../../src/capture/overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAMzC,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE;AAC9B,iFAAiF;GAC/E;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE;AACnB,8EAA8E;GAC5E;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,6DAA6D;GAC3D;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtB,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;CACf;AAgBD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAwBxD,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKlD;AAED,uEAAuE;AACvE,wBAAgB,WAAW,IAAI,IAAI,CAKlC;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAIhE;AAMD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAI3E;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIpD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,GAAG,SAAS,CAG9E;AAMD,6EAA6E;AAC7E,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQtF;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,IAAI,MAAM,CAI1C;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,UAAU,SAAO,GAAG,MAAM,CAQzD;AAED,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,SAAO,GAAG,IAAI,CAQrE;AAMD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAGtD;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGrD;AAED,wBAAgB,cAAc,IAAI;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAEzE;AAMD,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAYxE;AAgBD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,GAAG,EAAE,QAAQ,GACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA2CzB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Savings prover — Squoosh-style, on device.
|
|
3
|
+
*
|
|
4
|
+
* Instead of estimating what an oversized source wastes, PROVE it: re-encode
|
|
5
|
+
* the image at the displayed size (× pixel ratio) as WebP via
|
|
6
|
+
* expo-image-manipulator (verified: chainable resize → saveAsync WebP on BOTH
|
|
7
|
+
* platforms, available in Expo Go), stat the output file, and report real
|
|
8
|
+
* bytes vs the original. The optimized file:// URI can then be A/B'd in place
|
|
9
|
+
* through the existing swap-url override.
|
|
10
|
+
*
|
|
11
|
+
* Original size is resolved in tiers: observed download bytes (onProgress
|
|
12
|
+
* total) → expo disk-cache file size → HEAD Content-Length.
|
|
13
|
+
*/
|
|
14
|
+
import type { ImageRecord } from "../types";
|
|
15
|
+
export interface SavingsResult {
|
|
16
|
+
ok: boolean;
|
|
17
|
+
message: string;
|
|
18
|
+
/** Real encoded bytes of the original (when determinable). */
|
|
19
|
+
originalBytes?: number;
|
|
20
|
+
originalBytesSource?: "download" | "cacheFile" | "head";
|
|
21
|
+
/** Real encoded bytes of the optimized WebP on disk. */
|
|
22
|
+
optimizedBytes?: number;
|
|
23
|
+
/** file:// URI of the optimized image (feed to swap-url to preview). */
|
|
24
|
+
optimizedUri?: string;
|
|
25
|
+
optimizedDims?: {
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
};
|
|
29
|
+
savedBytes?: number;
|
|
30
|
+
savedPct?: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Re-encode `record`'s source at its displayed size as WebP and measure it.
|
|
34
|
+
* Requires expo-image-manipulator (graceful message when absent).
|
|
35
|
+
*/
|
|
36
|
+
export declare function proveSavings(record: ImageRecord): Promise<SavingsResult>;
|
|
37
|
+
//# sourceMappingURL=savings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"savings.d.ts","sourceRoot":"","sources":["../../../src/capture/savings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,MAAM,CAAC;IACxD,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAuED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAuF9E"}
|