Skip to content
This repository was archived by the owner on Apr 15, 2025. It is now read-only.

Commit 78aea73

Browse files
committed
Use ReplaySubject for the shared observables so we can notify subscribers of changes, requires test changes because the subscriptions will never complete
1 parent 46a82f6 commit 78aea73

File tree

3 files changed

+78
-32
lines changed

3 files changed

+78
-32
lines changed

src/FileSystem.tsx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import pathLib from 'path'
1212
import RNFS from 'react-native-fs'
1313
import sha1 from 'crypto-js/sha1'
1414
import URL from 'url-parse'
15-
import { from, Observable, of } from 'rxjs'
15+
import { from, Observable, of, ReplaySubject } from 'rxjs'
1616
import {
1717
switchMap,
1818
catchError,
@@ -24,6 +24,7 @@ import {
2424
filter,
2525
delayWhen,
2626
concatAll,
27+
take,
2728
} from 'rxjs/operators'
2829
import uuid from 'react-native-uuid'
2930
import { CacheStrategy } from '.'
@@ -74,7 +75,7 @@ export class FileSystem {
7475
}
7576
} = {}
7677
static cacheObservables: {
77-
[key: string]: Observable<CacheFileInfo>
78+
[key: string]: ReplaySubject<CacheFileInfo>
7879
} = {}
7980
baseFilePath: string
8081
cachePruneTriggerLimit: number
@@ -204,7 +205,9 @@ export class FileSystem {
204205
try {
205206
FileSystem.lockCacheFile(fileName, requestId)
206207

207-
const { path } = await this.observable(url, requestId, 'immutable', fileName).toPromise()
208+
const { path } = await this.observable(url, requestId, 'immutable', fileName)
209+
.pipe(take(1))
210+
.toPromise()
208211

209212
return path
210213
} finally {
@@ -261,6 +264,14 @@ export class FileSystem {
261264
}
262265
}
263266

267+
// Publish to subscribers that the image for this url has been updated
268+
if (FileSystem.cacheObservables[fileName]) {
269+
FileSystem.cacheObservables[fileName].next({
270+
path: 'file://' + path,
271+
fileName,
272+
})
273+
}
274+
264275
return {
265276
url,
266277
path,
@@ -429,9 +440,9 @@ export class FileSystem {
429440
if (!FileSystem.cacheObservables[fileName]) {
430441
this._validatePath(fileName)
431442

432-
return (FileSystem.cacheObservables[fileName] = from(
433-
RNFS.stat(this.baseFilePath + fileName),
434-
).pipe(
443+
const subject$ = new ReplaySubject<CacheFileInfo>()
444+
445+
const obs$ = from(RNFS.stat(this.baseFilePath + fileName)).pipe(
435446
catchError(() => of(null)),
436447
switchMap((stat) => {
437448
if (stat !== null) {
@@ -461,7 +472,12 @@ export class FileSystem {
461472
}),
462473
publishReplay(1),
463474
refCount(),
464-
))
475+
)
476+
477+
// Subscribe
478+
obs$.subscribe((v) => subject$.next(v))
479+
480+
return (FileSystem.cacheObservables[fileName] = subject$)
465481
}
466482

467483
return FileSystem.cacheObservables[fileName]

tests/CacheableImage.test.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import 'should'
22
import { mockData } from './mockData'
3-
import { imageCacheHoc, ReactNativeImageCacheHocOptions } from '../src/index'
3+
import { FileSystem, imageCacheHoc, ReactNativeImageCacheHocOptions } from '../src/index'
44
import { Image, Text } from 'react-native'
55
import 'should-sinon'
66
import RNFS from 'react-native-fs'
77
import { shallow } from 'enzyme'
88
import React from 'react'
99
import { mocked } from 'ts-jest/utils'
10+
import { ReplaySubject } from 'rxjs'
11+
import { CacheFileInfo } from '../src/FileSystem'
1012

1113
describe('CacheableImage', function () {
1214
const originalWarn = console.warn
@@ -145,6 +147,30 @@ describe('CacheableImage', function () {
145147
expect(MockedRNFS.copyFile).not.toHaveBeenCalled()
146148
expect(MockedRNFS.moveFile).not.toHaveBeenCalled()
147149
})
150+
151+
it('When local file and observable exist, it should be notified of changes', async (done) => {
152+
FileSystem.cacheObservables[
153+
'90c1be491d18ff2a7280039e9b65749461a65403.png'
154+
] = new ReplaySubject<CacheFileInfo>(1)
155+
156+
const CacheableImage = imageCacheHoc(Image)
157+
158+
const local = '/exists.png'
159+
const url = 'https://example.com/exists.png'
160+
161+
await CacheableImage.cacheLocalFile(local, url)
162+
163+
FileSystem.cacheObservables['90c1be491d18ff2a7280039e9b65749461a65403.png'].subscribe(
164+
(value) => {
165+
expect(value).toStrictEqual({
166+
path:
167+
'file:///base/file/path/react-native-image-cache-hoc/90c1be491d18ff2a7280039e9b65749461a65403.png',
168+
fileName: '90c1be491d18ff2a7280039e9b65749461a65403.png',
169+
})
170+
done()
171+
},
172+
)
173+
})
148174
})
149175

150176
it('#flush static method should work as expected.', () => {

tests/FileSystem.test.tsx

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,13 @@ describe('FileSystem', function () {
237237
fileName: 'cd7d2199cd8e088cdfd9c99fc6359666adc36289.png',
238238
})
239239
},
240-
complete: () => {
241-
expect(onNext).toBeCalledTimes(1)
242-
expect(MockedRNFS.downloadFile).not.toHaveBeenCalled()
243-
FileSystem.unlockCacheFile(fileName, requestId)
244-
done()
245-
},
240+
})
241+
242+
setImmediate(() => {
243+
expect(onNext).toBeCalledTimes(1)
244+
expect(MockedRNFS.downloadFile).not.toHaveBeenCalled()
245+
FileSystem.unlockCacheFile(fileName, requestId)
246+
done()
246247
})
247248
})
248249

@@ -268,12 +269,13 @@ describe('FileSystem', function () {
268269
fileName: 'cd7d2199cd8e088cdfd9c99fc6359666adc36289.png',
269270
})
270271
},
271-
complete: () => {
272-
expect(onNext).toBeCalledTimes(1)
273-
expect(MockedRNFS.downloadFile).toHaveBeenCalled()
274-
FileSystem.unlockCacheFile(fileName, requestId)
275-
done()
276-
},
272+
})
273+
274+
setImmediate(() => {
275+
expect(onNext).toBeCalledTimes(1)
276+
expect(MockedRNFS.downloadFile).toHaveBeenCalled()
277+
FileSystem.unlockCacheFile(fileName, requestId)
278+
done()
277279
})
278280
})
279281

