react-native-bspatch 3.0.6 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/lib/commonjs/index.js +11 -14
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ota/OtaProvider.js +1 -12
- package/lib/commonjs/ota/OtaProvider.js.map +1 -1
- package/lib/commonjs/ota/otaCore.js +62 -95
- package/lib/commonjs/ota/otaCore.js.map +1 -1
- package/lib/module/index.js +8 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/ota/OtaProvider.js +1 -12
- package/lib/module/ota/OtaProvider.js.map +1 -1
- package/lib/module/ota/otaCore.js +62 -95
- package/lib/module/ota/otaCore.js.map +1 -1
- package/lib/typescript/index.d.ts +7 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/ota/OtaProvider.d.ts.map +1 -1
- package/lib/typescript/ota/otaCore.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +8 -1
- package/src/ota/OtaProvider.tsx +1 -12
- package/src/ota/otaCore.ts +64 -134
- package/lib/commonjs/ota/otaAssetResolver.js +0 -141
- package/lib/commonjs/ota/otaAssetResolver.js.map +0 -1
- package/lib/module/ota/otaAssetResolver.js +0 -134
- package/lib/module/ota/otaAssetResolver.js.map +0 -1
- package/lib/typescript/ota/otaAssetResolver.d.ts +0 -15
- package/lib/typescript/ota/otaAssetResolver.d.ts.map +0 -1
- package/src/ota/otaAssetResolver.ts +0 -179
package/src/ota/otaCore.ts
CHANGED
|
@@ -206,14 +206,18 @@ export const fetchOtaManifest = (config: OtaConfig): Promise<OtaPatch[]> =>
|
|
|
206
206
|
|
|
207
207
|
const ASSET_STORE_DIR = `${ReactNativeBlobUtil.fs.dirs.DocumentDir}/ota/assets`;
|
|
208
208
|
|
|
209
|
+
/** Relative path inside the version dir: no absolute paths, no `..` segments. */
|
|
210
|
+
const isSafeRelativePath = (p: string): boolean =>
|
|
211
|
+
/^[A-Za-z0-9_\-.@/]+$/.test(p) && !p.startsWith('/') && !p.split('/').includes('..');
|
|
212
|
+
|
|
209
213
|
/**
|
|
210
|
-
* Downloads
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
214
|
+
* Downloads this version's assets and places each one next to the bundle, at the
|
|
215
|
+
* path React Native resolves by default for a bundle loaded from a file:
|
|
216
|
+
* Android: ota/vN/drawable-xxhdpi/foo.png, ota/vN/raw/bar.glb
|
|
217
|
+
* iOS: ota/vN/assets/src/images/foo@2x.png
|
|
218
|
+
* So images resolve correctly from the very first render, with no JS source
|
|
219
|
+
* transformer (which raced the first render). Files are fetched once per content
|
|
220
|
+
* hash into ota/assets/ and copied from there for later versions.
|
|
217
221
|
*/
|
|
218
222
|
const downloadAndSyncAssets = async (
|
|
219
223
|
assetManifestUrl: string,
|
|
@@ -227,168 +231,94 @@ const downloadAndSyncAssets = async (
|
|
|
227
231
|
) => void,
|
|
228
232
|
onProgress: (percent: number) => void,
|
|
229
233
|
): Promise<void> => {
|
|
234
|
+
const fs = ReactNativeBlobUtil.fs;
|
|
230
235
|
onStatus(OtaStatus.SYNCING_ASSETS, 'Syncing assets...');
|
|
231
|
-
|
|
232
236
|
const versionDir = `${OTA_DIR}/v${version}`;
|
|
233
|
-
const manifestPath = `${versionDir}/asset-manifest-v${version}.json`;
|
|
234
237
|
|
|
235
|
-
// Ensure asset store dir exists
|
|
236
|
-
if (!(await ReactNativeBlobUtil.fs.exists(ASSET_STORE_DIR))) {
|
|
237
|
-
await ReactNativeBlobUtil.fs.mkdir(ASSET_STORE_DIR);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Fetch the asset manifest
|
|
241
238
|
let assets: OtaAsset[] = [];
|
|
242
239
|
try {
|
|
243
|
-
if (__DEV__) {
|
|
244
|
-
console.log(
|
|
245
|
-
`[otaCore] Fetching asset manifest from: ${assetManifestUrl}`,
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
240
|
const resp = await ReactNativeBlobUtil.config({
|
|
249
241
|
followRedirect: true,
|
|
250
242
|
timeout: 10000,
|
|
251
|
-
}).fetch('GET', assetManifestUrl, {
|
|
252
|
-
'Cache-Control': 'no-cache',
|
|
253
|
-
});
|
|
254
|
-
|
|
243
|
+
}).fetch('GET', assetManifestUrl, { 'Cache-Control': 'no-cache' });
|
|
255
244
|
if (resp.respInfo.status !== 200) {
|
|
256
|
-
throw new Error(
|
|
257
|
-
`Manifest fetch failed with status ${resp.respInfo.status}`,
|
|
258
|
-
);
|
|
245
|
+
throw new Error(`status ${resp.respInfo.status}`);
|
|
259
246
|
}
|
|
260
|
-
|
|
261
|
-
//
|
|
262
|
-
if (!(await ReactNativeBlobUtil.fs.exists(versionDir))) {
|
|
263
|
-
await ReactNativeBlobUtil.fs.mkdir(versionDir);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const manifestData =
|
|
267
|
-
typeof resp.data === 'string'
|
|
268
|
-
? resp.data
|
|
269
|
-
: JSON.stringify(resp.data);
|
|
270
|
-
await ReactNativeBlobUtil.fs.writeFile(
|
|
271
|
-
manifestPath,
|
|
272
|
-
manifestData,
|
|
273
|
-
'utf8',
|
|
274
|
-
);
|
|
275
|
-
if (__DEV__) {
|
|
276
|
-
console.log(`[otaCore] Saved asset manifest to: ${manifestPath}`);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const manifest = JSON.parse(manifestData);
|
|
280
|
-
// Hash/ext become file names: reject anything that isn't a plain sha256 + extension
|
|
247
|
+
const manifest = typeof resp.data === 'string' ? JSON.parse(resp.data) : resp.data;
|
|
248
|
+
// Hash/ext/path become file names: reject anything unexpected
|
|
281
249
|
assets = (manifest.assets || []).filter(
|
|
282
250
|
(a: any) =>
|
|
283
251
|
/^[a-f0-9]{64}$/i.test(a.hash) &&
|
|
284
|
-
/^[a-z0-9]+$/i.test(a.ext)
|
|
252
|
+
/^[a-z0-9]+$/i.test(a.ext) &&
|
|
253
|
+
typeof a.originalPath === 'string' &&
|
|
254
|
+
isSafeRelativePath(a.originalPath),
|
|
285
255
|
);
|
|
286
256
|
} catch (e) {
|
|
287
|
-
// Fatal: activating the bundle without its
|
|
257
|
+
// Fatal: activating the bundle without its assets leaves images blank
|
|
288
258
|
throw new Error(`Failed to fetch asset manifest: ${(e as Error).message}`);
|
|
289
259
|
}
|
|
260
|
+
if (assets.length === 0) return;
|
|
290
261
|
|
|
291
|
-
if (assets.length === 0) {
|
|
292
|
-
if (__DEV__) {
|
|
293
|
-
console.log('[otaCore] No new assets to sync for this version.');
|
|
294
|
-
}
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Only notify UI now that we actually have assets to download
|
|
299
262
|
onStatus(OtaStatus.SYNCING_ASSETS, `Syncing ${assets.length} asset(s)...`);
|
|
263
|
+
// One promise per dir: parallel workers would otherwise race mkdir (EEXIST)
|
|
264
|
+
const dirs = new Map<string, Promise<void>>();
|
|
265
|
+
const ensureDir = (dir: string): Promise<void> => {
|
|
266
|
+
if (!dirs.has(dir)) {
|
|
267
|
+
dirs.set(dir, fs.exists(dir).then(ok => (ok ? undefined : fs.mkdir(dir))));
|
|
268
|
+
}
|
|
269
|
+
return dirs.get(dir)!;
|
|
270
|
+
};
|
|
271
|
+
await ensureDir(ASSET_STORE_DIR);
|
|
300
272
|
|
|
301
273
|
let processed = 0;
|
|
302
274
|
let downloaded = 0;
|
|
303
|
-
let cached = 0;
|
|
304
275
|
let failed = 0;
|
|
305
|
-
|
|
306
|
-
const updateProgress = () => {
|
|
307
|
-
processed++;
|
|
308
|
-
const percent = Math.round((processed / assets.length) * 100);
|
|
309
|
-
onProgress(percent);
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
// Concurrency-limited download queue
|
|
313
|
-
const maxConcurrency = 6; // Optimal for most mobile networks
|
|
314
276
|
let index = 0;
|
|
315
277
|
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
// Download missing asset
|
|
332
|
-
onStatus(
|
|
333
|
-
OtaStatus.SYNCING_ASSETS,
|
|
334
|
-
`Syncing assets (${processed + 1}/${assets.length})...`,
|
|
335
|
-
);
|
|
336
|
-
try {
|
|
337
|
-
const storage = getStorage(config);
|
|
338
|
-
const assetUrl = await storage.getAssetUrl(
|
|
339
|
-
asset.hash,
|
|
340
|
-
asset.ext,
|
|
341
|
-
config,
|
|
342
|
-
);
|
|
343
|
-
if (!assetUrl) {
|
|
344
|
-
if (__DEV__) {
|
|
345
|
-
console.warn(
|
|
346
|
-
`[otaCore] Could not get URL for asset ${filename}`,
|
|
347
|
-
);
|
|
278
|
+
const worker = async (): Promise<void> => {
|
|
279
|
+
while (index < assets.length) {
|
|
280
|
+
const asset = assets[index++];
|
|
281
|
+
const storePath = getLocalAssetPath(asset.hash, asset.ext);
|
|
282
|
+
try {
|
|
283
|
+
if (!(await fs.exists(storePath))) {
|
|
284
|
+
const url = await getStorage(config).getAssetUrl(asset.hash, asset.ext, config);
|
|
285
|
+
if (!url) throw new Error('no URL');
|
|
286
|
+
await downloadWithRetry(url, storePath, config, () => {});
|
|
287
|
+
if (!(await verifyHash(storePath, asset.hash))) {
|
|
288
|
+
await fs.unlink(storePath).catch(() => {});
|
|
289
|
+
throw new Error('hash mismatch');
|
|
290
|
+
}
|
|
291
|
+
downloaded++;
|
|
348
292
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
await
|
|
353
|
-
throw new Error('hash mismatch');
|
|
293
|
+
const dest = `${versionDir}/${asset.originalPath}`;
|
|
294
|
+
const parts = asset.originalPath.split('/').slice(0, -1);
|
|
295
|
+
for (let i = 1; i <= parts.length; i++) {
|
|
296
|
+
await ensureDir(`${versionDir}/${parts.slice(0, i).join('/')}`);
|
|
354
297
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
console.warn(
|
|
363
|
-
`[otaCore] Failed to download asset ${filename}:`,
|
|
364
|
-
e,
|
|
365
|
-
);
|
|
298
|
+
if (await fs.exists(dest)) await fs.unlink(dest);
|
|
299
|
+
await fs.cp(storePath, dest);
|
|
300
|
+
} catch (e) {
|
|
301
|
+
if (__DEV__) {
|
|
302
|
+
console.warn(`[otaCore] Asset ${asset.originalPath} failed:`, e);
|
|
303
|
+
}
|
|
304
|
+
failed++; // keep going, fail the sync at the end
|
|
366
305
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
updateProgress();
|
|
370
|
-
await downloadNext(); // Start next download
|
|
306
|
+
processed++;
|
|
307
|
+
onProgress(Math.round((processed / assets.length) * 100));
|
|
371
308
|
}
|
|
372
309
|
};
|
|
373
310
|
|
|
374
|
-
//
|
|
375
|
-
|
|
376
|
-
const workers = Array(initialWorkers)
|
|
377
|
-
.fill(null)
|
|
378
|
-
.map(() => downloadNext());
|
|
379
|
-
await Promise.all(workers);
|
|
311
|
+
// Concurrency-limited queue: 6 parallel requests suit most mobile networks
|
|
312
|
+
await Promise.all(Array.from({ length: Math.min(6, assets.length) }, worker));
|
|
380
313
|
|
|
381
314
|
if (failed > 0) {
|
|
382
315
|
throw new Error(`${failed} asset(s) failed to download`);
|
|
383
316
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
);
|
|
389
|
-
console.log(
|
|
390
|
-
`[otaCore] Assets: ${downloaded} downloaded, ${cached} from cache`,
|
|
391
|
-
);
|
|
317
|
+
log.emit(OtaEvent.DOWNLOAD_SUCCESS, {
|
|
318
|
+
version,
|
|
319
|
+
message: `Assets: ${assets.length} placed, ${downloaded} downloaded`,
|
|
320
|
+
});
|
|
321
|
+
onStatus(OtaStatus.SYNCING_ASSETS, `Assets synced (${downloaded} new)`);
|
|
392
322
|
};
|
|
393
323
|
|
|
394
324
|
/**
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.resetOtaAssetResolver = exports.initOtaAssetResolver = void 0;
|
|
7
|
-
var _reactNative = require("react-native");
|
|
8
|
-
var _reactNativeBlobUtil = _interopRequireDefault(require("react-native-blob-util"));
|
|
9
|
-
var _NativeBsPatch = _interopRequireDefault(require("../NativeBsPatch"));
|
|
10
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
-
const ASSET_STORE_DIR = `${_reactNativeBlobUtil.default.fs.dirs.DocumentDir}/ota/assets`;
|
|
12
|
-
let assetManifest = null;
|
|
13
|
-
let assetMap = new Map();
|
|
14
|
-
let assetList = [];
|
|
15
|
-
let assetLookupCache = new Map();
|
|
16
|
-
let isPatched = false;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Internal logger with native bridge integration.
|
|
20
|
-
*/
|
|
21
|
-
const log = msg => {
|
|
22
|
-
const formatted = `[otaAssetResolver] ${msg}`;
|
|
23
|
-
console.log(formatted);
|
|
24
|
-
if (_NativeBsPatch.default?.logNative) {
|
|
25
|
-
_NativeBsPatch.default.logNative(formatted);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Initializes the OTA asset resolver for a specific version.
|
|
31
|
-
* Loads the asset manifest and prepares an O(1) lookup map for intercepted image requests.
|
|
32
|
-
*
|
|
33
|
-
* @param version - The OTA version number to load assets from.
|
|
34
|
-
*/
|
|
35
|
-
const initOtaAssetResolver = async version => {
|
|
36
|
-
const otaDir = `${_reactNativeBlobUtil.default.fs.dirs.DocumentDir}/ota`;
|
|
37
|
-
const versionDir = `${otaDir}/v${version}`;
|
|
38
|
-
const manifestPath = `${versionDir}/asset-manifest-v${version}.json`;
|
|
39
|
-
try {
|
|
40
|
-
if (await _reactNativeBlobUtil.default.fs.exists(manifestPath)) {
|
|
41
|
-
const content = await _reactNativeBlobUtil.default.fs.readFile(manifestPath, 'utf8');
|
|
42
|
-
assetManifest = JSON.parse(content);
|
|
43
|
-
|
|
44
|
-
// Pre-compute normalized paths for O(1) lookup to prevent JS thread blocking during render
|
|
45
|
-
const map = new Map();
|
|
46
|
-
const list = assetManifest.assets || [];
|
|
47
|
-
list.forEach(a => {
|
|
48
|
-
const normPath = a.originalPath.toLowerCase().replace(/\//g, '_').replace(/^(assets_)+/, '');
|
|
49
|
-
a._normPath = normPath; // cache for fast fallback
|
|
50
|
-
map.set(normPath, a);
|
|
51
|
-
});
|
|
52
|
-
assetMap = map;
|
|
53
|
-
assetList = list;
|
|
54
|
-
assetLookupCache = new Map();
|
|
55
|
-
log(`Initialized version ${version} (${list.length} assets, mapped for O(1) lookup)`);
|
|
56
|
-
patchAssetResolver();
|
|
57
|
-
} else {
|
|
58
|
-
log(`Manifest NOT found at: ${manifestPath}`);
|
|
59
|
-
}
|
|
60
|
-
} catch (e) {
|
|
61
|
-
log(`Failed to load manifest: ${e.message}`);
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Patches React Native's Image.resolveAssetSource to intercept and redirect
|
|
67
|
-
* asset requests to the locally downloaded OTA asset store.
|
|
68
|
-
*/
|
|
69
|
-
exports.initOtaAssetResolver = initOtaAssetResolver;
|
|
70
|
-
const patchAssetResolver = () => {
|
|
71
|
-
if (isPatched) return;
|
|
72
|
-
isPatched = true;
|
|
73
|
-
const resolveAssetSource = _reactNative.Image.resolveAssetSource;
|
|
74
|
-
if (resolveAssetSource && typeof resolveAssetSource.setCustomSourceTransformer === 'function') {
|
|
75
|
-
resolveAssetSource.setCustomSourceTransformer(resolver => {
|
|
76
|
-
// Get the default resolution result
|
|
77
|
-
const res = resolver.defaultAsset();
|
|
78
|
-
if (!res || !assetManifest) return res;
|
|
79
|
-
const uri = res.uri;
|
|
80
|
-
|
|
81
|
-
// Skip remote or data URIs
|
|
82
|
-
// Note: We DO NOT skip 'file://' because local bundles use it for relative asset resolution.
|
|
83
|
-
if (!uri || uri.startsWith('http') || uri.startsWith('data')) {
|
|
84
|
-
return res;
|
|
85
|
-
}
|
|
86
|
-
const normUri = uri.toLowerCase().replace(/\//g, '_').replace(/^(assets_)+/, '');
|
|
87
|
-
const cached = assetLookupCache.get(normUri);
|
|
88
|
-
|
|
89
|
-
// 1. Fast cached lookup from previous exact/fuzzy resolution
|
|
90
|
-
let found = cached === undefined ? undefined : cached;
|
|
91
|
-
|
|
92
|
-
// 2. Fast O(1) Map lookup
|
|
93
|
-
if (found === undefined) {
|
|
94
|
-
found = assetMap.get(normUri) ?? undefined;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// 3. Fallback O(N) fuzzy matching (without regex overhead)
|
|
98
|
-
if (found === undefined) {
|
|
99
|
-
found = assetList.find(a => {
|
|
100
|
-
return a._normPath.endsWith(normUri) || normUri.endsWith(a._normPath);
|
|
101
|
-
});
|
|
102
|
-
assetLookupCache.set(normUri, found ?? null);
|
|
103
|
-
}
|
|
104
|
-
if (found) {
|
|
105
|
-
const localPath = `${ASSET_STORE_DIR}/${found.hash}.${found.ext}`;
|
|
106
|
-
// iOS & Android: requires file:// prefix for absolute filesystem paths
|
|
107
|
-
const finalUri = `file://${localPath}`;
|
|
108
|
-
log(`REDIRECTED: ${uri} -> ${found.hash} (Local: ${finalUri})`);
|
|
109
|
-
return {
|
|
110
|
-
...res,
|
|
111
|
-
uri: finalUri
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Diagnostic logging for missed assets that appear to be internal resources
|
|
116
|
-
if (uri.includes('assets')) {
|
|
117
|
-
log(`MISS: ${uri} (Not found in manifest)`);
|
|
118
|
-
}
|
|
119
|
-
return res;
|
|
120
|
-
});
|
|
121
|
-
log('Successfully attached CustomSourceTransformer.');
|
|
122
|
-
} else {
|
|
123
|
-
log('ERROR: setCustomSourceTransformer is not available in this React Native version.');
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Resets the OTA asset resolver state.
|
|
129
|
-
* Call this before a major app upgrade or when unmounting the OTA context.
|
|
130
|
-
* Clears cached manifest data and resets the transformer patch guard so
|
|
131
|
-
* `initOtaAssetResolver` can re-patch cleanly on next call.
|
|
132
|
-
*/
|
|
133
|
-
const resetOtaAssetResolver = () => {
|
|
134
|
-
assetManifest = null;
|
|
135
|
-
assetMap = new Map();
|
|
136
|
-
assetList = [];
|
|
137
|
-
assetLookupCache = new Map();
|
|
138
|
-
isPatched = false;
|
|
139
|
-
};
|
|
140
|
-
exports.resetOtaAssetResolver = resetOtaAssetResolver;
|
|
141
|
-
//# sourceMappingURL=otaAssetResolver.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_reactNativeBlobUtil","_interopRequireDefault","_NativeBsPatch","e","__esModule","default","ASSET_STORE_DIR","ReactNativeBlobUtil","fs","dirs","DocumentDir","assetManifest","assetMap","Map","assetList","assetLookupCache","isPatched","log","msg","formatted","console","NativeBsPatch","logNative","initOtaAssetResolver","version","otaDir","versionDir","manifestPath","exists","content","readFile","JSON","parse","map","list","assets","forEach","a","normPath","originalPath","toLowerCase","replace","_normPath","set","length","patchAssetResolver","message","exports","resolveAssetSource","Image","setCustomSourceTransformer","resolver","res","defaultAsset","uri","startsWith","normUri","cached","get","found","undefined","find","endsWith","localPath","hash","ext","finalUri","includes","resetOtaAssetResolver"],"sourceRoot":"../../../src","sources":["ota/otaAssetResolver.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { Image } from 'react-native';
|
|
4
|
-
import ReactNativeBlobUtil from 'react-native-blob-util';
|
|
5
|
-
import NativeBsPatch from '../NativeBsPatch';
|
|
6
|
-
const ASSET_STORE_DIR = `${ReactNativeBlobUtil.fs.dirs.DocumentDir}/ota/assets`;
|
|
7
|
-
let assetManifest = null;
|
|
8
|
-
let assetMap = new Map();
|
|
9
|
-
let assetList = [];
|
|
10
|
-
let assetLookupCache = new Map();
|
|
11
|
-
let isPatched = false;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Internal logger with native bridge integration.
|
|
15
|
-
*/
|
|
16
|
-
const log = msg => {
|
|
17
|
-
const formatted = `[otaAssetResolver] ${msg}`;
|
|
18
|
-
console.log(formatted);
|
|
19
|
-
if (NativeBsPatch?.logNative) {
|
|
20
|
-
NativeBsPatch.logNative(formatted);
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Initializes the OTA asset resolver for a specific version.
|
|
26
|
-
* Loads the asset manifest and prepares an O(1) lookup map for intercepted image requests.
|
|
27
|
-
*
|
|
28
|
-
* @param version - The OTA version number to load assets from.
|
|
29
|
-
*/
|
|
30
|
-
export const initOtaAssetResolver = async version => {
|
|
31
|
-
const otaDir = `${ReactNativeBlobUtil.fs.dirs.DocumentDir}/ota`;
|
|
32
|
-
const versionDir = `${otaDir}/v${version}`;
|
|
33
|
-
const manifestPath = `${versionDir}/asset-manifest-v${version}.json`;
|
|
34
|
-
try {
|
|
35
|
-
if (await ReactNativeBlobUtil.fs.exists(manifestPath)) {
|
|
36
|
-
const content = await ReactNativeBlobUtil.fs.readFile(manifestPath, 'utf8');
|
|
37
|
-
assetManifest = JSON.parse(content);
|
|
38
|
-
|
|
39
|
-
// Pre-compute normalized paths for O(1) lookup to prevent JS thread blocking during render
|
|
40
|
-
const map = new Map();
|
|
41
|
-
const list = assetManifest.assets || [];
|
|
42
|
-
list.forEach(a => {
|
|
43
|
-
const normPath = a.originalPath.toLowerCase().replace(/\//g, '_').replace(/^(assets_)+/, '');
|
|
44
|
-
a._normPath = normPath; // cache for fast fallback
|
|
45
|
-
map.set(normPath, a);
|
|
46
|
-
});
|
|
47
|
-
assetMap = map;
|
|
48
|
-
assetList = list;
|
|
49
|
-
assetLookupCache = new Map();
|
|
50
|
-
log(`Initialized version ${version} (${list.length} assets, mapped for O(1) lookup)`);
|
|
51
|
-
patchAssetResolver();
|
|
52
|
-
} else {
|
|
53
|
-
log(`Manifest NOT found at: ${manifestPath}`);
|
|
54
|
-
}
|
|
55
|
-
} catch (e) {
|
|
56
|
-
log(`Failed to load manifest: ${e.message}`);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Patches React Native's Image.resolveAssetSource to intercept and redirect
|
|
62
|
-
* asset requests to the locally downloaded OTA asset store.
|
|
63
|
-
*/
|
|
64
|
-
const patchAssetResolver = () => {
|
|
65
|
-
if (isPatched) return;
|
|
66
|
-
isPatched = true;
|
|
67
|
-
const resolveAssetSource = Image.resolveAssetSource;
|
|
68
|
-
if (resolveAssetSource && typeof resolveAssetSource.setCustomSourceTransformer === 'function') {
|
|
69
|
-
resolveAssetSource.setCustomSourceTransformer(resolver => {
|
|
70
|
-
// Get the default resolution result
|
|
71
|
-
const res = resolver.defaultAsset();
|
|
72
|
-
if (!res || !assetManifest) return res;
|
|
73
|
-
const uri = res.uri;
|
|
74
|
-
|
|
75
|
-
// Skip remote or data URIs
|
|
76
|
-
// Note: We DO NOT skip 'file://' because local bundles use it for relative asset resolution.
|
|
77
|
-
if (!uri || uri.startsWith('http') || uri.startsWith('data')) {
|
|
78
|
-
return res;
|
|
79
|
-
}
|
|
80
|
-
const normUri = uri.toLowerCase().replace(/\//g, '_').replace(/^(assets_)+/, '');
|
|
81
|
-
const cached = assetLookupCache.get(normUri);
|
|
82
|
-
|
|
83
|
-
// 1. Fast cached lookup from previous exact/fuzzy resolution
|
|
84
|
-
let found = cached === undefined ? undefined : cached;
|
|
85
|
-
|
|
86
|
-
// 2. Fast O(1) Map lookup
|
|
87
|
-
if (found === undefined) {
|
|
88
|
-
found = assetMap.get(normUri) ?? undefined;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// 3. Fallback O(N) fuzzy matching (without regex overhead)
|
|
92
|
-
if (found === undefined) {
|
|
93
|
-
found = assetList.find(a => {
|
|
94
|
-
return a._normPath.endsWith(normUri) || normUri.endsWith(a._normPath);
|
|
95
|
-
});
|
|
96
|
-
assetLookupCache.set(normUri, found ?? null);
|
|
97
|
-
}
|
|
98
|
-
if (found) {
|
|
99
|
-
const localPath = `${ASSET_STORE_DIR}/${found.hash}.${found.ext}`;
|
|
100
|
-
// iOS & Android: requires file:// prefix for absolute filesystem paths
|
|
101
|
-
const finalUri = `file://${localPath}`;
|
|
102
|
-
log(`REDIRECTED: ${uri} -> ${found.hash} (Local: ${finalUri})`);
|
|
103
|
-
return {
|
|
104
|
-
...res,
|
|
105
|
-
uri: finalUri
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Diagnostic logging for missed assets that appear to be internal resources
|
|
110
|
-
if (uri.includes('assets')) {
|
|
111
|
-
log(`MISS: ${uri} (Not found in manifest)`);
|
|
112
|
-
}
|
|
113
|
-
return res;
|
|
114
|
-
});
|
|
115
|
-
log('Successfully attached CustomSourceTransformer.');
|
|
116
|
-
} else {
|
|
117
|
-
log('ERROR: setCustomSourceTransformer is not available in this React Native version.');
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Resets the OTA asset resolver state.
|
|
123
|
-
* Call this before a major app upgrade or when unmounting the OTA context.
|
|
124
|
-
* Clears cached manifest data and resets the transformer patch guard so
|
|
125
|
-
* `initOtaAssetResolver` can re-patch cleanly on next call.
|
|
126
|
-
*/
|
|
127
|
-
export const resetOtaAssetResolver = () => {
|
|
128
|
-
assetManifest = null;
|
|
129
|
-
assetMap = new Map();
|
|
130
|
-
assetList = [];
|
|
131
|
-
assetLookupCache = new Map();
|
|
132
|
-
isPatched = false;
|
|
133
|
-
};
|
|
134
|
-
//# sourceMappingURL=otaAssetResolver.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["Image","ReactNativeBlobUtil","NativeBsPatch","ASSET_STORE_DIR","fs","dirs","DocumentDir","assetManifest","assetMap","Map","assetList","assetLookupCache","isPatched","log","msg","formatted","console","logNative","initOtaAssetResolver","version","otaDir","versionDir","manifestPath","exists","content","readFile","JSON","parse","map","list","assets","forEach","a","normPath","originalPath","toLowerCase","replace","_normPath","set","length","patchAssetResolver","e","message","resolveAssetSource","setCustomSourceTransformer","resolver","res","defaultAsset","uri","startsWith","normUri","cached","get","found","undefined","find","endsWith","localPath","hash","ext","finalUri","includes","resetOtaAssetResolver"],"sourceRoot":"../../../src","sources":["ota/otaAssetResolver.ts"],"mappings":";;AAAA,SAASA,KAAK,QAAQ,cAAc;AACpC,OAAOC,mBAAmB,MAAM,wBAAwB;AACxD,OAAOC,aAAa,MAAM,kBAAkB;AAE5C,MAAMC,eAAe,GAAG,GAAGF,mBAAmB,CAACG,EAAE,CAACC,IAAI,CAACC,WAAW,aAAa;AAa/E,IAAIC,aAAmC,GAAG,IAAI;AAC9C,IAAIC,QAAoC,GAAG,IAAIC,GAAG,CAAC,CAAC;AACpD,IAAIC,SAA0B,GAAG,EAAE;AACnC,IAAIC,gBAAmD,GAAG,IAAIF,GAAG,CAAC,CAAC;AACnE,IAAIG,SAAS,GAAG,KAAK;;AAErB;AACA;AACA;AACA,MAAMC,GAAG,GAAIC,GAAW,IAAW;EAC/B,MAAMC,SAAS,GAAG,sBAAsBD,GAAG,EAAE;EAC7CE,OAAO,CAACH,GAAG,CAACE,SAAS,CAAC;EACtB,IAAIb,aAAa,EAAEe,SAAS,EAAE;IAC1Bf,aAAa,CAACe,SAAS,CAACF,SAAS,CAAC;EACtC;AACJ,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMG,oBAAoB,GAAG,MAAOC,OAAe,IAAoB;EAC1E,MAAMC,MAAM,GAAG,GAAGnB,mBAAmB,CAACG,EAAE,CAACC,IAAI,CAACC,WAAW,MAAM;EAC/D,MAAMe,UAAU,GAAG,GAAGD,MAAM,KAAKD,OAAO,EAAE;EAC1C,MAAMG,YAAY,GAAG,GAAGD,UAAU,oBAAoBF,OAAO,OAAO;EAEpE,IAAI;IACA,IAAI,MAAMlB,mBAAmB,CAACG,EAAE,CAACmB,MAAM,CAACD,YAAY,CAAC,EAAE;MACnD,MAAME,OAAO,GAAG,MAAMvB,mBAAmB,CAACG,EAAE,CAACqB,QAAQ,CACjDH,YAAY,EACZ,MACJ,CAAC;MACDf,aAAa,GAAGmB,IAAI,CAACC,KAAK,CAACH,OAAO,CAAkB;;MAEpD;MACA,MAAMI,GAAG,GAAG,IAAInB,GAAG,CAAwB,CAAC;MAC5C,MAAMoB,IAAI,GAAGtB,aAAa,CAACuB,MAAM,IAAI,EAAE;MACvCD,IAAI,CAACE,OAAO,CAAEC,CAAgB,IAAK;QAC/B,MAAMC,QAAQ,GAAGD,CAAC,CAACE,YAAY,CAC1BC,WAAW,CAAC,CAAC,CACbC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CACnBA,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;QAC/BJ,CAAC,CAACK,SAAS,GAAGJ,QAAQ,CAAC,CAAC;QACxBL,GAAG,CAACU,GAAG,CAACL,QAAQ,EAAED,CAAC,CAAC;MACxB,CAAC,CAAC;MACFxB,QAAQ,GAAGoB,GAAG;MACdlB,SAAS,GAAGmB,IAAI;MAChBlB,gBAAgB,GAAG,IAAIF,GAAG,CAAC,CAAC;MAE5BI,GAAG,CACC,uBAAuBM,OAAO,KAAKU,IAAI,CAACU,MAAM,kCAClD,CAAC;MACDC,kBAAkB,CAAC,CAAC;IACxB,CAAC,MAAM;MACH3B,GAAG,CAAC,0BAA0BS,YAAY,EAAE,CAAC;IACjD;EACJ,CAAC,CAAC,OAAOmB,CAAC,EAAE;IACR5B,GAAG,CAAC,4BAA6B4B,CAAC,CAAWC,OAAO,EAAE,CAAC;EAC3D;AACJ,CAAC;;AAID;AACA;AACA;AACA;AACA,MAAMF,kBAAkB,GAAGA,CAAA,KAAY;EACnC,IAAI5B,SAAS,EAAE;EACfA,SAAS,GAAG,IAAI;EAEhB,MAAM+B,kBAAkB,GAAI3C,KAAK,CAQ9B2C,kBAAkB;EAErB,IACIA,kBAAkB,IAClB,OAAOA,kBAAkB,CAACC,0BAA0B,KAAK,UAAU,EACrE;IACED,kBAAkB,CAACC,0BAA0B,CAAEC,QAAQ,IAAK;MACxD;MACA,MAAMC,GAAG,GAAGD,QAAQ,CAACE,YAAY,CAAC,CAAC;MACnC,IAAI,CAACD,GAAG,IAAI,CAACvC,aAAa,EAAE,OAAOuC,GAAG;MAEtC,MAAME,GAAG,GAAGF,GAAG,CAACE,GAAG;;MAEnB;MACA;MACA,IAAI,CAACA,GAAG,IAAIA,GAAG,CAACC,UAAU,CAAC,MAAM,CAAC,IAAID,GAAG,CAACC,UAAU,CAAC,MAAM,CAAC,EAAE;QAC1D,OAAOH,GAAG;MACd;MAEA,MAAMI,OAAO,GAAGF,GAAG,CACdb,WAAW,CAAC,CAAC,CACbC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CACnBA,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;MAE/B,MAAMe,MAAM,GAAGxC,gBAAgB,CAACyC,GAAG,CAACF,OAAO,CAAC;;MAE5C;MACA,IAAIG,KAAK,GAAGF,MAAM,KAAKG,SAAS,GAAGA,SAAS,GAAGH,MAAM;;MAErD;MACA,IAAIE,KAAK,KAAKC,SAAS,EAAE;QACrBD,KAAK,GAAG7C,QAAQ,CAAC4C,GAAG,CAACF,OAAO,CAAC,IAAII,SAAS;MAC9C;;MAEA;MACA,IAAID,KAAK,KAAKC,SAAS,EAAE;QACrBD,KAAK,GAAG3C,SAAS,CAAC6C,IAAI,CAAEvB,CAAgB,IAAK;UACzC,OACIA,CAAC,CAACK,SAAS,CAACmB,QAAQ,CAACN,OAAO,CAAC,IAC7BA,OAAO,CAACM,QAAQ,CAACxB,CAAC,CAACK,SAAS,CAAC;QAErC,CAAC,CAAC;QACF1B,gBAAgB,CAAC2B,GAAG,CAACY,OAAO,EAAEG,KAAK,IAAI,IAAI,CAAC;MAChD;MAEA,IAAIA,KAAK,EAAE;QACP,MAAMI,SAAS,GAAG,GAAGtD,eAAe,IAAIkD,KAAK,CAACK,IAAI,IAAIL,KAAK,CAACM,GAAG,EAAE;QACjE;QACA,MAAMC,QAAQ,GAAG,UAAUH,SAAS,EAAE;QACtC5C,GAAG,CAAC,eAAemC,GAAG,OAAOK,KAAK,CAACK,IAAI,YAAYE,QAAQ,GAAG,CAAC;QAC/D,OAAO;UAAE,GAAGd,GAAG;UAAEE,GAAG,EAAEY;QAAS,CAAC;MACpC;;MAEA;MACA,IAAIZ,GAAG,CAACa,QAAQ,CAAC,QAAQ,CAAC,EAAE;QACxBhD,GAAG,CAAC,SAASmC,GAAG,0BAA0B,CAAC;MAC/C;MAEA,OAAOF,GAAG;IACd,CAAC,CAAC;IACFjC,GAAG,CAAC,gDAAgD,CAAC;EACzD,CAAC,MAAM;IACHA,GAAG,CACC,kFACJ,CAAC;EACL;AACJ,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMiD,qBAAqB,GAAGA,CAAA,KAAY;EAC7CvD,aAAa,GAAG,IAAI;EACpBC,QAAQ,GAAG,IAAIC,GAAG,CAAC,CAAC;EACpBC,SAAS,GAAG,EAAE;EACdC,gBAAgB,GAAG,IAAIF,GAAG,CAAC,CAAC;EAC5BG,SAAS,GAAG,KAAK;AACrB,CAAC","ignoreList":[]}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Initializes the OTA asset resolver for a specific version.
|
|
3
|
-
* Loads the asset manifest and prepares an O(1) lookup map for intercepted image requests.
|
|
4
|
-
*
|
|
5
|
-
* @param version - The OTA version number to load assets from.
|
|
6
|
-
*/
|
|
7
|
-
export declare const initOtaAssetResolver: (version: number) => Promise<void>;
|
|
8
|
-
/**
|
|
9
|
-
* Resets the OTA asset resolver state.
|
|
10
|
-
* Call this before a major app upgrade or when unmounting the OTA context.
|
|
11
|
-
* Clears cached manifest data and resets the transformer patch guard so
|
|
12
|
-
* `initOtaAssetResolver` can re-patch cleanly on next call.
|
|
13
|
-
*/
|
|
14
|
-
export declare const resetOtaAssetResolver: () => void;
|
|
15
|
-
//# sourceMappingURL=otaAssetResolver.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"otaAssetResolver.d.ts","sourceRoot":"","sources":["../../../src/ota/otaAssetResolver.ts"],"names":[],"mappings":"AAkCA;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,IAAI,CAsCxE,CAAC;AAwFF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAAO,IAMxC,CAAC"}
|