@buoy-gg/assets 7.0.38 → 7.0.40

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 (161) hide show
  1. package/lib/commonjs/capture/expo.js +46 -1
  2. package/lib/commonjs/capture/expo.js.map +1 -0
  3. package/lib/commonjs/capture/install.js +91 -1
  4. package/lib/commonjs/capture/install.js.map +1 -0
  5. package/lib/commonjs/capture/isBuoyAsset.js +23 -1
  6. package/lib/commonjs/capture/isBuoyAsset.js.map +1 -0
  7. package/lib/commonjs/capture/measure.js +186 -1
  8. package/lib/commonjs/capture/measure.js.map +1 -0
  9. package/lib/commonjs/capture/metroGraph.js +175 -1
  10. package/lib/commonjs/capture/metroGraph.js.map +1 -0
  11. package/lib/commonjs/capture/registry.js +127 -1
  12. package/lib/commonjs/capture/registry.js.map +1 -0
  13. package/lib/commonjs/components/AssetDetail.js +211 -1
  14. package/lib/commonjs/components/AssetDetail.js.map +1 -0
  15. package/lib/commonjs/components/AssetImage.js +66 -1
  16. package/lib/commonjs/components/AssetImage.js.map +1 -0
  17. package/lib/commonjs/components/AssetRow.js +232 -1
  18. package/lib/commonjs/components/AssetRow.js.map +1 -0
  19. package/lib/commonjs/components/AssetsFilterBar.js +105 -1
  20. package/lib/commonjs/components/AssetsFilterBar.js.map +1 -0
  21. package/lib/commonjs/components/AssetsHeader.js +73 -1
  22. package/lib/commonjs/components/AssetsHeader.js.map +1 -0
  23. package/lib/commonjs/components/AssetsIcon.js +19 -1
  24. package/lib/commonjs/components/AssetsIcon.js.map +1 -0
  25. package/lib/commonjs/components/AssetsListControls.js +81 -1
  26. package/lib/commonjs/components/AssetsListControls.js.map +1 -0
  27. package/lib/commonjs/components/AssetsModal.js +378 -1
  28. package/lib/commonjs/components/AssetsModal.js.map +1 -0
  29. package/lib/commonjs/components/ScanNotice.js +85 -1
  30. package/lib/commonjs/components/ScanNotice.js.map +1 -0
  31. package/lib/commonjs/components/optionalExpoImage.js +16 -1
  32. package/lib/commonjs/components/optionalExpoImage.js.map +1 -0
  33. package/lib/commonjs/components/optionalExpoImage.web.js +11 -1
  34. package/lib/commonjs/components/optionalExpoImage.web.js.map +1 -0
  35. package/lib/commonjs/export.js +62 -1
  36. package/lib/commonjs/export.js.map +1 -0
  37. package/lib/commonjs/format.js +59 -1
  38. package/lib/commonjs/format.js.map +1 -0
  39. package/lib/commonjs/hooks/useAssetRecords.js +22 -1
  40. package/lib/commonjs/hooks/useAssetRecords.js.map +1 -0
  41. package/lib/commonjs/hooks/useAssetScanStatus.js +28 -1
  42. package/lib/commonjs/hooks/useAssetScanStatus.js.map +1 -0
  43. package/lib/commonjs/index.js +313 -1
  44. package/lib/commonjs/index.js.map +1 -0
  45. package/lib/commonjs/preset.js +39 -1
  46. package/lib/commonjs/preset.js.map +1 -0
  47. package/lib/commonjs/remote.js +68 -1
  48. package/lib/commonjs/remote.js.map +1 -0
  49. package/lib/commonjs/state.js +51 -1
  50. package/lib/commonjs/state.js.map +1 -0
  51. package/lib/commonjs/store/assetStore.js +256 -1
  52. package/lib/commonjs/store/assetStore.js.map +1 -0
  53. package/lib/commonjs/store/baseline.js +175 -1
  54. package/lib/commonjs/store/baseline.js.map +1 -0
  55. package/lib/commonjs/store/insights.js +120 -1
  56. package/lib/commonjs/store/insights.js.map +1 -0
  57. package/lib/commonjs/sync/assetsSyncAdapter.js +157 -1
  58. package/lib/commonjs/sync/assetsSyncAdapter.js.map +1 -0
  59. package/lib/commonjs/types.js +2 -1
  60. package/lib/commonjs/types.js.map +1 -0
  61. package/lib/commonjs/utils/deviceScale.js +50 -1
  62. package/lib/commonjs/utils/deviceScale.js.map +1 -0
  63. package/lib/commonjs/utils/testIDs.js +110 -1
  64. package/lib/commonjs/utils/testIDs.js.map +1 -0
  65. package/lib/module/capture/expo.js +41 -1
  66. package/lib/module/capture/expo.js.map +1 -0
  67. package/lib/module/capture/install.js +85 -1
  68. package/lib/module/capture/install.js.map +1 -0
  69. package/lib/module/capture/isBuoyAsset.js +18 -1
  70. package/lib/module/capture/isBuoyAsset.js.map +1 -0
  71. package/lib/module/capture/measure.js +179 -1
  72. package/lib/module/capture/measure.js.map +1 -0
  73. package/lib/module/capture/metroGraph.js +168 -1
  74. package/lib/module/capture/metroGraph.js.map +1 -0
  75. package/lib/module/capture/registry.js +120 -1
  76. package/lib/module/capture/registry.js.map +1 -0
  77. package/lib/module/components/AssetDetail.js +207 -1
  78. package/lib/module/components/AssetDetail.js.map +1 -0
  79. package/lib/module/components/AssetImage.js +62 -1
  80. package/lib/module/components/AssetImage.js.map +1 -0
  81. package/lib/module/components/AssetRow.js +228 -1
  82. package/lib/module/components/AssetRow.js.map +1 -0
  83. package/lib/module/components/AssetsFilterBar.js +101 -1
  84. package/lib/module/components/AssetsFilterBar.js.map +1 -0
  85. package/lib/module/components/AssetsHeader.js +69 -1
  86. package/lib/module/components/AssetsHeader.js.map +1 -0
  87. package/lib/module/components/AssetsIcon.js +12 -1
  88. package/lib/module/components/AssetsIcon.js.map +1 -0
  89. package/lib/module/components/AssetsListControls.js +77 -1
  90. package/lib/module/components/AssetsListControls.js.map +1 -0
  91. package/lib/module/components/AssetsModal.js +373 -1
  92. package/lib/module/components/AssetsModal.js.map +1 -0
  93. package/lib/module/components/ScanNotice.js +81 -1
  94. package/lib/module/components/ScanNotice.js.map +1 -0
  95. package/lib/module/components/optionalExpoImage.js +12 -1
  96. package/lib/module/components/optionalExpoImage.js.map +1 -0
  97. package/lib/module/components/optionalExpoImage.web.js +7 -1
  98. package/lib/module/components/optionalExpoImage.web.js.map +1 -0
  99. package/lib/module/export.js +57 -1
  100. package/lib/module/export.js.map +1 -0
  101. package/lib/module/format.js +51 -1
  102. package/lib/module/format.js.map +1 -0
  103. package/lib/module/hooks/useAssetRecords.js +18 -1
  104. package/lib/module/hooks/useAssetRecords.js.map +1 -0
  105. package/lib/module/hooks/useAssetScanStatus.js +23 -1
  106. package/lib/module/hooks/useAssetScanStatus.js.map +1 -0
  107. package/lib/module/index.js +63 -1
  108. package/lib/module/index.js.map +1 -0
  109. package/lib/module/preset.js +35 -1
  110. package/lib/module/preset.js.map +1 -0
  111. package/lib/module/remote.js +61 -1
  112. package/lib/module/remote.js.map +1 -0
  113. package/lib/module/state.js +47 -1
  114. package/lib/module/state.js.map +1 -0
  115. package/lib/module/store/assetStore.js +240 -1
  116. package/lib/module/store/assetStore.js.map +1 -0
  117. package/lib/module/store/baseline.js +167 -1
  118. package/lib/module/store/baseline.js.map +1 -0
  119. package/lib/module/store/insights.js +116 -1
  120. package/lib/module/store/insights.js.map +1 -0
  121. package/lib/module/sync/assetsSyncAdapter.js +153 -1
  122. package/lib/module/sync/assetsSyncAdapter.js.map +1 -0
  123. package/lib/module/types.js +2 -1
  124. package/lib/module/types.js.map +1 -0
  125. package/lib/module/utils/deviceScale.js +46 -1
  126. package/lib/module/utils/deviceScale.js.map +1 -0
  127. package/lib/module/utils/testIDs.js +99 -1
  128. package/lib/module/utils/testIDs.js.map +1 -0
  129. package/lib/typescript/capture/expo.d.ts.map +1 -0
  130. package/lib/typescript/capture/install.d.ts.map +1 -0
  131. package/lib/typescript/capture/isBuoyAsset.d.ts.map +1 -0
  132. package/lib/typescript/capture/measure.d.ts.map +1 -0
  133. package/lib/typescript/capture/metroGraph.d.ts.map +1 -0
  134. package/lib/typescript/capture/registry.d.ts.map +1 -0
  135. package/lib/typescript/components/AssetDetail.d.ts.map +1 -0
  136. package/lib/typescript/components/AssetImage.d.ts.map +1 -0
  137. package/lib/typescript/components/AssetRow.d.ts.map +1 -0
  138. package/lib/typescript/components/AssetsFilterBar.d.ts.map +1 -0
  139. package/lib/typescript/components/AssetsHeader.d.ts.map +1 -0
  140. package/lib/typescript/components/AssetsIcon.d.ts.map +1 -0
  141. package/lib/typescript/components/AssetsListControls.d.ts.map +1 -0
  142. package/lib/typescript/components/AssetsModal.d.ts.map +1 -0
  143. package/lib/typescript/components/ScanNotice.d.ts.map +1 -0
  144. package/lib/typescript/components/optionalExpoImage.d.ts.map +1 -0
  145. package/lib/typescript/components/optionalExpoImage.web.d.ts.map +1 -0
  146. package/lib/typescript/export.d.ts.map +1 -0
  147. package/lib/typescript/format.d.ts.map +1 -0
  148. package/lib/typescript/hooks/useAssetRecords.d.ts.map +1 -0
  149. package/lib/typescript/hooks/useAssetScanStatus.d.ts.map +1 -0
  150. package/lib/typescript/index.d.ts.map +1 -0
  151. package/lib/typescript/preset.d.ts.map +1 -0
  152. package/lib/typescript/remote.d.ts.map +1 -0
  153. package/lib/typescript/state.d.ts.map +1 -0
  154. package/lib/typescript/store/assetStore.d.ts.map +1 -0
  155. package/lib/typescript/store/baseline.d.ts.map +1 -0
  156. package/lib/typescript/store/insights.d.ts.map +1 -0
  157. package/lib/typescript/sync/assetsSyncAdapter.d.ts.map +1 -0
  158. package/lib/typescript/types.d.ts.map +1 -0
  159. package/lib/typescript/utils/deviceScale.d.ts.map +1 -0
  160. package/lib/typescript/utils/testIDs.d.ts.map +1 -0
  161. package/package.json +2 -2
