@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,59 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * @buoy-gg/assets — bundled-asset inventory for React Native / Expo.
5
+ *
6
+ * Enumerates every asset in the app (images, fonts, video, audio, …) via the
7
+ * runtime asset registry, enriched in dev with the Metro graph (full-bundle
8
+ * coverage, byte sizes, never-loaded detection) and on Expo with loaded font
9
+ * families + the updates localAssets map. Zero configuration: importing this
10
+ * package installs the (cheap, synchronous) registry capture.
11
+ */
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Tool preset (FloatingDevTools)
15
+ // ---------------------------------------------------------------------------
16
+ export { assetsToolPreset, createAssetsTool } from "./preset";
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // Components
20
+ // ---------------------------------------------------------------------------
21
+ export { AssetsModal, AssetsToolView } from "./components/AssetsModal";
22
+ export { AssetsIcon, ASSETS_ICON_COLOR } from "./components/AssetsIcon";
23
+
24
+ // ---------------------------------------------------------------------------
25
+ // Capture / scanning
26
+ // ---------------------------------------------------------------------------
27
+ export { installAssetCapture, rescan, getScanStatus } from "./capture/install";
28
+ export { measureSizes } from "./capture/measure";
29
+ export { fetchAssetGraph, getDevServerOrigin } from "./capture/metroGraph";
30
+ export { getLoadedFontFamilies, getLocalAssets } from "./capture/expo";
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // Store
34
+ // ---------------------------------------------------------------------------
35
+ export { clearRecords, computeStats, estDecodedBytes, getRecord, getSnapshot, subscribe } from "./store/assetStore";
36
+ export { computeInsights } from "./store/insights";
37
+ export { clearBaseline, computeDiff, getDiff, loadBaseline, saveBaseline } from "./store/baseline";
38
+ export { useAssetRecords } from "./hooks/useAssetRecords";
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // Reports
42
+ // ---------------------------------------------------------------------------
43
+ export { formatAssetMarkdown, formatInventoryMarkdown } from "./export";
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // External sync (desktop dashboard + MCP)
47
+ // ---------------------------------------------------------------------------
48
+ export { assetsSyncAdapter } from "./sync/assetsSyncAdapter";
49
+ export { disableAssetsCapture, replaceAssetsFromSnapshot, setRemoteAssetsHandler } from "./remote";
50
+
51
+ // ---------------------------------------------------------------------------
52
+ // Types
53
+ // ---------------------------------------------------------------------------
54
+
55
+ // Side effect: install the registry capture at import (walk + patch — cheap,
56
+ // synchronous, no network). The Metro graph fetch waits for the modal/action.
57
+ import { installAssetCapture as installOnImport } from "./capture/install";
58
+ installOnImport();
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["assetsToolPreset","createAssetsTool","AssetsModal","AssetsToolView","AssetsIcon","ASSETS_ICON_COLOR","installAssetCapture","rescan","getScanStatus","measureSizes","fetchAssetGraph","getDevServerOrigin","getLoadedFontFamilies","getLocalAssets","clearRecords","computeStats","estDecodedBytes","getRecord","getSnapshot","subscribe","computeInsights","clearBaseline","computeDiff","getDiff","loadBaseline","saveBaseline","useAssetRecords","formatAssetMarkdown","formatInventoryMarkdown","assetsSyncAdapter","disableAssetsCapture","replaceAssetsFromSnapshot","setRemoteAssetsHandler","installOnImport"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAASA,gBAAgB,EAAEC,gBAAgB,QAAQ,UAAU;;AAE7D;AACA;AACA;AACA,SAASC,WAAW,EAAEC,cAAc,QAAQ,0BAA0B;AACtE,SAASC,UAAU,EAAEC,iBAAiB,QAAQ,yBAAyB;;AAEvE;AACA;AACA;AACA,SAASC,mBAAmB,EAAEC,MAAM,EAAEC,aAAa,QAAQ,mBAAmB;AAC9E,SAASC,YAAY,QAAQ,mBAAmB;AAChD,SAASC,eAAe,EAAEC,kBAAkB,QAAQ,sBAAsB;AAC1E,SAASC,qBAAqB,EAAEC,cAAc,QAAQ,gBAAgB;;AAEtE;AACA;AACA;AACA,SACEC,YAAY,EACZC,YAAY,EACZC,eAAe,EACfC,SAAS,EACTC,WAAW,EACXC,SAAS,QACJ,oBAAoB;AAC3B,SAASC,eAAe,QAAQ,kBAAkB;AAClD,SACEC,aAAa,EACbC,WAAW,EACXC,OAAO,EACPC,YAAY,EACZC,YAAY,QACP,kBAAkB;AACzB,SAASC,eAAe,QAAQ,yBAAyB;;AAEzD;AACA;AACA;AACA,SAASC,mBAAmB,EAAEC,uBAAuB,QAAQ,UAAU;;AAEvE;AACA;AACA;AACA,SAASC,iBAAiB,QAAQ,0BAA0B;AAC5D,SACEC,oBAAoB,EACpBC,yBAAyB,EACzBC,sBAAsB,QACjB,UAAU;;AAGjB;AACA;AACA;;AAeA;AACA;AACA,SAAS1B,mBAAmB,IAAI2B,eAAe,QAAQ,mBAAmB;AAC1EA,eAAe,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Pre-configured Assets tool for FloatingDevTools.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { assetsToolPreset } from '@buoy-gg/assets';
9
+ *
10
+ * <FloatingDevTools apps={[assetsToolPreset]} />
11
+ * ```
12
+ */
13
+
14
+ import { AssetsIcon, ASSETS_ICON_COLOR } from "./components/AssetsIcon";
15
+ import { AssetsModal } from "./components/AssetsModal";
16
+ import { jsx as _jsx } from "react/jsx-runtime";
17
+ export const assetsToolPreset = {
18
+ id: "assets",
19
+ name: "ASSETS",
20
+ description: "Every bundled asset — sizes, scale coverage, unused detection",
21
+ slot: "both",
22
+ icon: ({
23
+ size,
24
+ color
25
+ }) => /*#__PURE__*/_jsx(AssetsIcon, {
26
+ size: size,
27
+ color: color || ASSETS_ICON_COLOR
28
+ }),
29
+ component: AssetsModal
30
+ };
31
+
32
+ /** Create a custom Assets tool configuration. */
33
+ export function createAssetsTool(options = {}) {
34
+ return {
35
+ ...assetsToolPreset,
36
+ name: options.name ?? assetsToolPreset.name,
37
+ description: options.description ?? assetsToolPreset.description
38
+ };
39
+ }
40
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["AssetsIcon","ASSETS_ICON_COLOR","AssetsModal","jsx","_jsx","assetsToolPreset","id","name","description","slot","icon","size","color","component","createAssetsTool","options"],"sourceRoot":"../../src","sources":["preset.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,UAAU,EAAEC,iBAAiB,QAAQ,yBAAyB;AACvE,SAASC,WAAW,QAAQ,0BAA0B;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAEvD,OAAO,MAAMC,gBAAgB,GAAG;EAC9BC,EAAE,EAAE,QAAQ;EACZC,IAAI,EAAE,QAAQ;EACdC,WAAW,EAAE,+DAA+D;EAC5EC,IAAI,EAAE,MAAe;EACrBC,IAAI,EAAEA,CAAC;IAAEC,IAAI;IAAEC;EAAwC,CAAC,kBACtDR,IAAA,CAACJ,UAAU;IAACW,IAAI,EAAEA,IAAK;IAACC,KAAK,EAAEA,KAAK,IAAIX;EAAkB,CAAE,CAC7D;EACDY,SAAS,EAAEX;AACb,CAAC;;AAED;AACA,OAAO,SAASY,gBAAgBA,CAC9BC,OAAgD,GAAG,CAAC,CAAC,EACrD;EACA,OAAO;IACL,GAAGV,gBAAgB;IACnBE,IAAI,EAAEQ,OAAO,CAACR,IAAI,IAAIF,gBAAgB,CAACE,IAAI;IAC3CC,WAAW,EAAEO,OAAO,CAACP,WAAW,IAAIH,gBAAgB,CAACG;EACvD,CAAC;AACH","ignoreList":[]}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Remote-dispatch seam for dashboard mirrors (Buoy Desktop).
5
+ *
6
+ * On device this stays null and every action runs locally. A dashboard sets
7
+ * a handler that forwards action name + params over external-sync to the
8
+ * SAME adapter actions the MCP uses (sync/assetsSyncAdapter.ts), so one
9
+ * action vocabulary serves phone UI, desktop UI, and LLM automation.
10
+ */
11
+
12
+ import { assetsState } from "./state";
13
+ import { invalidate } from "./store/assetStore";
14
+ export function setRemoteAssetsHandler(handler) {
15
+ assetsState().remoteDispatch = handler;
16
+ }
17
+ export function remoteAssetsDispatch() {
18
+ return assetsState().remoteDispatch;
19
+ }
20
+
21
+ /** Dashboards never scan their own bundle — the store is purely a mirror. */
22
+ export function disableAssetsCapture() {
23
+ assetsState().captureDisabled = true;
24
+ }
25
+
26
+ /** Replace the whole store from a synced adapter snapshot. */
27
+ export function replaceAssetsFromSnapshot(payload) {
28
+ const s = assetsState();
29
+ const wire = payload.records ?? [];
30
+ s.records = wire.map(w => ({
31
+ id: w.id,
32
+ key: w.key,
33
+ registryId: w.registryId ?? undefined,
34
+ name: w.name,
35
+ type: w.type,
36
+ kind: w.kind,
37
+ hash: w.hash ?? undefined,
38
+ httpServerLocation: w.location ?? undefined,
39
+ width: w.width ?? undefined,
40
+ height: w.height ?? undefined,
41
+ scales: w.scales,
42
+ resolvedUri: w.uri ?? undefined,
43
+ loaded: w.loaded,
44
+ origin: w.registryId != null ? "registry" : "graph",
45
+ sizeBytes: w.sizeBytes ?? undefined,
46
+ sizeSource: w.sizeSource ?? undefined,
47
+ firstSeenAt: Date.now()
48
+ }));
49
+ s.byKey = new Map(s.records.map(r => [r.key, r]));
50
+ s.byId = new Map(s.records.map(r => [r.id, r]));
51
+ if (payload.scanStatus) {
52
+ s.mirrorScanStatus = payload.scanStatus;
53
+ s.fontFamilies = payload.scanStatus.fontFamilies ?? [];
54
+ }
55
+ s.mirrorDiff = payload.diff ?? null;
56
+ invalidate();
57
+ }
58
+ //# sourceMappingURL=remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["assetsState","invalidate","setRemoteAssetsHandler","handler","remoteDispatch","remoteAssetsDispatch","disableAssetsCapture","captureDisabled","replaceAssetsFromSnapshot","payload","s","wire","records","map","w","id","key","registryId","undefined","name","type","kind","hash","httpServerLocation","location","width","height","scales","resolvedUri","uri","loaded","origin","sizeBytes","sizeSource","firstSeenAt","Date","now","byKey","Map","r","byId","scanStatus","mirrorScanStatus","fontFamilies","mirrorDiff","diff"],"sourceRoot":"../../src","sources":["remote.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,WAAW,QAAQ,SAAS;AACrC,SAASC,UAAU,QAAQ,oBAAoB;AAQ/C,OAAO,SAASC,sBAAsBA,CACpCC,OAAoC,EAC9B;EACNH,WAAW,CAAC,CAAC,CAACI,cAAc,GAAGD,OAAO;AACxC;AAEA,OAAO,SAASE,oBAAoBA,CAAA,EAAgC;EAClE,OAAOL,WAAW,CAAC,CAAC,CAACI,cAAc;AACrC;;AAEA;AACA,OAAO,SAASE,oBAAoBA,CAAA,EAAS;EAC3CN,WAAW,CAAC,CAAC,CAACO,eAAe,GAAG,IAAI;AACtC;;AAEA;AACA,OAAO,SAASC,yBAAyBA,CAACC,OAA8B,EAAQ;EAC9E,MAAMC,CAAC,GAAGV,WAAW,CAAC,CAAC;EACvB,MAAMW,IAAI,GAAGF,OAAO,CAACG,OAAO,IAAI,EAAE;EAClCF,CAAC,CAACE,OAAO,GAAGD,IAAI,CAACE,GAAG,CAAEC,CAAC,KAAM;IAC3BC,EAAE,EAAED,CAAC,CAACC,EAAE;IACRC,GAAG,EAAEF,CAAC,CAACE,GAAG;IACVC,UAAU,EAAEH,CAAC,CAACG,UAAU,IAAIC,SAAS;IACrCC,IAAI,EAAEL,CAAC,CAACK,IAAI;IACZC,IAAI,EAAEN,CAAC,CAACM,IAAI;IACZC,IAAI,EAAEP,CAAC,CAACO,IAAI;IACZC,IAAI,EAAER,CAAC,CAACQ,IAAI,IAAIJ,SAAS;IACzBK,kBAAkB,EAAET,CAAC,CAACU,QAAQ,IAAIN,SAAS;IAC3CO,KAAK,EAAEX,CAAC,CAACW,KAAK,IAAIP,SAAS;IAC3BQ,MAAM,EAAEZ,CAAC,CAACY,MAAM,IAAIR,SAAS;IAC7BS,MAAM,EAAEb,CAAC,CAACa,MAAM;IAChBC,WAAW,EAAEd,CAAC,CAACe,GAAG,IAAIX,SAAS;IAC/BY,MAAM,EAAEhB,CAAC,CAACgB,MAAM;IAChBC,MAAM,EAAEjB,CAAC,CAACG,UAAU,IAAI,IAAI,GAAI,UAAU,GAAc,OAAiB;IACzEe,SAAS,EAAElB,CAAC,CAACkB,SAAS,IAAId,SAAS;IACnCe,UAAU,EAAEnB,CAAC,CAACmB,UAAU,IAAIf,SAAS;IACrCgB,WAAW,EAAEC,IAAI,CAACC,GAAG,CAAC;EACxB,CAAC,CAAC,CAAC;EACH1B,CAAC,CAAC2B,KAAK,GAAG,IAAIC,GAAG,CAAC5B,CAAC,CAACE,OAAO,CAACC,GAAG,CAAE0B,CAAC,IAAK,CAACA,CAAC,CAACvB,GAAG,EAAEuB,CAAC,CAAC,CAAC,CAAC;EACnD7B,CAAC,CAAC8B,IAAI,GAAG,IAAIF,GAAG,CAAC5B,CAAC,CAACE,OAAO,CAACC,GAAG,CAAE0B,CAAC,IAAK,CAACA,CAAC,CAACxB,EAAE,EAAEwB,CAAC,CAAC,CAAC,CAAC;EACjD,IAAI9B,OAAO,CAACgC,UAAU,EAAE;IACtB/B,CAAC,CAACgC,gBAAgB,GAAGjC,OAAO,CAACgC,UAAU;IACvC/B,CAAC,CAACiC,YAAY,GAAGlC,OAAO,CAACgC,UAAU,CAACE,YAAY,IAAI,EAAE;EACxD;EACAjC,CAAC,CAACkC,UAAU,GAAGnC,OAAO,CAACoC,IAAI,IAAI,IAAI;EACnC5C,UAAU,CAAC,CAAC;AACd","ignoreList":[]}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Global singleton state for the Assets tool.
5
+ *
6
+ * Same rationale as the images tool: the package can be evaluated as two
7
+ * module instances (lib vs src resolution), and the registerAsset patch must
8
+ * share one store with whichever copy the UI renders from. All mutable state
9
+ * lives on globalThis under a well-known symbol.
10
+ */
11
+
12
+ const KEY = Symbol.for("buoy.assets.globalState.v1");
13
+ export function assetsState() {
14
+ const g = globalThis;
15
+ if (!g[KEY]) {
16
+ g[KEY] = {
17
+ records: [],
18
+ byKey: new Map(),
19
+ byId: new Map(),
20
+ nextId: 1,
21
+ listeners: new Set(),
22
+ snapshot: [],
23
+ emitScheduled: false,
24
+ installed: false,
25
+ patched: false,
26
+ registryAvailable: false,
27
+ graphSupported: false,
28
+ graphCount: null,
29
+ graphError: null,
30
+ graphFetchInFlight: false,
31
+ lastScanAt: null,
32
+ measuring: false,
33
+ measuredCount: 0,
34
+ fontFamilies: [],
35
+ localAssetCount: null,
36
+ baseline: null,
37
+ baselineLoaded: false,
38
+ captureDisabled: false,
39
+ remoteDispatch: null,
40
+ mirrorScanStatus: null,
41
+ mirrorPixelRatio: null,
42
+ mirrorDiff: null
43
+ };
44
+ }
45
+ return g[KEY];
46
+ }
47
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["KEY","Symbol","for","assetsState","g","globalThis","records","byKey","Map","byId","nextId","listeners","Set","snapshot","emitScheduled","installed","patched","registryAvailable","graphSupported","graphCount","graphError","graphFetchInFlight","lastScanAt","measuring","measuredCount","fontFamilies","localAssetCount","baseline","baselineLoaded","captureDisabled","remoteDispatch","mirrorScanStatus","mirrorPixelRatio","mirrorDiff"],"sourceRoot":"../../src","sources":["state.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAyCA,MAAMA,GAAG,GAAGC,MAAM,CAACC,GAAG,CAAC,4BAA4B,CAAC;AAEpD,OAAO,SAASC,WAAWA,CAAA,EAAsB;EAC/C,MAAMC,CAAC,GAAGC,UAA2D;EACrE,IAAI,CAACD,CAAC,CAACJ,GAAG,CAAC,EAAE;IACXI,CAAC,CAACJ,GAAG,CAAC,GAAG;MACPM,OAAO,EAAE,EAAE;MACXC,KAAK,EAAE,IAAIC,GAAG,CAAC,CAAC;MAChBC,IAAI,EAAE,IAAID,GAAG,CAAC,CAAC;MACfE,MAAM,EAAE,CAAC;MACTC,SAAS,EAAE,IAAIC,GAAG,CAAC,CAAC;MACpBC,QAAQ,EAAE,EAAE;MACZC,aAAa,EAAE,KAAK;MACpBC,SAAS,EAAE,KAAK;MAChBC,OAAO,EAAE,KAAK;MACdC,iBAAiB,EAAE,KAAK;MACxBC,cAAc,EAAE,KAAK;MACrBC,UAAU,EAAE,IAAI;MAChBC,UAAU,EAAE,IAAI;MAChBC,kBAAkB,EAAE,KAAK;MACzBC,UAAU,EAAE,IAAI;MAChBC,SAAS,EAAE,KAAK;MAChBC,aAAa,EAAE,CAAC;MAChBC,YAAY,EAAE,EAAE;MAChBC,eAAe,EAAE,IAAI;MACrBC,QAAQ,EAAE,IAAI;MACdC,cAAc,EAAE,KAAK;MACrBC,eAAe,EAAE,KAAK;MACtBC,cAAc,EAAE,IAAI;MACpBC,gBAAgB,EAAE,IAAI;MACtBC,gBAAgB,EAAE,IAAI;MACtBC,UAAU,EAAE;IACd,CAAC;EACH;EACA,OAAO7B,CAAC,CAACJ,GAAG,CAAC;AACf","ignoreList":[]}
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * assetStore
5
+ *
6
+ * Bounded store of AssetRecords keyed by their stable asset key
7
+ * (`location/name.type`). Follows the images tool's store shape — Set of
8
+ * listeners, frame-coalesced emit, all mutable state on the globalThis
9
+ * singleton (../state.ts) so dual module instances share one store.
10
+ *
11
+ * Unlike the images tool this is an INVENTORY, not an event log: upserts
12
+ * merge into the existing record for a key instead of appending, and there
13
+ * is no ring-buffer cap (a bundle has a bounded asset count by construction).
14
+ */
15
+
16
+ import { assetsState } from "../state";
17
+ function emit() {
18
+ const s = assetsState();
19
+ if (s.emitScheduled) return;
20
+ s.emitScheduled = true;
21
+ requestAnimationFrame(() => {
22
+ s.emitScheduled = false;
23
+ for (const listener of s.listeners) listener();
24
+ });
25
+ }
26
+
27
+ /** Snapshot identity only changes on emit, so useSyncExternalStore stays cheap. */
28
+ export function invalidate() {
29
+ const s = assetsState();
30
+ s.snapshot = [...s.records];
31
+ emit();
32
+ }
33
+ const KIND_BY_EXT = {
34
+ png: "image",
35
+ jpg: "image",
36
+ jpeg: "image",
37
+ gif: "image",
38
+ webp: "image",
39
+ bmp: "image",
40
+ psd: "image",
41
+ svg: "image",
42
+ tiff: "image",
43
+ ktx: "image",
44
+ heic: "image",
45
+ heif: "image",
46
+ avif: "image",
47
+ ttf: "font",
48
+ otf: "font",
49
+ woff: "font",
50
+ woff2: "font",
51
+ ttc: "font",
52
+ mp4: "video",
53
+ m4v: "video",
54
+ mov: "video",
55
+ mpeg: "video",
56
+ mpg: "video",
57
+ webm: "video",
58
+ avi: "video",
59
+ mp3: "audio",
60
+ wav: "audio",
61
+ aac: "audio",
62
+ aiff: "audio",
63
+ caf: "audio",
64
+ m4a: "audio",
65
+ ogg: "audio",
66
+ json: "data",
67
+ db: "data",
68
+ yaml: "data",
69
+ yml: "data",
70
+ xml: "data",
71
+ html: "data",
72
+ pdf: "data",
73
+ zip: "data"
74
+ };
75
+ export function kindForType(type) {
76
+ return KIND_BY_EXT[type.toLowerCase()] ?? "other";
77
+ }
78
+ export function assetKey(httpServerLocation, name, type) {
79
+ // The runtime registry percent-encodes ?unstable_path= locations while the
80
+ // Metro graph endpoint returns them decoded — normalize or every asset
81
+ // splits into a registry record + a graph record.
82
+ let location = httpServerLocation ?? "";
83
+ try {
84
+ location = decodeURIComponent(location);
85
+ } catch {
86
+ // malformed escapes: keep the raw string
87
+ }
88
+ return `${location}/${name}.${type}`;
89
+ }
90
+ /** Merge an asset sighting into the store; creates the record on first sight. */
91
+ export function upsertRecord(input) {
92
+ const s = assetsState();
93
+ let record = s.byKey.get(input.key);
94
+ if (!record) {
95
+ record = {
96
+ id: s.nextId++,
97
+ key: input.key,
98
+ name: input.name,
99
+ type: input.type,
100
+ kind: kindForType(input.type),
101
+ scales: input.scales ?? [],
102
+ loaded: input.loaded ?? false,
103
+ origin: input.origin,
104
+ firstSeenAt: Date.now()
105
+ };
106
+ s.records.push(record);
107
+ s.byKey.set(record.key, record);
108
+ s.byId.set(record.id, record);
109
+ }
110
+ if (input.registryId != null) record.registryId = input.registryId;
111
+ if (input.hash != null) record.hash = input.hash;
112
+ if (input.httpServerLocation != null) record.httpServerLocation = input.httpServerLocation;
113
+ if (input.width != null) record.width = input.width;
114
+ if (input.height != null) record.height = input.height;
115
+ if (input.scales && input.scales.length) {
116
+ // Dedupe: foo.png + foo@1x.png both existing yields [1, 1, …] from Metro.
117
+ record.scales = [...new Set(input.scales)].sort((a, b) => a - b);
118
+ }
119
+ if (input.resolvedUri != null) record.resolvedUri = input.resolvedUri;
120
+ if (input.resolvedScale != null) record.resolvedScale = input.resolvedScale;
121
+ if (input.loaded) record.loaded = true;
122
+ if (input.fileSystemLocation != null) record.fileSystemLocation = input.fileSystemLocation;
123
+ if (input.files) record.files = input.files;
124
+ if (input.fileHashes) record.fileHashes = input.fileHashes;
125
+ invalidate();
126
+ return record;
127
+ }
128
+
129
+ /** Mutate a record in place (records are owned by the store) and notify. */
130
+ export function updateRecord(id, patch) {
131
+ const s = assetsState();
132
+ const record = s.byId.get(id);
133
+ if (!record) return undefined;
134
+ Object.assign(record, patch);
135
+ invalidate();
136
+ return record;
137
+ }
138
+ export function getRecord(id) {
139
+ return assetsState().byId.get(id);
140
+ }
141
+ export function getRecordByKey(key) {
142
+ return assetsState().byKey.get(key);
143
+ }
144
+ export function getSnapshot() {
145
+ return assetsState().snapshot;
146
+ }
147
+ export function subscribe(listener) {
148
+ const s = assetsState();
149
+ s.listeners.add(listener);
150
+ return () => assetsState().listeners.delete(listener);
151
+ }
152
+ export function clearRecords() {
153
+ const s = assetsState();
154
+ s.records = [];
155
+ s.byKey = new Map();
156
+ s.byId = new Map();
157
+ s.measuredCount = 0;
158
+ s.graphCount = null;
159
+ invalidate();
160
+ }
161
+
162
+ /**
163
+ * Estimated decoded-bitmap memory (RGBA8888) at the scale this device would
164
+ * pick — the size fallback when bytes can't be measured (release builds).
165
+ */
166
+ export function estDecodedBytes(record) {
167
+ if (record.kind !== "image" || !record.width || !record.height) return 0;
168
+ const scale = record.resolvedScale ?? (record.scales.length ? record.scales[record.scales.length - 1] : 1);
169
+ return Math.round(record.width * scale * record.height * scale * 4);
170
+ }
171
+ export function computeStats(list) {
172
+ const s = assetsState();
173
+ const byKind = {
174
+ image: {
175
+ count: 0,
176
+ bytes: 0
177
+ },
178
+ font: {
179
+ count: 0,
180
+ bytes: 0
181
+ },
182
+ video: {
183
+ count: 0,
184
+ bytes: 0
185
+ },
186
+ audio: {
187
+ count: 0,
188
+ bytes: 0
189
+ },
190
+ data: {
191
+ count: 0,
192
+ bytes: 0
193
+ },
194
+ other: {
195
+ count: 0,
196
+ bytes: 0
197
+ }
198
+ };
199
+ const stats = {
200
+ total: list.length,
201
+ loaded: 0,
202
+ neverLoaded: 0,
203
+ byKind,
204
+ totalBytes: 0,
205
+ measuredCount: 0,
206
+ fontFamilies: s.fontFamilies.length
207
+ };
208
+ for (const r of list) {
209
+ if (r.loaded) stats.loaded++;else stats.neverLoaded++;
210
+ byKind[r.kind].count++;
211
+ if (r.sizeBytes != null && r.sizeSource === "measured") {
212
+ byKind[r.kind].bytes += r.sizeBytes;
213
+ stats.totalBytes += r.sizeBytes;
214
+ stats.measuredCount++;
215
+ }
216
+ }
217
+ return stats;
218
+ }
219
+ //# sourceMappingURL=assetStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["assetsState","emit","s","emitScheduled","requestAnimationFrame","listener","listeners","invalidate","snapshot","records","KIND_BY_EXT","png","jpg","jpeg","gif","webp","bmp","psd","svg","tiff","ktx","heic","heif","avif","ttf","otf","woff","woff2","ttc","mp4","m4v","mov","mpeg","mpg","webm","avi","mp3","wav","aac","aiff","caf","m4a","ogg","json","db","yaml","yml","xml","html","pdf","zip","kindForType","type","toLowerCase","assetKey","httpServerLocation","name","location","decodeURIComponent","upsertRecord","input","record","byKey","get","key","id","nextId","kind","scales","loaded","origin","firstSeenAt","Date","now","push","set","byId","registryId","hash","width","height","length","Set","sort","a","b","resolvedUri","resolvedScale","fileSystemLocation","files","fileHashes","updateRecord","patch","undefined","Object","assign","getRecord","getRecordByKey","getSnapshot","subscribe","add","delete","clearRecords","Map","measuredCount","graphCount","estDecodedBytes","scale","Math","round","computeStats","list","byKind","image","count","bytes","font","video","audio","data","other","stats","total","neverLoaded","totalBytes","fontFamilies","r","sizeBytes","sizeSource"],"sourceRoot":"../../../src","sources":["store/assetStore.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Baseline diff — the regression-prevention half of the tool.
5
+ *
6
+ * "Save baseline" persists a slim {hash, size} snapshot of the inventory via
7
+ * shared-ui's persistentStorage (FileSystem → AsyncStorage → memory), and
8
+ * every later scan diffs against it: new assets, removed assets, grown
9
+ * assets, net bytes. Run it before and after a branch and you get "this
10
+ * branch added 2.3 MB" without any CI tooling.
11
+ *
12
+ * On dashboard mirrors the actions forward to the device (the baseline
13
+ * belongs to the app being inspected, not the dashboard) and the computed
14
+ * diff arrives back inside the synced snapshot.
15
+ */
16
+
17
+ import { persistentStorage } from "@buoy-gg/shared-ui";
18
+ import { remoteAssetsDispatch } from "../remote";
19
+ import { assetsState } from "../state";
20
+ import { getSnapshot, invalidate } from "./assetStore";
21
+ const STORAGE_KEY = "@react_buoy/assets/baseline";
22
+
23
+ /** ≥1 KB counts as growth; below that is codec/metadata noise. */
24
+ const GROWN_THRESHOLD_BYTES = 1024;
25
+
26
+ /** Load the persisted baseline into state once; safe to call repeatedly. */
27
+ export async function loadBaseline() {
28
+ const s = assetsState();
29
+ if (s.baselineLoaded) return s.baseline;
30
+ s.baselineLoaded = true;
31
+ try {
32
+ const raw = await persistentStorage.getItem(STORAGE_KEY);
33
+ if (raw) {
34
+ const parsed = JSON.parse(raw);
35
+ if (parsed && typeof parsed.savedAt === "number" && parsed.entries) {
36
+ s.baseline = parsed;
37
+ invalidate();
38
+ }
39
+ }
40
+ } catch {
41
+ // unreadable baseline = no baseline
42
+ }
43
+ return s.baseline;
44
+ }
45
+ export async function saveBaseline() {
46
+ const remote = remoteAssetsDispatch();
47
+ if (remote) {
48
+ await remote("saveBaseline");
49
+ return assetsState().baseline ?? {
50
+ savedAt: Date.now(),
51
+ entries: {}
52
+ };
53
+ }
54
+ const s = assetsState();
55
+ const entries = {};
56
+ for (const r of getSnapshot()) {
57
+ entries[r.key] = {
58
+ hash: r.hash ?? null,
59
+ sizeBytes: r.sizeSource === "measured" ? r.sizeBytes ?? null : null,
60
+ name: r.name,
61
+ type: r.type
62
+ };
63
+ }
64
+ const baseline = {
65
+ savedAt: Date.now(),
66
+ entries
67
+ };
68
+ s.baseline = baseline;
69
+ s.baselineLoaded = true;
70
+ invalidate();
71
+ try {
72
+ await persistentStorage.setItem(STORAGE_KEY, JSON.stringify(baseline));
73
+ } catch {
74
+ // in-memory baseline still works for this session
75
+ }
76
+ return baseline;
77
+ }
78
+ export async function clearBaseline() {
79
+ const remote = remoteAssetsDispatch();
80
+ if (remote) {
81
+ await remote("clearBaseline");
82
+ return;
83
+ }
84
+ const s = assetsState();
85
+ s.baseline = null;
86
+ s.baselineLoaded = true;
87
+ invalidate();
88
+ try {
89
+ await persistentStorage.removeItem(STORAGE_KEY);
90
+ } catch {
91
+ // nothing to clean up
92
+ }
93
+ }
94
+ export function computeDiff(records, baseline) {
95
+ const added = [];
96
+ const grown = [];
97
+ const seen = new Set();
98
+ let currentBytes = 0;
99
+ let baselineBytes = 0;
100
+ let comparable = false;
101
+ for (const r of records) {
102
+ seen.add(r.key);
103
+ const then = baseline.entries[r.key];
104
+ if (!then) {
105
+ added.push(r.id);
106
+ continue;
107
+ }
108
+ const now = r.sizeSource === "measured" ? r.sizeBytes ?? null : null;
109
+ if (now != null && then.sizeBytes != null) {
110
+ comparable = true;
111
+ currentBytes += now;
112
+ baselineBytes += then.sizeBytes;
113
+ if (now - then.sizeBytes >= GROWN_THRESHOLD_BYTES) {
114
+ grown.push({
115
+ id: r.id,
116
+ deltaBytes: now - then.sizeBytes
117
+ });
118
+ }
119
+ }
120
+ }
121
+ const removed = [];
122
+ for (const [key, entry] of Object.entries(baseline.entries)) {
123
+ if (!seen.has(key)) {
124
+ removed.push({
125
+ key,
126
+ name: entry.name,
127
+ type: entry.type
128
+ });
129
+ if (entry.sizeBytes != null) baselineBytes += entry.sizeBytes;
130
+ }
131
+ }
132
+ // Added assets' measured bytes count toward the net even without a
133
+ // baseline counterpart — that's exactly the growth being reported.
134
+ for (const id of added) {
135
+ const r = records.find(rec => rec.id === id);
136
+ if (r?.sizeSource === "measured" && r.sizeBytes != null) {
137
+ comparable = true;
138
+ currentBytes += r.sizeBytes;
139
+ }
140
+ }
141
+ return {
142
+ baselineSavedAt: baseline.savedAt,
143
+ added,
144
+ removed,
145
+ grown: grown.sort((a, b) => b.deltaBytes - a.deltaBytes),
146
+ netBytes: comparable ? currentBytes - baselineBytes : null
147
+ };
148
+ }
149
+
150
+ /** Current diff: the synced device's on mirrors, computed locally on device. */
151
+ export function getDiff() {
152
+ const s = assetsState();
153
+ if (s.mirrorDiff) return s.mirrorDiff;
154
+ if (!s.baseline) return null;
155
+ return computeDiff(getSnapshot(), s.baseline);
156
+ }
157
+ //# sourceMappingURL=baseline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["persistentStorage","remoteAssetsDispatch","assetsState","getSnapshot","invalidate","STORAGE_KEY","GROWN_THRESHOLD_BYTES","loadBaseline","s","baselineLoaded","baseline","raw","getItem","parsed","JSON","parse","savedAt","entries","saveBaseline","remote","Date","now","r","key","hash","sizeBytes","sizeSource","name","type","setItem","stringify","clearBaseline","removeItem","computeDiff","records","added","grown","seen","Set","currentBytes","baselineBytes","comparable","add","then","push","id","deltaBytes","removed","entry","Object","has","find","rec","baselineSavedAt","sort","a","b","netBytes","getDiff","mirrorDiff"],"sourceRoot":"../../../src","sources":["store/baseline.ts"],"mappings":"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","ignoreList":[]}