Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit a81b5f1

Browse files
committed
Add JSON stream fs support #99
1 parent 9c3d947 commit a81b5f1

File tree

2 files changed

+117
-7
lines changed

2 files changed

+117
-7
lines changed

src/index.js

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
RNFetchBlobStream,
1717
RNFetchBlobResponseInfo
1818
} from './types'
19+
import URIUtil from './utils/uri'
1920
import StatefulPromise from './class/StatefulPromise.js'
2021
import fs from './fs'
2122
import getUUID from './utils/uuid'
@@ -100,6 +101,86 @@ function config (options:RNFetchBlobConfig) {
100101
return { fetch : fetch.bind(options) }
101102
}
102103

104+
/**
105+
* Fetch from file system, use the same interface as RNFB.fetch
106+
* @param {RNFetchBlobConfig} [options={}] Fetch configurations
107+
* @param {string} method Should be one of `get`, `post`, `put`
108+
* @param {string} url A file URI string
109+
* @param {string} headers Arguments of file system API
110+
* @param {any} body Data to put or post to file systen.
111+
* @return {Promise}
112+
*/
113+
function fetchFile(options = {}, method, url, headers = {}, body):Promise {
114+
115+
if(!URIUtil.isFileURI(url)) {
116+
throw `could not fetch file from an invalid URI : ${url}`
117+
}
118+
119+
url = URIUtil.unwrapFileURI(url)
120+
121+
let promise = null
122+
let cursor = 0
123+
let total = -1
124+
let cacheData = ''
125+
let info = null
126+
127+
let _progress, _uploadProgress, _stateChange
128+
129+
switch(method.toLowerCase()) {
130+
131+
case 'post':
132+
break
133+
134+
case 'put':
135+
break
136+
137+
// read data from file system
138+
default:
139+
promise = fs.stat(url)
140+
.then((stat) => {
141+
total = stat.size
142+
return fs.readStream(url, headers.encoding || 'utf8', Math.floor(headers.bufferSize) || 4096)
143+
})
144+
.then((stream) => new Promise((resolve, reject) => {
145+
stream.open()
146+
info = {
147+
state : "2",
148+
headers : { 'source' : 'system-fs' },
149+
status : 200,
150+
respType : 'text',
151+
rnfbEncode : headers.encoding || 'utf8'
152+
}
153+
_stateChange(info)
154+
stream.onData((chunk) => {
155+
_progress && _progress(cursor, total, chunk)
156+
if(headers.noCache)
157+
return
158+
cacheData += chunk
159+
})
160+
stream.onError((err) => { reject(err) })
161+
stream.onEnd(() => {
162+
resolve(new FetchBlobResponse(null, info, cacheData))
163+
})
164+
}))
165+
break
166+
}
167+
168+
promise.progress = (fn) => {
169+
_progress = fn
170+
return promise
171+
}
172+
promise.stateChange = (fn) => {
173+
_stateChange = fn
174+
return promise
175+
}
176+
promise.uploadProgress = (fn) => {
177+
_uploadProgress = fn
178+
return promise
179+
}
180+
181+
return promise
182+
}
183+
103184
/**
104185
* Create a HTTP request by settings, the `this` context is a `RNFetchBlobConfig` object.
105186
* @param {string} method HTTP method, should be `GET`, `POST`, `PUT`, `DELETE`
@@ -119,9 +200,15 @@ function fetch(...args:any):Promise {
119200
let options = this || {}
120201
let subscription, subscriptionUpload, stateEvent
121202
let respInfo = {}
203+
let [method, url, headers, body] = [...args]
204+
205+
// fetch from file system
206+
if(URIUtil.isFileURI(url)) {
207+
return fetchFile(options, method, url, headers, body)
208+
}
122209

210+
// from remote HTTP(S)
123211
let promise = new Promise((resolve, reject) => {
124-
let [method, url, headers, body] = [...args]
125212
let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob'
126213

127214
// on progress event listener

src/json-stream.js

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,38 @@
11
import Oboe from './lib/oboe-browser.min.js'
22
import XMLHttpRequest from './polyfill/XMLHttpRequest'
3+
import URIUtil from './utils/uri'
34

45
const OboeExtended = (arg: string | object) => {
5-
6-
window.XMLHttpRequest = XMLHttpRequest
6+
7+
78
window.location = ''
89

9-
if(typeof arg === 'string')
10-
arg = 'JSONStream://' + arg
11-
else if(typeof arg === 'object')
12-
arg = Object.assign(arg, { url : 'JSONStream://' + arg.url })
10+
if(!window.XMLHttpRequest.isRNFBPolyfill ) {
11+
window.XMLHttpRequest = XMLHttpRequest
12+
console.warn('Use JSONStream will automatically replace window.XMLHttpRequest with RNFetchBlob.polyfill.XMLHttpRequest. You are seeing this warning because you did not replace it maually.')
13+
}
14+
15+
if(typeof arg === 'string') {
16+
if(URIUtil.isFileURI(arg)) {
17+
arg = {
18+
url : 'JSONStream://' + arg,
19+
headers : { noCache : true }
20+
}
21+
}
22+
else
23+
arg = 'JSONStream://' + arg
24+
25+
}
26+
else if(typeof arg === 'object') {
27+
let headers = arg.headers || {}
28+
if(URIUtil.isFileURI(arg.url)) {
29+
headers.noCache = true
30+
}
31+
arg = Object.assign(arg, {
32+
url : 'JSONStream://' + arg.url,
33+
headers
34+
})
35+
}
1336
return Oboe(arg)
1437
}
1538

0 commit comments

Comments
 (0)