@buoy-gg/assets 7.0.16

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 (179) hide show
  1. package/LICENSE +58 -0
  2. package/README.md +55 -0
  3. package/lib/commonjs/capture/expo.js +46 -0
  4. package/lib/commonjs/capture/expo.js.map +1 -0
  5. package/lib/commonjs/capture/install.js +78 -0
  6. package/lib/commonjs/capture/install.js.map +1 -0
  7. package/lib/commonjs/capture/measure.js +186 -0
  8. package/lib/commonjs/capture/measure.js.map +1 -0
  9. package/lib/commonjs/capture/metroGraph.js +148 -0
  10. package/lib/commonjs/capture/metroGraph.js.map +1 -0
  11. package/lib/commonjs/capture/registry.js +124 -0
  12. package/lib/commonjs/capture/registry.js.map +1 -0
  13. package/lib/commonjs/components/AssetDetail.js +205 -0
  14. package/lib/commonjs/components/AssetDetail.js.map +1 -0
  15. package/lib/commonjs/components/AssetRow.js +246 -0
  16. package/lib/commonjs/components/AssetRow.js.map +1 -0
  17. package/lib/commonjs/components/AssetsFilterBar.js +92 -0
  18. package/lib/commonjs/components/AssetsFilterBar.js.map +1 -0
  19. package/lib/commonjs/components/AssetsHeader.js +66 -0
  20. package/lib/commonjs/components/AssetsHeader.js.map +1 -0
  21. package/lib/commonjs/components/AssetsIcon.js +19 -0
  22. package/lib/commonjs/components/AssetsIcon.js.map +1 -0
  23. package/lib/commonjs/components/AssetsListControls.js +94 -0
  24. package/lib/commonjs/components/AssetsListControls.js.map +1 -0
  25. package/lib/commonjs/components/AssetsModal.js +338 -0
  26. package/lib/commonjs/components/AssetsModal.js.map +1 -0
  27. package/lib/commonjs/components/BaselineBar.js +110 -0
  28. package/lib/commonjs/components/BaselineBar.js.map +1 -0
  29. package/lib/commonjs/export.js +62 -0
  30. package/lib/commonjs/export.js.map +1 -0
  31. package/lib/commonjs/format.js +59 -0
  32. package/lib/commonjs/format.js.map +1 -0
  33. package/lib/commonjs/hooks/useAssetRecords.js +22 -0
  34. package/lib/commonjs/hooks/useAssetRecords.js.map +1 -0
  35. package/lib/commonjs/index.js +260 -0
  36. package/lib/commonjs/index.js.map +1 -0
  37. package/lib/commonjs/package.json +1 -0
  38. package/lib/commonjs/preset.js +45 -0
  39. package/lib/commonjs/preset.js.map +1 -0
  40. package/lib/commonjs/remote.js +65 -0
  41. package/lib/commonjs/remote.js.map +1 -0
  42. package/lib/commonjs/state.js +51 -0
  43. package/lib/commonjs/state.js.map +1 -0
  44. package/lib/commonjs/store/assetStore.js +234 -0
  45. package/lib/commonjs/store/assetStore.js.map +1 -0
  46. package/lib/commonjs/store/baseline.js +165 -0
  47. package/lib/commonjs/store/baseline.js.map +1 -0
  48. package/lib/commonjs/store/insights.js +129 -0
  49. package/lib/commonjs/store/insights.js.map +1 -0
  50. package/lib/commonjs/sync/assetsSyncAdapter.js +157 -0
  51. package/lib/commonjs/sync/assetsSyncAdapter.js.map +1 -0
  52. package/lib/commonjs/types.js +2 -0
  53. package/lib/commonjs/types.js.map +1 -0
  54. package/lib/module/capture/expo.js +41 -0
  55. package/lib/module/capture/expo.js.map +1 -0
  56. package/lib/module/capture/install.js +72 -0
  57. package/lib/module/capture/install.js.map +1 -0
  58. package/lib/module/capture/measure.js +179 -0
  59. package/lib/module/capture/measure.js.map +1 -0
  60. package/lib/module/capture/metroGraph.js +141 -0
  61. package/lib/module/capture/metroGraph.js.map +1 -0
  62. package/lib/module/capture/registry.js +117 -0
  63. package/lib/module/capture/registry.js.map +1 -0
  64. package/lib/module/components/AssetDetail.js +201 -0
  65. package/lib/module/components/AssetDetail.js.map +1 -0
  66. package/lib/module/components/AssetRow.js +242 -0
  67. package/lib/module/components/AssetRow.js.map +1 -0
  68. package/lib/module/components/AssetsFilterBar.js +88 -0
  69. package/lib/module/components/AssetsFilterBar.js.map +1 -0
  70. package/lib/module/components/AssetsHeader.js +62 -0
  71. package/lib/module/components/AssetsHeader.js.map +1 -0
  72. package/lib/module/components/AssetsIcon.js +12 -0
  73. package/lib/module/components/AssetsIcon.js.map +1 -0
  74. package/lib/module/components/AssetsListControls.js +90 -0
  75. package/lib/module/components/AssetsListControls.js.map +1 -0
  76. package/lib/module/components/AssetsModal.js +333 -0
  77. package/lib/module/components/AssetsModal.js.map +1 -0
  78. package/lib/module/components/BaselineBar.js +106 -0
  79. package/lib/module/components/BaselineBar.js.map +1 -0
  80. package/lib/module/export.js +57 -0
  81. package/lib/module/export.js.map +1 -0
  82. package/lib/module/format.js +51 -0
  83. package/lib/module/format.js.map +1 -0
  84. package/lib/module/hooks/useAssetRecords.js +18 -0
  85. package/lib/module/hooks/useAssetRecords.js.map +1 -0
  86. package/lib/module/index.js +59 -0
  87. package/lib/module/index.js.map +1 -0
  88. package/lib/module/preset.js +40 -0
  89. package/lib/module/preset.js.map +1 -0
  90. package/lib/module/remote.js +58 -0
  91. package/lib/module/remote.js.map +1 -0
  92. package/lib/module/state.js +47 -0
  93. package/lib/module/state.js.map +1 -0
  94. package/lib/module/store/assetStore.js +219 -0
  95. package/lib/module/store/assetStore.js.map +1 -0
  96. package/lib/module/store/baseline.js +157 -0
  97. package/lib/module/store/baseline.js.map +1 -0
  98. package/lib/module/store/insights.js +125 -0
  99. package/lib/module/store/insights.js.map +1 -0
  100. package/lib/module/sync/assetsSyncAdapter.js +153 -0
  101. package/lib/module/sync/assetsSyncAdapter.js.map +1 -0
  102. package/lib/module/types.js +2 -0
  103. package/lib/module/types.js.map +1 -0
  104. package/lib/typescript/capture/expo.d.ts +18 -0
  105. package/lib/typescript/capture/expo.d.ts.map +1 -0
  106. package/lib/typescript/capture/install.d.ts +17 -0
  107. package/lib/typescript/capture/install.d.ts.map +1 -0
  108. package/lib/typescript/capture/measure.d.ts +38 -0
  109. package/lib/typescript/capture/measure.d.ts.map +1 -0
  110. package/lib/typescript/capture/metroGraph.d.ts +33 -0
  111. package/lib/typescript/capture/metroGraph.d.ts.map +1 -0
  112. package/lib/typescript/capture/registry.d.ts +45 -0
  113. package/lib/typescript/capture/registry.d.ts.map +1 -0
  114. package/lib/typescript/components/AssetDetail.d.ts +17 -0
  115. package/lib/typescript/components/AssetDetail.d.ts.map +1 -0
  116. package/lib/typescript/components/AssetRow.d.ts +32 -0
  117. package/lib/typescript/components/AssetRow.d.ts.map +1 -0
  118. package/lib/typescript/components/AssetsFilterBar.d.ts +16 -0
  119. package/lib/typescript/components/AssetsFilterBar.d.ts.map +1 -0
  120. package/lib/typescript/components/AssetsHeader.d.ts +22 -0
  121. package/lib/typescript/components/AssetsHeader.d.ts.map +1 -0
  122. package/lib/typescript/components/AssetsIcon.d.ts +9 -0
  123. package/lib/typescript/components/AssetsIcon.d.ts.map +1 -0
  124. package/lib/typescript/components/AssetsListControls.d.ts +18 -0
  125. package/lib/typescript/components/AssetsListControls.d.ts.map +1 -0
  126. package/lib/typescript/components/AssetsModal.d.ts +24 -0
  127. package/lib/typescript/components/AssetsModal.d.ts.map +1 -0
  128. package/lib/typescript/components/BaselineBar.d.ts +13 -0
  129. package/lib/typescript/components/BaselineBar.d.ts.map +1 -0
  130. package/lib/typescript/export.d.ts +8 -0
  131. package/lib/typescript/export.d.ts.map +1 -0
  132. package/lib/typescript/format.d.ts +13 -0
  133. package/lib/typescript/format.d.ts.map +1 -0
  134. package/lib/typescript/hooks/useAssetRecords.d.ts +11 -0
  135. package/lib/typescript/hooks/useAssetRecords.d.ts.map +1 -0
  136. package/lib/typescript/index.d.ts +26 -0
  137. package/lib/typescript/index.d.ts.map +1 -0
  138. package/lib/typescript/preset.d.ts +38 -0
  139. package/lib/typescript/preset.d.ts.map +1 -0
  140. package/lib/typescript/remote.d.ts +17 -0
  141. package/lib/typescript/remote.d.ts.map +1 -0
  142. package/lib/typescript/state.d.ts +41 -0
  143. package/lib/typescript/state.d.ts.map +1 -0
  144. package/lib/typescript/store/assetStore.d.ts +51 -0
  145. package/lib/typescript/store/assetStore.d.ts.map +1 -0
  146. package/lib/typescript/store/baseline.d.ts +22 -0
  147. package/lib/typescript/store/baseline.d.ts.map +1 -0
  148. package/lib/typescript/store/insights.d.ts +7 -0
  149. package/lib/typescript/store/insights.d.ts.map +1 -0
  150. package/lib/typescript/sync/assetsSyncAdapter.d.ts +83 -0
  151. package/lib/typescript/sync/assetsSyncAdapter.d.ts.map +1 -0
  152. package/lib/typescript/types.d.ts +162 -0
  153. package/lib/typescript/types.d.ts.map +1 -0
  154. package/package.json +77 -0
  155. package/src/capture/expo.ts +45 -0
  156. package/src/capture/install.ts +73 -0
  157. package/src/capture/measure.ts +167 -0
  158. package/src/capture/metroGraph.ts +146 -0
  159. package/src/capture/registry.ts +134 -0
  160. package/src/components/AssetDetail.tsx +207 -0
  161. package/src/components/AssetRow.tsx +243 -0
  162. package/src/components/AssetsFilterBar.tsx +99 -0
  163. package/src/components/AssetsHeader.tsx +75 -0
  164. package/src/components/AssetsIcon.tsx +9 -0
  165. package/src/components/AssetsListControls.tsx +101 -0
  166. package/src/components/AssetsModal.tsx +368 -0
  167. package/src/components/BaselineBar.tsx +98 -0
  168. package/src/export.ts +108 -0
  169. package/src/format.ts +53 -0
  170. package/src/hooks/useAssetRecords.ts +26 -0
  171. package/src/index.tsx +87 -0
  172. package/src/preset.tsx +35 -0
  173. package/src/remote.ts +65 -0
  174. package/src/state.ts +84 -0
  175. package/src/store/assetStore.ts +209 -0
  176. package/src/store/baseline.ts +152 -0
  177. package/src/store/insights.ts +145 -0
  178. package/src/sync/assetsSyncAdapter.ts +151 -0
  179. package/src/types.ts +160 -0
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Derived insights over the asset inventory — the Lighthouse/Emerge-style
5
+ * audit findings, each pointing at concrete record ids.
6
+ */
7
+
8
+ import { assetsState } from "../state";
9
+ import { estDecodedBytes } from "./assetStore";
10
+ /** png/jpeg at or above this measured size are flagged as WebP candidates. */
11
+ const WEBP_CANDIDATE_BYTES = 50 * 1024;
12
+ /** GIFs at or above this measured size decode into serious frame memory. */
13
+ const HEAVY_GIF_BYTES = 100 * 1024;
14
+ /** Fonts at or above this are usually unsubset icon fonts. */
15
+ const HEAVY_FONT_BYTES = 150 * 1024;
16
+ /** Flag images decoding to more pixels than this many screenfuls. */
17
+ const OVER_DECODE_SCREENS = 2;
18
+ /** A higher scale variant this much smaller than a lower one = bad export. */
19
+ const SCALE_ANOMALY_RATIO = 0.9;
20
+ /**
21
+ * Anomaly checks only apply when the smaller variant is at least this big —
22
+ * for tiny icons PNG overhead dominates and byte ordering is pure noise.
23
+ */
24
+ const SCALE_ANOMALY_MIN_BYTES = 4 * 1024;
25
+ function effectivePixelRatio() {
26
+ const mirror = assetsState().mirrorPixelRatio;
27
+ if (mirror != null) return mirror;
28
+ try {
29
+ return require("react-native").PixelRatio.get();
30
+ } catch {
31
+ return 2;
32
+ }
33
+ }
34
+
35
+ /** Physical pixels of the entire screen (fallback ≈ a 6.1" phone). */
36
+ function screenPixels() {
37
+ try {
38
+ const {
39
+ Dimensions,
40
+ PixelRatio
41
+ } = require("react-native");
42
+ const screen = Dimensions.get("screen");
43
+ const ratio = PixelRatio.get();
44
+ return screen.width * ratio * screen.height * ratio;
45
+ } catch {
46
+ return 1170 * 2532;
47
+ }
48
+ }
49
+
50
+ /** True when the measured per-scale sizes contradict the scales (bad export). */
51
+ function hasScaleAnomaly(record) {
52
+ const sizes = record.sizesByScale;
53
+ if (!sizes) return false;
54
+ const ordered = Object.entries(sizes).map(([scale, bytes]) => ({
55
+ scale: Number(scale),
56
+ bytes
57
+ })).filter(e => Number.isFinite(e.scale) && e.bytes > 0).sort((a, b) => a.scale - b.scale);
58
+ for (let i = 1; i < ordered.length; i++) {
59
+ if (ordered[i - 1].bytes >= SCALE_ANOMALY_MIN_BYTES && ordered[i].bytes < ordered[i - 1].bytes * SCALE_ANOMALY_RATIO) {
60
+ return true;
61
+ }
62
+ }
63
+ return false;
64
+ }
65
+ export function computeInsights(list) {
66
+ const deviceScale = effectivePixelRatio();
67
+ const byHash = new Map();
68
+ for (const r of list) {
69
+ if (!r.hash) continue;
70
+ const group = byHash.get(r.hash);
71
+ if (group) group.push(r);else byHash.set(r.hash, [r]);
72
+ }
73
+ const duplicates = [];
74
+ for (const [hash, group] of byHash) {
75
+ if (group.length < 2) continue;
76
+ const measured = group.find(r => r.sizeBytes != null);
77
+ duplicates.push({
78
+ hash,
79
+ ids: group.map(r => r.id),
80
+ wastedBytes: measured?.sizeBytes != null ? measured.sizeBytes * (group.length - 1) : null
81
+ });
82
+ }
83
+ const screenPx = screenPixels();
84
+ const scaleGaps = [];
85
+ const webpCandidates = [];
86
+ const neverLoaded = [];
87
+ const overDecode = [];
88
+ const heavyGifs = [];
89
+ const heavyFonts = [];
90
+ const scaleAnomalies = [];
91
+ for (const r of list) {
92
+ if (!r.loaded) neverLoaded.push(r.id);
93
+ // Only multi-scale assets missing the device scale are flagged — the
94
+ // author clearly manages variants and missed one. Single-@1x images are
95
+ // the overwhelmingly common case and flagging them all is pure noise.
96
+ if (r.kind === "image" && r.scales.length > 1 && !r.scales.some(s => s >= deviceScale)) {
97
+ scaleGaps.push(r.id);
98
+ }
99
+ if ((r.type === "png" || r.type === "jpg" || r.type === "jpeg") && r.sizeBytes != null && r.sizeBytes >= WEBP_CANDIDATE_BYTES) {
100
+ webpCandidates.push(r.id);
101
+ }
102
+ // estDecodedBytes = pixels × 4, so pixels = bytes / 4.
103
+ if (r.kind === "image" && estDecodedBytes(r) / 4 > screenPx * OVER_DECODE_SCREENS) {
104
+ overDecode.push(r.id);
105
+ }
106
+ if (r.type === "gif" && (r.sizeBytes ?? 0) >= HEAVY_GIF_BYTES) {
107
+ heavyGifs.push(r.id);
108
+ }
109
+ if (r.kind === "font" && (r.sizeBytes ?? 0) >= HEAVY_FONT_BYTES) {
110
+ heavyFonts.push(r.id);
111
+ }
112
+ if (hasScaleAnomaly(r)) scaleAnomalies.push(r.id);
113
+ }
114
+ return {
115
+ duplicates,
116
+ scaleGaps,
117
+ webpCandidates,
118
+ neverLoaded,
119
+ overDecode,
120
+ heavyGifs,
121
+ heavyFonts,
122
+ scaleAnomalies
123
+ };
124
+ }
125
+ //# sourceMappingURL=insights.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["assetsState","estDecodedBytes","WEBP_CANDIDATE_BYTES","HEAVY_GIF_BYTES","HEAVY_FONT_BYTES","OVER_DECODE_SCREENS","SCALE_ANOMALY_RATIO","SCALE_ANOMALY_MIN_BYTES","effectivePixelRatio","mirror","mirrorPixelRatio","require","PixelRatio","get","screenPixels","Dimensions","screen","ratio","width","height","hasScaleAnomaly","record","sizes","sizesByScale","ordered","Object","entries","map","scale","bytes","Number","filter","e","isFinite","sort","a","b","i","length","computeInsights","list","deviceScale","byHash","Map","r","hash","group","push","set","duplicates","measured","find","sizeBytes","ids","id","wastedBytes","screenPx","scaleGaps","webpCandidates","neverLoaded","overDecode","heavyGifs","heavyFonts","scaleAnomalies","loaded","kind","scales","some","s","type"],"sourceRoot":"../../../src","sources":["store/insights.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Sync adapter for the Assets 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 images).
7
+ * Exposes the asset inventory to the desktop dashboard and the MCP server.
8
+ */
9
+
10
+ import { getScanStatus, rescan } from "../capture/install";
11
+ import { measureSizes } from "../capture/measure";
12
+ import { clearRecords, computeStats, estDecodedBytes, getRecord, getSnapshot, subscribe } from "../store/assetStore";
13
+ import { clearBaseline, getDiff, saveBaseline } from "../store/baseline";
14
+ import { computeInsights } from "../store/insights";
15
+ const KINDS = ["image", "font", "video", "audio", "data", "other"];
16
+ function toWire(record) {
17
+ return {
18
+ id: record.id,
19
+ key: record.key,
20
+ registryId: record.registryId ?? null,
21
+ name: record.name,
22
+ type: record.type,
23
+ kind: record.kind,
24
+ hash: record.hash ?? null,
25
+ location: record.httpServerLocation ?? null,
26
+ width: record.width ?? null,
27
+ height: record.height ?? null,
28
+ scales: record.scales,
29
+ uri: record.resolvedUri ?? null,
30
+ loaded: record.loaded,
31
+ sizeBytes: record.sizeSource === "measured" ? record.sizeBytes ?? null : estDecodedBytes(record) || null,
32
+ sizeSource: record.sizeSource ?? null
33
+ };
34
+ }
35
+ function requireRecord(params) {
36
+ const id = params?.id;
37
+ if (typeof id !== "number") throw new Error("Missing numeric `id` param");
38
+ const record = getRecord(id);
39
+ if (!record) {
40
+ throw new Error(`Asset record ${id} not found — re-run the list action for current ids.`);
41
+ }
42
+ return record;
43
+ }
44
+
45
+ /** Largest-first is the useful default for an inventory. */
46
+ function bySizeDesc(a, b) {
47
+ return (b.sizeBytes ?? estDecodedBytes(b)) - (a.sizeBytes ?? estDecodedBytes(a));
48
+ }
49
+ function overview() {
50
+ const snapshot = getSnapshot();
51
+ return {
52
+ stats: computeStats(snapshot),
53
+ scanStatus: getScanStatus(),
54
+ insights: computeInsights(snapshot),
55
+ diff: getDiff(),
56
+ records: [...snapshot].sort(bySizeDesc)
57
+ };
58
+ }
59
+ export const assetsSyncAdapter = {
60
+ version: 1,
61
+ getSnapshot: () => {
62
+ const {
63
+ records,
64
+ ...rest
65
+ } = overview();
66
+ return {
67
+ ...rest,
68
+ records: records.slice(0, 200).map(toWire)
69
+ };
70
+ },
71
+ subscribe: onChange => subscribe(onChange),
72
+ actions: {
73
+ /** List assets, largest first. Params: { limit?, kind?, loadedOnly? }. */
74
+ list: params => {
75
+ const p = params ?? {};
76
+ const limit = Math.min(Math.max(p.limit ?? 50, 1), 500);
77
+ const {
78
+ records,
79
+ ...rest
80
+ } = overview();
81
+ let filtered = records;
82
+ if (p.kind) {
83
+ if (!KINDS.includes(p.kind)) {
84
+ throw new Error(`kind must be one of: ${KINDS.join(", ")}`);
85
+ }
86
+ filtered = filtered.filter(r => r.kind === p.kind);
87
+ }
88
+ if (p.loadedOnly) filtered = filtered.filter(r => r.loaded);
89
+ return {
90
+ ...rest,
91
+ total: filtered.length,
92
+ records: filtered.slice(0, limit).map(toWire)
93
+ };
94
+ },
95
+ /** Full detail for one asset. Params: { id }. */
96
+ getDetail: params => {
97
+ const record = requireRecord(params);
98
+ return {
99
+ ...toWire(record),
100
+ origin: record.origin,
101
+ fileSystemLocation: record.fileSystemLocation ?? null,
102
+ files: record.files ?? null,
103
+ sizesByScale: record.sizesByScale ?? null,
104
+ estDecodedBytes: estDecodedBytes(record) || null
105
+ };
106
+ },
107
+ /** Re-walk the registry, merge the Metro graph, refresh fonts, measure sizes. */
108
+ rescan: async () => {
109
+ const status = await rescan();
110
+ return {
111
+ ok: true,
112
+ scanStatus: status
113
+ };
114
+ },
115
+ /** (Re-)measure byte sizes from the dev server. */
116
+ measureSizes: async () => {
117
+ const result = await measureSizes();
118
+ return {
119
+ ok: result.measured > 0,
120
+ ...result
121
+ };
122
+ },
123
+ /** Persist the current inventory as the comparison baseline. */
124
+ saveBaseline: async () => {
125
+ const baseline = await saveBaseline();
126
+ return {
127
+ ok: true,
128
+ savedAt: baseline.savedAt,
129
+ assets: Object.keys(baseline.entries).length
130
+ };
131
+ },
132
+ /** Drop the saved baseline. */
133
+ clearBaseline: async () => {
134
+ await clearBaseline();
135
+ return {
136
+ ok: true,
137
+ message: "Baseline cleared"
138
+ };
139
+ },
140
+ /** Change vs the saved baseline (null when no baseline exists). */
141
+ getDiff: () => getDiff(),
142
+ /** Wipe the store (next rescan rebuilds it). */
143
+ clearRecords: () => {
144
+ clearRecords();
145
+ return {
146
+ ok: true,
147
+ message: "Inventory cleared — rescan to rebuild"
148
+ };
149
+ },
150
+ getScanStatus: () => getScanStatus()
151
+ }
152
+ };
153
+ //# sourceMappingURL=assetsSyncAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getScanStatus","rescan","measureSizes","clearRecords","computeStats","estDecodedBytes","getRecord","getSnapshot","subscribe","clearBaseline","getDiff","saveBaseline","computeInsights","KINDS","toWire","record","id","key","registryId","name","type","kind","hash","location","httpServerLocation","width","height","scales","uri","resolvedUri","loaded","sizeBytes","sizeSource","requireRecord","params","Error","bySizeDesc","a","b","overview","snapshot","stats","scanStatus","insights","diff","records","sort","assetsSyncAdapter","version","rest","slice","map","onChange","actions","list","p","limit","Math","min","max","filtered","includes","join","filter","r","loadedOnly","total","length","getDetail","origin","fileSystemLocation","files","sizesByScale","status","ok","result","measured","baseline","savedAt","assets","Object","keys","entries","message"],"sourceRoot":"../../../src","sources":["sync/assetsSyncAdapter.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Expo enrichment — all optional, all read through globalThis.expo guards so
3
+ * bare RN apps (no expo-modules) silently get none of it and no imports are
4
+ * added for anyone.
5
+ */
6
+ /**
7
+ * Every loaded font family — build-time embedded (config plugin / UIAppFonts /
8
+ * android assets/fonts) AND runtime Font.loadAsync, straight from the native
9
+ * module Expo documents as a stable global. [] when unavailable (bare RN).
10
+ */
11
+ export declare function getLoadedFontFamilies(): string[];
12
+ /**
13
+ * expo-updates' per-file-hash → local URI map: the COMPLETE shipped asset set
14
+ * in Expo Go / OTA environments, independent of what JS has evaluated.
15
+ * null when not running in an updates-managed environment.
16
+ */
17
+ export declare function getLocalAssets(): Record<string, string> | null;
18
+ //# sourceMappingURL=expo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo.d.ts","sourceRoot":"","sources":["../../../src/capture/expo.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAOhD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAQ9D"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Capture install + scan orchestration.
3
+ *
4
+ * installAssetCapture() is cheap and synchronous (registry walk + patch) and
5
+ * runs at package import. The expensive passes — Metro graph fetch and byte
6
+ * measurement — run in rescan(), triggered when the modal opens or via the
7
+ * `rescan` sync action, so merely installing Buoy never hits the network.
8
+ */
9
+ import type { AssetsScanStatus } from "../types";
10
+ export declare function installAssetCapture(): void;
11
+ /**
12
+ * Full scan: registry re-walk (catches anything the patch missed), Metro
13
+ * graph merge (dev), Expo enrichment refresh, then size measurement.
14
+ */
15
+ export declare function rescan(): Promise<AssetsScanStatus>;
16
+ export declare function getScanStatus(): AssetsScanStatus;
17
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/capture/install.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,wBAAgB,mBAAmB,IAAI,IAAI,CAU1C;AASD;;;GAGG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAWxD;AAED,wBAAgB,aAAa,IAAI,gBAAgB,CAmBhD"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Byte-size measurement.
3
+ *
4
+ * Dev only in practice: each scale variant is fetched from the Metro dev
5
+ * server (HEAD first for Content-Length, GET-blob fallback since Metro
6
+ * doesn't reliably answer HEAD) and the per-variant sizes are summed onto
7
+ * the record. Android release resource ids and iOS file:// URIs are not
8
+ * measurable from JS — those records keep `estDecodedBytes` as their only
9
+ * size signal and the UI marks them as estimates.
10
+ */
11
+ import type { AssetRecord } from "../types";
12
+ /**
13
+ * Best displayable URL for a record: the resolved runtime URI, or (dev) the
14
+ * same dev-server URL the measurement pass uses — this is what gives graph-
15
+ * only (never-loaded) images real thumbnails.
16
+ */
17
+ export declare function previewURL(record: AssetRecord): string | null;
18
+ /**
19
+ * Image source for thumbnails/previews. On device the NUMERIC registry id is
20
+ * preferred (resolves natively — works for Android release resource ids too).
21
+ * On dashboard mirrors that id belongs to the DEVICE's registry and rn-web
22
+ * throws "asset with ID N could not be found" — use the device's http(s)
23
+ * URL instead (the Metro dev server is reachable from the desktop).
24
+ */
25
+ export declare function displaySource(record: AssetRecord): number | {
26
+ uri: string;
27
+ } | null;
28
+ /** All scale-variant URLs for a record, derived without re-encoding pitfalls. */
29
+ export declare function variantURLs(record: AssetRecord): Array<{
30
+ scale: number;
31
+ url: string;
32
+ }>;
33
+ /** Measure every unmeasured record; safe to re-run (skips measured ones). */
34
+ export declare function measureSizes(): Promise<{
35
+ measured: number;
36
+ total: number;
37
+ }>;
38
+ //# sourceMappingURL=measure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../../../src/capture/measure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAI5C;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,WAAW,GAClB,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAOjC;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAoCtF;AAoDD,6EAA6E;AAC7E,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA6BjF"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Metro dev-server graph fetch.
3
+ *
4
+ * The dev server serves `<entry>.assets` next to `<entry>.bundle` — the full
5
+ * dependency graph's AssetData[], INCLUDING assets never required at runtime
6
+ * and the `fileSystemLocation`/`files` fields Metro strips from runtime
7
+ * records. Deriving the URL by swapping `.bundle` → `.assets` on the running
8
+ * bundle's scriptURL keeps the entry path and platform/dev query params
9
+ * intact for both RN CLI (index.bundle) and Expo (…/entry.bundle) layouts.
10
+ *
11
+ * Graph-only records (in the graph, not the registry) are exactly the
12
+ * "shipped but never loaded" set. Dev-only: no server, no graph.
13
+ */
14
+ export declare function getScriptURL(): string | null;
15
+ /** http(s) origin of the Metro dev server, or null when running embedded. */
16
+ export declare function getDevServerOrigin(): string | null;
17
+ /**
18
+ * Candidate graph URLs, most-likely first. The straight `.bundle`→`.assets`
19
+ * swap works for RN CLI, but Expo dev builds serve a VIRTUAL entry
20
+ * (.expo/.virtual-metro-entry.bundle) that only exists for .bundle requests —
21
+ * its .assets twin 404s — so the real entry modules are tried next, keeping
22
+ * the original query string (platform/dev/etc.) intact.
23
+ */
24
+ export declare function getGraphURLCandidates(): string[];
25
+ /** Fetch the full asset graph from the dev server and merge it into the store. */
26
+ export declare function fetchAssetGraph(): Promise<{
27
+ ok: true;
28
+ count: number;
29
+ } | {
30
+ ok: false;
31
+ message: string;
32
+ }>;
33
+ //# sourceMappingURL=metroGraph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metroGraph.d.ts","sourceRoot":"","sources":["../../../src/capture/metroGraph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAmBH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAU5C;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAIlD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAkBhD;AAED,kFAAkF;AAClF,wBAAsB,eAAe,IAAI,OAAO,CAC9C;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAC7D,CAiEA"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Runtime access to @react-native/assets-registry.
3
+ *
4
+ * Asset ids are contiguous 1..N (`assets.push` return value), so a plain
5
+ * getAssetByID walk enumerates every asset registered so far — including
6
+ * everything registered BEFORE this tool was evaluated. That's why, unlike
7
+ * the images tool, there is no "must be the first import" requirement here:
8
+ * the walk backfills whatever the patch missed.
9
+ *
10
+ * registerAsset is patched (plain non-frozen CommonJS export, looked up at
11
+ * call time by Metro's generated asset modules) purely for LIVE updates as
12
+ * lazily-required assets register later.
13
+ */
14
+ import type { AssetRecord } from "../types";
15
+ /** Runtime shape of a registry entry (fileSystemLocation/files are stripped by Metro). */
16
+ export interface PackagerAsset {
17
+ __packager_asset: boolean;
18
+ httpServerLocation: string;
19
+ width?: number | null;
20
+ height?: number | null;
21
+ scales: number[];
22
+ hash: string;
23
+ name: string;
24
+ type: string;
25
+ }
26
+ interface RegistryModule {
27
+ registerAsset: (asset: PackagerAsset) => number;
28
+ getAssetByID: (assetId: number) => PackagerAsset | undefined;
29
+ }
30
+ export declare function getRegistryModule(): RegistryModule | null;
31
+ /** resolveAssetSource(id) → this environment's URI (dev URL / file:// / res id). */
32
+ export declare function resolveRegistryAsset(registryId: number): {
33
+ uri: string;
34
+ scale: number;
35
+ } | null;
36
+ export declare function upsertFromPackagerAsset(registryId: number, asset: PackagerAsset): AssetRecord;
37
+ /** Enumerate every asset registered so far. Returns the highest id seen. */
38
+ export declare function walkRegistry(): number;
39
+ /**
40
+ * Wrap registerAsset so future registrations stream in live. Safe to call
41
+ * more than once (marker guard); the walk covers anything registered before.
42
+ */
43
+ export declare function patchRegisterAsset(): boolean;
44
+ export {};
45
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/capture/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,cAAc;IACtB,aAAa,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,MAAM,CAAC;IAChD,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;CAC9D;AAID,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAgBzD;AAED,oFAAoF;AACpF,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,GACjB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAWvC;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,aAAa,GACnB,WAAW,CAiBb;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,IAAI,MAAM,CAWrC;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAqB5C"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * AssetDetail — full metadata for one asset: preview, identity, dimensions,
3
+ * per-scale sizes, resolution info, and which audit findings apply.
4
+ *
5
+ * Image previews render through the numeric registry id (works in every
6
+ * environment); fonts render a pangram with fontFamily set to the asset name
7
+ * — a best-effort guess (family ≠ filename for many fonts) that falls back
8
+ * to the system font silently when it misses.
9
+ */
10
+ import type { AssetRecord, AssetsInsights } from "../types";
11
+ interface AssetDetailProps {
12
+ record: AssetRecord;
13
+ insights: AssetsInsights;
14
+ }
15
+ export declare function AssetDetail({ record, insights }: AssetDetailProps): import("react").JSX.Element;
16
+ export {};
17
+ //# sourceMappingURL=AssetDetail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetDetail.d.ts","sourceRoot":"","sources":["../../../src/components/AssetDetail.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE5D,UAAU,gBAAgB;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAwCD,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,gBAAgB,+BA4FjE"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * AssetRow — one bundled asset as a family-style card (matching the network
3
+ * tool's rows): rounded card, colored accent edge per kind, thumbnail, name,
4
+ * quiet metadata, bold right-aligned size, and finding badges ONLY when a
5
+ * finding exists. A thin proportional bar along the card bottom makes the
6
+ * heavy assets feel heavy at a glance.
7
+ *
8
+ * Thumbnails render through the NUMERIC registry id when available — that
9
+ * routes through resolveAssetSource natively, so it works in dev, iOS
10
+ * release (file://) and Android release (bare resource id) alike. They carry
11
+ * the buoy-internal testID so the images tool never records our own UI.
12
+ */
13
+ import type { AssetRecord } from "../types";
14
+ /** Which audit findings apply to this record (drives the row badges). */
15
+ export interface AssetRowFlags {
16
+ scaleGap: boolean;
17
+ scaleAnomaly: boolean;
18
+ duplicate: boolean;
19
+ webp: boolean;
20
+ oversize: boolean;
21
+ heavy: boolean;
22
+ }
23
+ interface AssetRowProps {
24
+ record: AssetRecord;
25
+ flags: AssetRowFlags;
26
+ /** This record's size relative to the largest in the list (0–1). */
27
+ sizeFraction: number;
28
+ onPress: (id: number) => void;
29
+ }
30
+ export declare function AssetRow({ record, flags, sizeFraction, onPress }: AssetRowProps): import("react").JSX.Element;
31
+ export {};
32
+ //# sourceMappingURL=AssetRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetRow.d.ts","sourceRoot":"","sources":["../../../src/components/AssetRow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAaH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAaD,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,aAAa,+BAiF/E"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * AssetsFilterBar — kind filter pills with counts, styled like the network
3
+ * tool's bordered pills: outlined, kind-accent-colored when active. Wrapping
4
+ * row, not a horizontal ScrollView (same height-measurement pitfall the
5
+ * images tool documents).
6
+ */
7
+ import type { AssetKind, AssetsStats } from "../types";
8
+ export type AssetFilter = "all" | "unused" | AssetKind;
9
+ interface AssetsFilterBarProps {
10
+ stats: AssetsStats;
11
+ filter: AssetFilter;
12
+ onChange: (filter: AssetFilter) => void;
13
+ }
14
+ export declare function AssetsFilterBar({ stats, filter, onChange }: AssetsFilterBarProps): import("react").JSX.Element | null;
15
+ export {};
16
+ //# sourceMappingURL=AssetsFilterBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetsFilterBar.d.ts","sourceRoot":"","sources":["../../../src/components/AssetsFilterBar.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvD,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEvD,UAAU,oBAAoB;IAC5B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;CACzC;AAED,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,oBAAoB,sCAsDhF"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * AssetsHeader — shared ModalHeader wiring, matching the Images/Console
3
+ * header pattern. List mode shows inventory totals plus the shared
4
+ * ToolbarCopyButton (full markdown report); detail mode shows back
5
+ * navigation and the single-asset report.
6
+ */
7
+ import type { AssetsStats } from "../types";
8
+ interface AssetsHeaderProps {
9
+ stats: AssetsStats;
10
+ /** Size measurement in progress — suppress the (partial) byte total. */
11
+ measuring: boolean;
12
+ detailOpen: boolean;
13
+ detailIndex?: number;
14
+ detailTotal?: number;
15
+ onCloseDetail: () => void;
16
+ onClear: () => void;
17
+ getReport: () => string;
18
+ onBack?: () => void;
19
+ }
20
+ export declare function AssetsHeader({ stats, measuring, detailOpen, detailIndex, detailTotal, onCloseDetail, onClear, getReport, onBack, }: AssetsHeaderProps): import("react").JSX.Element;
21
+ export {};
22
+ //# sourceMappingURL=AssetsHeader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetsHeader.d.ts","sourceRoot":"","sources":["../../../src/components/AssetsHeader.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,UAAU,iBAAiB;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,wEAAwE;IACxE,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,SAAS,EACT,UAAU,EACV,WAAgB,EAChB,WAAe,EACf,aAAa,EACb,OAAO,EACP,SAAS,EACT,MAAM,GACP,EAAE,iBAAiB,+BAoCnB"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * AssetsIcon — re-exported from the Buoy Icon Format.
3
+ *
4
+ * The artwork lives in shared/icons/assets.json and is generated into
5
+ * @buoy-gg/floating-tools-core, so React Native, the desktop dashboard and
6
+ * Flutter all render the same drawing. Edit the JSON, then `pnpm icons`.
7
+ */
8
+ export { AssetsIcon, ASSETS_ICON_COLOR } from "@buoy-gg/shared-ui";
9
+ //# sourceMappingURL=AssetsIcon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetsIcon.d.ts","sourceRoot":"","sources":["../../../src/components/AssetsIcon.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * AssetsListControls — one compact row: name search, sort cycle (SIZE →
3
+ * NAME → TYPE), and — when no baseline exists yet — the BASE button that
4
+ * saves one. Once a baseline exists the BaselineBar takes over the diff UI,
5
+ * so this row never wastes space on a hint sentence.
6
+ */
7
+ export type AssetSort = "size" | "name" | "type";
8
+ interface AssetsListControlsProps {
9
+ query: string;
10
+ onQueryChange: (query: string) => void;
11
+ sort: AssetSort;
12
+ onSortChange: (sort: AssetSort) => void;
13
+ /** Show the save-baseline button (no baseline saved yet). */
14
+ showBaselineButton: boolean;
15
+ }
16
+ export declare function AssetsListControls({ query, onQueryChange, sort, onSortChange, showBaselineButton, }: AssetsListControlsProps): import("react").JSX.Element;
17
+ export {};
18
+ //# sourceMappingURL=AssetsListControls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssetsListControls.d.ts","sourceRoot":"","sources":["../../../src/components/AssetsListControls.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAQjD,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACxC,6DAA6D;IAC7D,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,aAAa,EACb,IAAI,EACJ,YAAY,EACZ,kBAAkB,GACnB,EAAE,uBAAuB,+BA+BzB"}