@@ -325,12 +327,13 @@ describe('FileSystem', function () {
325327
fileName: 'cd7d2199cd8e088cdfd9c99fc6359666adc36289.png',
326328
})
327329
},
328-
complete: () => {
329-
expect(onNext).toBeCalledTimes(2)
330-
expect(MockedRNFS.downloadFile).toHaveBeenCalled()
331-
FileSystem.unlockCacheFile(fileName, requestId)
332-
done()
333-
},
330+
})
331+
332+
setImmediate(() => {
333+
expect(onNext).toBeCalledTimes(2)
334+
expect(MockedRNFS.downloadFile).toHaveBeenCalled()
335+
FileSystem.unlockCacheFile(fileName, requestId)
336+
done()
334337
})
335338
})
336339

@@ -385,12 +388,13 @@ describe('FileSystem', function () {
385388
fileName: 'cd7d2199cd8e088cdfd9c99fc6359666adc36289.png',
386389
})
387390
},
388-
complete: () => {
389-
expect(onNext).toBeCalledTimes(1)
390-
expect(MockedRNFS.downloadFile).toHaveBeenCalled()
391-
FileSystem.unlockCacheFile(fileName, requestId)
392-
done()
393-
},
391+
})
392+
393+
setImmediate(() => {
394+
expect(onNext).toBeCalledTimes(1)
395+
expect(MockedRNFS.downloadFile).toHaveBeenCalled()
396+
FileSystem.unlockCacheFile(fileName, requestId)
397+
done()
394398
})
395399
})
396400

0 commit comments

Comments
 (0)