@@ -1 +1,179 @@
1
- "use strict";import{assetsState}from"../state";import{getSnapshot,invalidate,updateRecord}from"../store/assetStore";import{getDevServerOrigin}from"./metroGraph";const CONCURRENCY=4;export function previewURL(e){if(e.resolvedUri)return e.resolvedUri;const t=variantURLs(e);return t.length?t[0].url:null}export function displaySource(e){const t=assetsState().captureDisabled;if(!t&&null!=e.registryId)return e.registryId;const r=previewURL(e);return r?t&&!/^https?:\/\//.test(r)?null:{uri:r}:null}export function variantURLs(e){const t=e.scales.length?e.scales:[1],r=e.resolvedUri;if(r&&/^https?:\/\//.test(r)&&null!=e.resolvedScale){const n=1===e.resolvedScale?"":`@${e.resolvedScale}x`,s=`${n}.${e.type}`;if(r.includes(s)||""===n)return t.map(t=>{const a=1===t?"":`@${t}x`;return{scale:t,url:(""===n?r.replace(`.${e.type}`,`${a}.${e.type}`):r.replace(s,`${a}.${e.type}`)).replace(/ /g,"%20")}})}const n=getDevServerOrigin();return n&&e.httpServerLocation?t.map(t=>{const r=1===t?"":`@${t}x`,s=`${e.httpServerLocation}/${e.name}${r}.${e.type}`,a=s.includes("?")?"&":"?";return{scale:t,url:`${n}${s}${a}platform=${platformName()}${e.hash?`&hash=${e.hash}`:""}`.replace(/ /g,"%20")}}):[]}function platformName(){try{return require("react-native").Platform.OS}catch{return"ios"}}async function fetchSize(e){try{const t=await fetch(e,{method:"HEAD"});if(t.ok){const e=Number(t.headers.get("content-length"));if(Number.isFinite(e)&&e>0)return e}}catch{}try{const t=await fetch(e);if(!t.ok)return null;const r=await t.blob();return r.size>0?r.size:null}catch{return null}}async function measureRecord(e){const t=variantURLs(e);if(!t.length)return void updateRecord(e.id,{sizeSource:"estimate"});const r={};let n=0;for(const{scale:e,url:s}of t){const t=await fetchSize(s);null!=t&&(r[String(e)]=t,n+=t)}updateRecord(e.id,n>0?{sizesByScale:r,sizeBytes:n,sizeSource:"measured"}:{sizeSource:"estimate"})}export async function measureSizes(){const e=assetsState();if(e.measuring)return{measured:e.measuredCount,total:getSnapshot().length};const t=getSnapshot().filter(e=>"measured"!==e.sizeSource);e.measuring=!0,invalidate();try{let r=0;const n=async()=>{for(;;){const n=t[r++];if(!n)return;await measureRecord(n),e.measuredCount=getSnapshot().filter(e=>"measured"===e.sizeSource).length}};await Promise.all(Array.from({length:Math.min(4,t.length)},n))}finally{e.measuring=!1,invalidate()}return{measured:e.measuredCount,total:getSnapshot().length}}
1
+ "use strict";
2
+
3
+ /**
4
+ * Byte-size measurement.
5
+ *
6
+ * Dev only in practice: each scale variant is fetched from the Metro dev
7
+ * server (HEAD first for Content-Length, GET-blob fallback since Metro
8
+ * doesn't reliably answer HEAD) and the per-variant sizes are summed onto
9
+ * the record. Android release resource ids and iOS file:// URIs are not
10
+ * measurable from JS — those records keep `estDecodedBytes` as their only
11
+ * size signal and the UI marks them as estimates.
12
+ */
13
+
14
+ import { assetsState } from "../state";
15
+ import { getSnapshot, invalidate, updateRecord } from "../store/assetStore";
16
+ import { getDevServerOrigin } from "./metroGraph";
17
+ const CONCURRENCY = 4;
18
+
19
+ /**
20
+ * Best displayable URL for a record: the resolved runtime URI, or (dev) the
21
+ * same dev-server URL the measurement pass uses — this is what gives graph-
22
+ * only (never-loaded) images real thumbnails.
23
+ */
24
+ export function previewURL(record) {
25
+ if (record.resolvedUri) return record.resolvedUri;
26
+ const variants = variantURLs(record);
27
+ return variants.length ? variants[0].url : null;
28
+ }
29
+
30
+ /**
31
+ * Image source for thumbnails/previews. On device the NUMERIC registry id is
32
+ * preferred (resolves natively — works for Android release resource ids too).
33
+ * On dashboard mirrors that id belongs to the DEVICE's registry and rn-web
34
+ * throws "asset with ID N could not be found" — use the device's http(s)
35
+ * URL instead (the Metro dev server is reachable from the desktop).
36
+ */
37
+ export function displaySource(record) {
38
+ const mirror = assetsState().captureDisabled;
39
+ if (!mirror && record.registryId != null) return record.registryId;
40
+ const uri = previewURL(record);
41
+ if (!uri) return null;
42
+ if (mirror && !/^https?:\/\//.test(uri)) return null;
43
+ return {
44
+ uri
45
+ };
46
+ }
47
+
48
+ /** All scale-variant URLs for a record, derived without re-encoding pitfalls. */
49
+ export function variantURLs(record) {
50
+ const scales = record.scales.length ? record.scales : [1];
51
+
52
+ // Preferred: string surgery on the URL resolveAssetSource already proved
53
+ // works (handles Expo's ?unstable_path= form and monorepo rewrites).
54
+ const resolved = record.resolvedUri;
55
+ if (resolved && /^https?:\/\//.test(resolved) && record.resolvedScale != null) {
56
+ const pickedSuffix = record.resolvedScale === 1 ? "" : `@${record.resolvedScale}x`;
57
+ const marker = `${pickedSuffix}.${record.type}`;
58
+ if (resolved.includes(marker) || pickedSuffix === "") {
59
+ return scales.map(scale => {
60
+ const suffix = scale === 1 ? "" : `@${scale}x`;
61
+ const url = (pickedSuffix === "" ? resolved.replace(`.${record.type}`, `${suffix}.${record.type}`) : resolved.replace(marker, `${suffix}.${record.type}`)).replace(/ /g, "%20"); // RN's asset path builder doesn't encode spaces
62
+ return {
63
+ scale,
64
+ url
65
+ };
66
+ });
67
+ }
68
+ }
69
+
70
+ // Graph-only records: rebuild the dev-server URL the way Metro's
71
+ // AssetSourceResolver does (plain concatenation), encoding only spaces —
72
+ // full encodeURI would double-encode Expo's pre-escaped unstable_path.
73
+ const origin = getDevServerOrigin();
74
+ if (!origin || !record.httpServerLocation) return [];
75
+ return scales.map(scale => {
76
+ const suffix = scale === 1 ? "" : `@${scale}x`;
77
+ const path = `${record.httpServerLocation}/${record.name}${suffix}.${record.type}`;
78
+ const sep = path.includes("?") ? "&" : "?";
79
+ const url = `${origin}${path}${sep}platform=${platformName()}${record.hash ? `&hash=${record.hash}` : ""}`.replace(/ /g, "%20");
80
+ return {
81
+ scale,
82
+ url
83
+ };
84
+ });
85
+ }
86
+ function platformName() {
87
+ try {
88
+ return require("react-native").Platform.OS;
89
+ } catch {
90
+ return "ios";
91
+ }
92
+ }
93
+ async function fetchSize(url) {
94
+ try {
95
+ const head = await fetch(url, {
96
+ method: "HEAD"
97
+ });
98
+ if (head.ok) {
99
+ const length = Number(head.headers.get("content-length"));
100
+ if (Number.isFinite(length) && length > 0) return length;
101
+ }
102
+ } catch {
103
+ // fall through to GET
104
+ }
105
+ try {
106
+ const response = await fetch(url);
107
+ if (!response.ok) return null;
108
+ const blob = await response.blob();
109
+ return blob.size > 0 ? blob.size : null;
110
+ } catch {
111
+ return null;
112
+ }
113
+ }
114
+ async function measureRecord(record) {
115
+ const variants = variantURLs(record);
116
+ if (!variants.length) {
117
+ updateRecord(record.id, {
118
+ sizeSource: "estimate"
119
+ });
120
+ return;
121
+ }
122
+ const sizesByScale = {};
123
+ let total = 0;
124
+ for (const {
125
+ scale,
126
+ url
127
+ } of variants) {
128
+ const size = await fetchSize(url);
129
+ if (size != null) {
130
+ sizesByScale[String(scale)] = size;
131
+ total += size;
132
+ }
133
+ }
134
+ if (total > 0) {
135
+ updateRecord(record.id, {
136
+ sizesByScale,
137
+ sizeBytes: total,
138
+ sizeSource: "measured"
139
+ });
140
+ } else {
141
+ updateRecord(record.id, {
142
+ sizeSource: "estimate"
143
+ });
144
+ }
145
+ }
146
+
147
+ /** Measure every unmeasured record; safe to re-run (skips measured ones). */
148
+ export async function measureSizes() {
149
+ const s = assetsState();
150
+ if (s.measuring) return {
151
+ measured: s.measuredCount,
152
+ total: getSnapshot().length
153
+ };
154
+ const pending = getSnapshot().filter(r => r.sizeSource !== "measured");
155
+ s.measuring = true;
156
+ invalidate();
157
+ try {
158
+ let index = 0;
159
+ const worker = async () => {
160
+ for (;;) {
161
+ const next = pending[index++];
162
+ if (!next) return;
163
+ await measureRecord(next);
164
+ s.measuredCount = getSnapshot().filter(r => r.sizeSource === "measured").length;
165
+ }
166
+ };
167
+ await Promise.all(Array.from({
168
+ length: Math.min(CONCURRENCY, pending.length)
169
+ }, worker));
170
+ } finally {
171
+ s.measuring = false;
172
+ invalidate();
173
+ }
174
+ return {
175
+ measured: s.measuredCount,
176
+ total: getSnapshot().length
177
+ };
178
+ }
179
+ //# sourceMappingURL=measure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["assetsState","getSnapshot","invalidate","updateRecord","getDevServerOrigin","CONCURRENCY","previewURL","record","resolvedUri","variants","variantURLs","length","url","displaySource","mirror","captureDisabled","registryId","uri","test","scales","resolved","resolvedScale","pickedSuffix","marker","type","includes","map","scale","suffix","replace","origin","httpServerLocation","path","name","sep","platformName","hash","require","Platform","OS","fetchSize","head","fetch","method","ok","Number","headers","get","isFinite","response","blob","size","measureRecord","id","sizeSource","sizesByScale","total","String","sizeBytes","measureSizes","s","measuring","measured","measuredCount","pending","filter","r","index","worker","next","Promise","all","Array","from","Math","min"],"sourceRoot":"../../../src","sources":["capture/measure.ts"],"mappings":"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","ignoreList":[]}
@@ -1 +1,168 @@
1
- "use strict";import{assetsState}from"../state";import{assetKey,invalidate,upsertRecord}from"../store/assetStore";const GRAPH_TIMEOUT_MS=9e4;async function fetchGraphPayload(e,t){const r=new AbortController;let a;try{return await Promise.race([(async()=>{const t=await fetch(e,{signal:r.signal});if(!t.ok)throw new Error(`Metro responded ${t.status} for ${e}`);return t.json()})(),new Promise((e,n)=>{a=setTimeout(()=>{n(new Error("Asset discovery timed out. Try again.")),r.abort()},Math.max(0,t))})])}finally{clearTimeout(a)}}export function getScriptURL(){try{const{NativeModules:e}=require("react-native"),t=e?.SourceCode,r=t?.getConstants?.().scriptURL??t?.scriptURL;return"string"==typeof r?r:null}catch{return null}}export function getDevServerOrigin(){const e=getScriptURL(),t=e?.match(/^https?:\/\/[^/]+/);return t?t[0]:null}export function getGraphURLCandidates(){const e=getScriptURL();if(!e||!/^https?:\/\//.test(e))return[];const t=getDevServerOrigin(),r=e.indexOf("?"),a=r>=0?e.slice(r):"?platform=ios&dev=true",n=[];return e.includes(".bundle")&&n.push(e.replace(".bundle",".assets")),t&&n.push(`${t}/node_modules/expo-router/entry.assets${a}`,`${t}/node_modules/expo/AppEntry.assets${a}`,`${t}/index.assets${a}`),n}export async function fetchAssetGraph(){const e=assetsState(),t=getGraphURLCandidates();if(!t.length)return e.graphSupported=!1,e.graphError="No Metro dev server (embedded bundle)",invalidate(),{ok:!1,message:e.graphError};if(e.graphFetchInFlight)return{ok:!1,message:"Graph fetch already running"};e.graphFetchInFlight=!0,e.graphFetchStartedAt=Date.now(),e.graphError=null,invalidate();const r=e.graphFetchStartedAt+9e4;try{let a=null,n="";for(const e of t)try{const t=await fetchGraphPayload(e,r-Date.now());if(Array.isArray(t)){a=t;break}n="Unexpected .assets payload shape"}catch(e){if(n=String(e?.message??e),Date.now()>=r)break}if(!Array.isArray(a))throw new Error(n||"No graph endpoint answered");const s=a;let o=0;for(const e of s)e&&"string"==typeof e.name&&"string"==typeof e.type&&upsertRecord({key:assetKey(e.httpServerLocation,e.name,e.type),name:e.name,type:e.type,origin:"graph",hash:e.hash,httpServerLocation:e.httpServerLocation,width:e.width??void 0,height:e.height??void 0,scales:e.scales,fileSystemLocation:e.fileSystemLocation,files:e.files,fileHashes:e.fileHashes})&&o++;return e.graphSupported=!0,e.graphCount=o,e.graphError=null,invalidate(),{ok:!0,count:o}}catch(t){return e.graphSupported=null!=getDevServerOrigin(),e.graphError=String(t?.message??t),invalidate(),{ok:!1,message:e.graphError}}finally{e.graphFetchInFlight=!1,e.graphFetchStartedAt=null,invalidate()}}
1
+ "use strict";
2
+
3
+ /**
4
+ * Metro dev-server graph fetch.
5
+ *
6
+ * The dev server serves `<entry>.assets` next to `<entry>.bundle` — the full
7
+ * dependency graph's AssetData[], INCLUDING assets never required at runtime
8
+ * and the `fileSystemLocation`/`files` fields Metro strips from runtime
9
+ * records. Deriving the URL by swapping `.bundle` → `.assets` on the running
10
+ * bundle's scriptURL keeps the entry path and platform/dev query params
11
+ * intact for both RN CLI (index.bundle) and Expo (…/entry.bundle) layouts.
12
+ *
13
+ * Graph-only records (in the graph, not the registry) are exactly the
14
+ * "shipped but never loaded" set. Dev-only: no server, no graph.
15
+ */
16
+
17
+ import { assetsState } from "../state";
18
+ import { assetKey, invalidate, upsertRecord } from "../store/assetStore";
19
+ const GRAPH_TIMEOUT_MS = 90_000;
20
+
21
+ /** Bound the whole discovery pass, including response body reads. */
22
+ async function fetchGraphPayload(url, remainingMs) {
23
+ const controller = new AbortController();
24
+ let timer;
25
+ try {
26
+ return await Promise.race([(async () => {
27
+ const response = await fetch(url, {
28
+ signal: controller.signal
29
+ });
30
+ if (!response.ok) throw new Error(`Metro responded ${response.status} for ${url}`);
31
+ return response.json();
32
+ })(), new Promise((_, reject) => {
33
+ timer = setTimeout(() => {
34
+ reject(new Error("Asset discovery timed out. Try again."));
35
+ controller.abort();
36
+ }, Math.max(0, remainingMs));
37
+ })]);
38
+ } finally {
39
+ clearTimeout(timer);
40
+ }
41
+ }
42
+ export function getScriptURL() {
43
+ try {
44
+ const {
45
+ NativeModules
46
+ } = require("react-native");
47
+ const sourceCode = NativeModules?.SourceCode;
48
+ const url = sourceCode?.getConstants?.().scriptURL ?? sourceCode?.scriptURL;
49
+ return typeof url === "string" ? url : null;
50
+ } catch {
51
+ return null;
52
+ }
53
+ }
54
+
55
+ /** http(s) origin of the Metro dev server, or null when running embedded. */
56
+ export function getDevServerOrigin() {
57
+ const scriptURL = getScriptURL();
58
+ const match = scriptURL?.match(/^https?:\/\/[^/]+/);
59
+ return match ? match[0] : null;
60
+ }
61
+
62
+ /**
63
+ * Candidate graph URLs, most-likely first. The straight `.bundle`→`.assets`
64
+ * swap works for RN CLI, but Expo dev builds serve a VIRTUAL entry
65
+ * (.expo/.virtual-metro-entry.bundle) that only exists for .bundle requests —
66
+ * its .assets twin 404s — so the real entry modules are tried next, keeping
67
+ * the original query string (platform/dev/etc.) intact.
68
+ */
69
+ export function getGraphURLCandidates() {
70
+ const scriptURL = getScriptURL();
71
+ if (!scriptURL || !/^https?:\/\//.test(scriptURL)) return [];
72
+ const origin = getDevServerOrigin();
73
+ const queryIndex = scriptURL.indexOf("?");
74
+ const query = queryIndex >= 0 ? scriptURL.slice(queryIndex) : "?platform=ios&dev=true";
75
+ const candidates = [];
76
+ if (scriptURL.includes(".bundle")) {
77
+ candidates.push(scriptURL.replace(".bundle", ".assets"));
78
+ }
79
+ if (origin) {
80
+ candidates.push(`${origin}/node_modules/expo-router/entry.assets${query}`, `${origin}/node_modules/expo/AppEntry.assets${query}`, `${origin}/index.assets${query}`);
81
+ }
82
+ return candidates;
83
+ }
84
+
85
+ /** Fetch the full asset graph from the dev server and merge it into the store. */
86
+ export async function fetchAssetGraph() {
87
+ const s = assetsState();
88
+ const candidates = getGraphURLCandidates();
89
+ if (!candidates.length) {
90
+ s.graphSupported = false;
91
+ s.graphError = "No Metro dev server (embedded bundle)";
92
+ invalidate();
93
+ return {
94
+ ok: false,
95
+ message: s.graphError
96
+ };
97
+ }
98
+ if (s.graphFetchInFlight) return {
99
+ ok: false,
100
+ message: "Graph fetch already running"
101
+ };
102
+ s.graphFetchInFlight = true;
103
+ s.graphFetchStartedAt = Date.now();
104
+ s.graphError = null;
105
+ invalidate();
106
+ const deadline = s.graphFetchStartedAt + GRAPH_TIMEOUT_MS;
107
+ try {
108
+ let data = null;
109
+ let lastError = "";
110
+ for (const url of candidates) {
111
+ try {
112
+ const parsed = await fetchGraphPayload(url, deadline - Date.now());
113
+ if (Array.isArray(parsed)) {
114
+ data = parsed;
115
+ break;
116
+ }
117
+ lastError = "Unexpected .assets payload shape";
118
+ } catch (error) {
119
+ lastError = String(error?.message ?? error);
120
+ if (Date.now() >= deadline) break;
121
+ }
122
+ }
123
+ if (!Array.isArray(data)) throw new Error(lastError || "No graph endpoint answered");
124
+ const graph = data;
125
+ let count = 0;
126
+ for (const asset of graph) {
127
+ if (!asset || typeof asset.name !== "string" || typeof asset.type !== "string") {
128
+ continue;
129
+ }
130
+ const record = upsertRecord({
131
+ key: assetKey(asset.httpServerLocation, asset.name, asset.type),
132
+ name: asset.name,
133
+ type: asset.type,
134
+ origin: "graph",
135
+ hash: asset.hash,
136
+ httpServerLocation: asset.httpServerLocation,
137
+ width: asset.width ?? undefined,
138
+ height: asset.height ?? undefined,
139
+ scales: asset.scales,
140
+ fileSystemLocation: asset.fileSystemLocation,
141
+ files: asset.files,
142
+ fileHashes: asset.fileHashes
143
+ });
144
+ if (record) count++;
145
+ }
146
+ s.graphSupported = true;
147
+ s.graphCount = count;
148
+ s.graphError = null;
149
+ invalidate();
150
+ return {
151
+ ok: true,
152
+ count
153
+ };
154
+ } catch (error) {
155
+ s.graphSupported = getDevServerOrigin() != null;
156
+ s.graphError = String(error?.message ?? error);
157
+ invalidate();
158
+ return {
159
+ ok: false,
160
+ message: s.graphError
161
+ };
162
+ } finally {
163
+ s.graphFetchInFlight = false;
164
+ s.graphFetchStartedAt = null;
165
+ invalidate();
166
+ }
167
+ }
168
+ //# sourceMappingURL=metroGraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["assetsState","assetKey","invalidate","upsertRecord","GRAPH_TIMEOUT_MS","fetchGraphPayload","url","remainingMs","controller","AbortController","timer","Promise","race","response","fetch","signal","ok","Error","status","json","_","reject","setTimeout","abort","Math","max","clearTimeout","getScriptURL","NativeModules","require","sourceCode","SourceCode","getConstants","scriptURL","getDevServerOrigin","match","getGraphURLCandidates","test","origin","queryIndex","indexOf","query","slice","candidates","includes","push","replace","fetchAssetGraph","s","length","graphSupported","graphError","message","graphFetchInFlight","graphFetchStartedAt","Date","now","deadline","data","lastError","parsed","Array","isArray","error","String","graph","count","asset","name","type","record","key","httpServerLocation","hash","width","undefined","height","scales","fileSystemLocation","files","fileHashes","graphCount"],"sourceRoot":"../../../src","sources":["capture/metroGraph.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,WAAW,QAAQ,UAAU;AACtC,SAASC,QAAQ,EAAEC,UAAU,EAAEC,YAAY,QAAQ,qBAAqB;AAExE,MAAMC,gBAAgB,GAAG,MAAM;;AAE/B;AACA,eAAeC,iBAAiBA,CAACC,GAAW,EAAEC,WAAmB,EAAoB;EACnF,MAAMC,UAAU,GAAG,IAAIC,eAAe,CAAC,CAAC;EACxC,IAAIC,KAAgD;EACpD,IAAI;IACF,OAAO,MAAMC,OAAO,CAACC,IAAI,CAAC,CACxB,CAAC,YAAY;MACX,MAAMC,QAAQ,GAAG,MAAMC,KAAK,CAACR,GAAG,EAAE;QAAES,MAAM,EAAEP,UAAU,CAACO;MAAO,CAAC,CAAC;MAChE,IAAI,CAACF,QAAQ,CAACG,EAAE,EAAE,MAAM,IAAIC,KAAK,CAAC,mBAAmBJ,QAAQ,CAACK,MAAM,QAAQZ,GAAG,EAAE,CAAC;MAClF,OAAOO,QAAQ,CAACM,IAAI,CAAC,CAAC;IACxB,CAAC,EAAE,CAAC,EACJ,IAAIR,OAAO,CAAQ,CAACS,CAAC,EAAEC,MAAM,KAAK;MAChCX,KAAK,GAAGY,UAAU,CAAC,MAAM;QACvBD,MAAM,CAAC,IAAIJ,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC1DT,UAAU,CAACe,KAAK,CAAC,CAAC;MACpB,CAAC,EAAEC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAElB,WAAW,CAAC,CAAC;IAC9B,CAAC,CAAC,CACH,CAAC;EACJ,CAAC,SAAS;IACRmB,YAAY,CAAChB,KAAK,CAAC;EACrB;AACF;AAgBA,OAAO,SAASiB,YAAYA,CAAA,EAAkB;EAC5C,IAAI;IACF,MAAM;MAAEC;IAAc,CAAC,GAAGC,OAAO,CAAC,cAAc,CAAC;IACjD,MAAMC,UAAU,GAAGF,aAAa,EAAEG,UAAU;IAC5C,MAAMzB,GAAY,GAChBwB,UAAU,EAAEE,YAAY,GAAG,CAAC,CAACC,SAAS,IAAIH,UAAU,EAAEG,SAAS;IACjE,OAAO,OAAO3B,GAAG,KAAK,QAAQ,GAAGA,GAAG,GAAG,IAAI;EAC7C,CAAC,CAAC,MAAM;IACN,OAAO,IAAI;EACb;AACF;;AAEA;AACA,OAAO,SAAS4B,kBAAkBA,CAAA,EAAkB;EAClD,MAAMD,SAAS,GAAGN,YAAY,CAAC,CAAC;EAChC,MAAMQ,KAAK,GAAGF,SAAS,EAAEE,KAAK,CAAC,mBAAmB,CAAC;EACnD,OAAOA,KAAK,GAAGA,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;AAChC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAAA,EAAa;EAChD,MAAMH,SAAS,GAAGN,YAAY,CAAC,CAAC;EAChC,IAAI,CAACM,SAAS,IAAI,CAAC,cAAc,CAACI,IAAI,CAACJ,SAAS,CAAC,EAAE,OAAO,EAAE;EAC5D,MAAMK,MAAM,GAAGJ,kBAAkB,CAAC,CAAC;EACnC,MAAMK,UAAU,GAAGN,SAAS,CAACO,OAAO,CAAC,GAAG,CAAC;EACzC,MAAMC,KAAK,GAAGF,UAAU,IAAI,CAAC,GAAGN,SAAS,CAACS,KAAK,CAACH,UAAU,CAAC,GAAG,wBAAwB;EACtF,MAAMI,UAAoB,GAAG,EAAE;EAC/B,IAAIV,SAAS,CAACW,QAAQ,CAAC,SAAS,CAAC,EAAE;IACjCD,UAAU,CAACE,IAAI,CAACZ,SAAS,CAACa,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;EAC1D;EACA,IAAIR,MAAM,EAAE;IACVK,UAAU,CAACE,IAAI,CACb,GAAGP,MAAM,yCAAyCG,KAAK,EAAE,EACzD,GAAGH,MAAM,qCAAqCG,KAAK,EAAE,EACrD,GAAGH,MAAM,gBAAgBG,KAAK,EAChC,CAAC;EACH;EACA,OAAOE,UAAU;AACnB;;AAEA;AACA,OAAO,eAAeI,eAAeA,CAAA,EAEnC;EACA,MAAMC,CAAC,GAAGhD,WAAW,CAAC,CAAC;EACvB,MAAM2C,UAAU,GAAGP,qBAAqB,CAAC,CAAC;EAC1C,IAAI,CAACO,UAAU,CAACM,MAAM,EAAE;IACtBD,CAAC,CAACE,cAAc,GAAG,KAAK;IACxBF,CAAC,CAACG,UAAU,GAAG,uCAAuC;IACtDjD,UAAU,CAAC,CAAC;IACZ,OAAO;MAAEc,EAAE,EAAE,KAAK;MAAEoC,OAAO,EAAEJ,CAAC,CAACG;IAAW,CAAC;EAC7C;EACA,IAAIH,CAAC,CAACK,kBAAkB,EAAE,OAAO;IAAErC,EAAE,EAAE,KAAK;IAAEoC,OAAO,EAAE;EAA8B,CAAC;EACtFJ,CAAC,CAACK,kBAAkB,GAAG,IAAI;EAC3BL,CAAC,CAACM,mBAAmB,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC;EAClCR,CAAC,CAACG,UAAU,GAAG,IAAI;EACnBjD,UAAU,CAAC,CAAC;EACZ,MAAMuD,QAAQ,GAAGT,CAAC,CAACM,mBAAmB,GAAGlD,gBAAgB;EACzD,IAAI;IACF,IAAIsD,IAAa,GAAG,IAAI;IACxB,IAAIC,SAAS,GAAG,EAAE;IAClB,KAAK,MAAMrD,GAAG,IAAIqC,UAAU,EAAE;MAC5B,IAAI;QACF,MAAMiB,MAAM,GAAG,MAAMvD,iBAAiB,CAACC,GAAG,EAAEmD,QAAQ,GAAGF,IAAI,CAACC,GAAG,CAAC,CAAC,CAAC;QAClE,IAAIK,KAAK,CAACC,OAAO,CAACF,MAAM,CAAC,EAAE;UACzBF,IAAI,GAAGE,MAAM;UACb;QACF;QACAD,SAAS,GAAG,kCAAkC;MAChD,CAAC,CAAC,OAAOI,KAAK,EAAE;QACdJ,SAAS,GAAGK,MAAM,CAAED,KAAK,EAAYX,OAAO,IAAIW,KAAK,CAAC;QACtD,IAAIR,IAAI,CAACC,GAAG,CAAC,CAAC,IAAIC,QAAQ,EAAE;MAC9B;IACF;IACA,IAAI,CAACI,KAAK,CAACC,OAAO,CAACJ,IAAI,CAAC,EAAE,MAAM,IAAIzC,KAAK,CAAC0C,SAAS,IAAI,4BAA4B,CAAC;IACpF,MAAMM,KAAK,GAAGP,IAAwB;IACtC,IAAIQ,KAAK,GAAG,CAAC;IACb,KAAK,MAAMC,KAAK,IAAIF,KAAK,EAAE;MACzB,IAAI,CAACE,KAAK,IAAI,OAAOA,KAAK,CAACC,IAAI,KAAK,QAAQ,IAAI,OAAOD,KAAK,CAACE,IAAI,KAAK,QAAQ,EAAE;QAC9E;MACF;MACA,MAAMC,MAAM,GAAGnE,YAAY,CAAC;QAC1BoE,GAAG,EAAEtE,QAAQ,CAACkE,KAAK,CAACK,kBAAkB,EAAEL,KAAK,CAACC,IAAI,EAAED,KAAK,CAACE,IAAI,CAAC;QAC/DD,IAAI,EAAED,KAAK,CAACC,IAAI;QAChBC,IAAI,EAAEF,KAAK,CAACE,IAAI;QAChB/B,MAAM,EAAE,OAAO;QACfmC,IAAI,EAAEN,KAAK,CAACM,IAAI;QAChBD,kBAAkB,EAAEL,KAAK,CAACK,kBAAkB;QAC5CE,KAAK,EAAEP,KAAK,CAACO,KAAK,IAAIC,SAAS;QAC/BC,MAAM,EAAET,KAAK,CAACS,MAAM,IAAID,SAAS;QACjCE,MAAM,EAAEV,KAAK,CAACU,MAAM;QACpBC,kBAAkB,EAAEX,KAAK,CAACW,kBAAkB;QAC5CC,KAAK,EAAEZ,KAAK,CAACY,KAAK;QAClBC,UAAU,EAAEb,KAAK,CAACa;MACpB,CAAC,CAAC;MACF,IAAIV,MAAM,EAAEJ,KAAK,EAAE;IACrB;IACAlB,CAAC,CAACE,cAAc,GAAG,IAAI;IACvBF,CAAC,CAACiC,UAAU,GAAGf,KAAK;IACpBlB,CAAC,CAACG,UAAU,GAAG,IAAI;IACnBjD,UAAU,CAAC,CAAC;IACZ,OAAO;MAAEc,EAAE,EAAE,IAAI;MAAEkD;IAAM,CAAC;EAC5B,CAAC,CAAC,OAAOH,KAAK,EAAE;IACdf,CAAC,CAACE,cAAc,GAAGhB,kBAAkB,CAAC,CAAC,IAAI,IAAI;IAC/Cc,CAAC,CAACG,UAAU,GAAGa,MAAM,CAAED,KAAK,EAAYX,OAAO,IAAIW,KAAK,CAAC;IACzD7D,UAAU,CAAC,CAAC;IACZ,OAAO;MAAEc,EAAE,EAAE,KAAK;MAAEoC,OAAO,EAAEJ,CAAC,CAACG;IAAW,CAAC;EAC7C,CAAC,SAAS;IACRH,CAAC,CAACK,kBAAkB,GAAG,KAAK;IAC5BL,CAAC,CAACM,mBAAmB,GAAG,IAAI;IAC5BpD,UAAU,CAAC,CAAC;EACd;AACF","ignoreList":[]}
@@ -1 +1,120 @@
1
- "use strict";import{upsertRecord,assetKey}from"../store/assetStore";let cachedRegistry;export function getRegistryModule(){if(void 0!==cachedRegistry)return cachedRegistry;let e=null;try{e=require("@react-native/assets-registry/registry")}catch{try{e=require("react-native/Libraries/Image/AssetRegistry")}catch{e=null}}return cachedRegistry=e&&"function"==typeof e.getAssetByID?e:null,cachedRegistry}export function resolveRegistryAsset(e){try{const{Image:t}=require("react-native"),r=t.resolveAssetSource(e);if(r&&"string"==typeof r.uri)return{uri:r.uri,scale:r.scale??1}}catch{}return null}export function upsertFromPackagerAsset(e,t){const r=resolveRegistryAsset(e);return upsertRecord({key:assetKey(t.httpServerLocation,t.name,t.type),name:t.name,type:t.type,origin:"registry",registryId:e,hash:t.hash,httpServerLocation:t.httpServerLocation,width:t.width??void 0,height:t.height??void 0,scales:t.scales,resolvedUri:r?.uri,resolvedScale:r?.scale,loaded:!0})}export function walkRegistry(){const e=getRegistryModule();if(!e)return 0;let t=0;for(;;){const r=e.getAssetByID(t+1);if(!r)break;t++,upsertFromPackagerAsset(t,r)}return t}const PATCH_MARKER="__buoyAssetsPatched";export function patchRegisterAsset(){const e=getRegistryModule();if(!e)return!1;const t=e.registerAsset;if(t[PATCH_MARKER])return!0;const r=r=>{const s=t.call(e,r);try{upsertFromPackagerAsset(s,r)}catch{}return s};r[PATCH_MARKER]=!0;try{e.registerAsset=r}catch{return!1}return!0}
1
+ "use strict";
2
+
3
+ /**
4
+ * Runtime access to @react-native/assets-registry.
5
+ *
6
+ * Asset ids are contiguous 1..N (`assets.push` return value), so a plain
7
+ * getAssetByID walk enumerates every asset registered so far — including
8
+ * everything registered BEFORE this tool was evaluated. That's why, unlike
9
+ * the images tool, there is no "must be the first import" requirement here:
10
+ * the walk backfills whatever the patch missed.
11
+ *
12
+ * registerAsset is patched (plain non-frozen CommonJS export, looked up at
13
+ * call time by Metro's generated asset modules) purely for LIVE updates as
14
+ * lazily-required assets register later.
15
+ */
16
+
17
+ import { upsertRecord, assetKey } from "../store/assetStore";
18
+
19
+ /** Runtime shape of a registry entry (fileSystemLocation/files are stripped by Metro). */
20
+
21
+ let cachedRegistry;
22
+ export function getRegistryModule() {
23
+ if (cachedRegistry !== undefined) return cachedRegistry;
24
+ let mod = null;
25
+ try {
26
+ mod = require("@react-native/assets-registry/registry");
27
+ } catch {
28
+ // Old RN layouts (< 0.72) don't ship @react-native/assets-registry as a
29
+ // resolvable package — the registry only exists at this deep path. RN's
30
+ // deep-import deprecation warning fires when this executes, but it only
31
+ // executes on those old layouts, where there is no other way in.
32
+ try {
33
+ mod = require("react-native/Libraries/Image/AssetRegistry");
34
+ } catch {
35
+ mod = null;
36
+ }
37
+ }
38
+ cachedRegistry = mod && typeof mod.getAssetByID === "function" ? mod : null;
39
+ return cachedRegistry;
40
+ }
41
+
42
+ /** resolveAssetSource(id) → this environment's URI (dev URL / file:// / res id). */
43
+ export function resolveRegistryAsset(registryId) {
44
+ try {
45
+ const {
46
+ Image
47
+ } = require("react-native");
48
+ const resolved = Image.resolveAssetSource(registryId);
49
+ if (resolved && typeof resolved.uri === "string") {
50
+ return {
51
+ uri: resolved.uri,
52
+ scale: resolved.scale ?? 1
53
+ };
54
+ }
55
+ } catch {
56
+ // resolution is enrichment — never let it break the walk
57
+ }
58
+ return null;
59
+ }
60
+ export function upsertFromPackagerAsset(registryId, asset) {
61
+ const resolved = resolveRegistryAsset(registryId);
62
+ return upsertRecord({
63
+ key: assetKey(asset.httpServerLocation, asset.name, asset.type),
64
+ name: asset.name,
65
+ type: asset.type,
66
+ origin: "registry",
67
+ registryId,
68
+ hash: asset.hash,
69
+ httpServerLocation: asset.httpServerLocation,
70
+ width: asset.width ?? undefined,
71
+ height: asset.height ?? undefined,
72
+ scales: asset.scales,
73
+ resolvedUri: resolved?.uri,
74
+ resolvedScale: resolved?.scale,
75
+ loaded: true
76
+ });
77
+ }
78
+
79
+ /** Enumerate every asset registered so far. Returns the highest id seen. */
80
+ export function walkRegistry() {
81
+ const registry = getRegistryModule();
82
+ if (!registry) return 0;
83
+ let id = 0;
84
+ for (;;) {
85
+ const asset = registry.getAssetByID(id + 1);
86
+ if (!asset) break;
87
+ id++;
88
+ upsertFromPackagerAsset(id, asset);
89
+ }
90
+ return id;
91
+ }
92
+ const PATCH_MARKER = "__buoyAssetsPatched";
93
+
94
+ /**
95
+ * Wrap registerAsset so future registrations stream in live. Safe to call
96
+ * more than once (marker guard); the walk covers anything registered before.
97
+ */
98
+ export function patchRegisterAsset() {
99
+ const registry = getRegistryModule();
100
+ if (!registry) return false;
101
+ const original = registry.registerAsset;
102
+ if (original[PATCH_MARKER]) return true;
103
+ const wrapped = asset => {
104
+ const id = original.call(registry, asset);
105
+ try {
106
+ upsertFromPackagerAsset(id, asset);
107
+ } catch {
108
+ // never break app asset registration
109
+ }
110
+ return id;
111
+ };
112
+ wrapped[PATCH_MARKER] = true;
113
+ try {
114
+ registry.registerAsset = wrapped;
115
+ } catch {
116
+ return false;
117
+ }
118
+ return true;
119
+ }
120
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["upsertRecord","assetKey","cachedRegistry","getRegistryModule","undefined","mod","require","getAssetByID","resolveRegistryAsset","registryId","Image","resolved","resolveAssetSource","uri","scale","upsertFromPackagerAsset","asset","key","httpServerLocation","name","type","origin","hash","width","height","scales","resolvedUri","resolvedScale","loaded","walkRegistry","registry","id","PATCH_MARKER","patchRegisterAsset","original","registerAsset","wrapped","call"],"sourceRoot":"../../../src","sources":["capture/registry.ts"],"mappings":"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","ignoreList":[]}