Skip to content

Commit d1f9a51

Browse files
authored
Merge pull request #6 from Exilz/dev
v1.2.0 closes #5
2 parents 1825b03 + e29fd40 commit d1f9a51

File tree

4 files changed

+42
-37
lines changed

4 files changed

+42
-37
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Easily write offline-first react-native applications with your own REST API. Thi
99
- [react-native-offline-api](#react-native-offline-api)
1010
- [Table of contents](#table-of-contents)
1111
- [Installation](#installation)
12-
- [How does it work ?](#how-does-it-work)
12+
- [How it works](#how-it-works)
1313
- [How to use](#how-to-use)
1414
- [Setting up your global API options](#setting-up-your-global-api-options)
1515
- [Declaring your services definitions](#declaring-your-services-definitions)
@@ -32,7 +32,7 @@ npm install --save react-native-offline-api # with npm
3232
yarn add react-native-offline-api # with yarn
3333
```
3434

35-
## How does it work ?
35+
## How it works
3636

3737
<p align="center"><a href="http://i.imgur.com/SBm5Xhj.png"><img src="http://i.imgur.com/TO1sGZU.png"/></a></p>
3838
<p align="center"><em>click to enlarge</em></p>
@@ -173,13 +173,14 @@ Key | Type | Description | Example
173173
------ | ------ | ------ | ------
174174
`path` | `string` | Required path to your endpoint, see [path and query parameters](#path-and-query-parameters) | `article/:articleId`
175175
`expiration` | `number` | Optional time in ms before this service's cached data becomes stale, defaults to 5 minutes
176-
`method` | `'GET' | 'POST' | 'OPTIONS'...` | Optional HTTP method of your request, defaults to `GET`
176+
`method` | `GET` | Optional HTTP method of your request, defaults to `GET` | `OPTIONS...`
177177
`domain` | `string` | Optional specific domain to use for this service, provide the key you set in your `domains` API option
178178
`prefix` | `string` | Optional specific prefix to use for this service, provide the key you set in your `prefixes` API option
179179
`middlewares` | `APIMiddleware[]` | Optional array of middlewares that override the ones set globally in your `middlewares` API option, , see [middlewares](#middlewares)
180180
`disableCache` | `boolean` | Optional, disables the cache for this service (override your [API's global options](#api-options))
181181
`capService` | `boolean` | Optional, enable or disable capping for this specific service, see [limiting the size of your cache](#limiting-the-size-of-your-cache)
182182
`capLimit` | `number` | Optional quantity of cached items for this specific service, defaults to `50`, see [limiting the size of your cache](#limiting-the-size-of-your-cache)
183+
`rawData` | `boolean` | Disables JSON parsing from your network requests, useful if you want to fetch XML or anything else from your api
183184

184185
## Fetch options
185186

@@ -293,7 +294,7 @@ These are Typescript defintions, so they should be displayed in your editor/IDE
293294

294295
Pull requests are more than welcome for these items, or for any feature that might be missing.
295296

296-
- [ ] Write a demo
297+
- [x] Write a demo
297298
- [ ] Improve capping performance by storing how many items are cached for each service so we don't have to parse the whole service's dictionary each time
298299
- [ ] Add a method to check for the total size of the cache, which would be useful to trigger a clearing if it reaches a certain size
299300
- [ ] Thoroughly test custom caching drivers, maybe provide one (realm or sqlite)

dist/index.js

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ var DEFAULT_API_OPTIONS = {
6060
var DEFAULT_SERVICE_OPTIONS = {
6161
method: 'GET',
6262
domain: 'default',
63-
prefix: 'default',
64-
disableCache: false
63+
prefix: 'default'
6564
};
6665
var DEFAULT_CACHE_DRIVER = react_native_1.AsyncStorage;
6766
var OfflineFirstAPI = (function () {
@@ -74,21 +73,21 @@ var OfflineFirstAPI = (function () {
7473
}
7574
OfflineFirstAPI.prototype.fetch = function (service, options) {
7675
return __awaiter(this, void 0, void 0, function () {
77-
var serviceDefinition, fullPath, middlewares, fetchOptions, fetchHeaders, shouldUseCache, requestId, expiration, _sha, expirationDelay, cachedData, parsedResponseData, res, err_1;
78-
return __generator(this, function (_a) {
79-
switch (_a.label) {
76+
var serviceDefinition, fullPath, middlewares, fetchOptions, fetchHeaders, shouldUseCache, requestId, expiration, _sha, expirationDelay, cachedData, parsedResponseData, res, _a, err_1;
77+
return __generator(this, function (_b) {
78+
switch (_b.label) {
8079
case 0:
8180
serviceDefinition = this._APIServices[service];
8281
if (!serviceDefinition) {
8382
throw new Error("Cannot fetch data from unregistered service '" + service + "'");
8483
}
8584
fullPath = this._constructPath(serviceDefinition, options);
86-
_a.label = 1;
85+
_b.label = 1;
8786
case 1:
88-
_a.trys.push([1, 8, , 9]);
87+
_b.trys.push([1, 10, , 11]);
8988
return [4 /*yield*/, this._applyMiddlewares(serviceDefinition, fullPath, options)];
9089
case 2:
91-
middlewares = _a.sent();
90+
middlewares = _b.sent();
9291
fetchOptions = _merge(middlewares, (options && options.fetchOptions) || {}, { method: serviceDefinition.method }, { headers: (options && options.headers) || {} });
9392
fetchHeaders = options && options.fetchHeaders;
9493
shouldUseCache = this._shouldUseCache(serviceDefinition, options);
@@ -101,7 +100,7 @@ var OfflineFirstAPI = (function () {
101100
expiration = Date.now() + expirationDelay;
102101
return [4 /*yield*/, this._getCachedData(service, requestId, fullPath)];
103102
case 3:
104-
cachedData = _a.sent();
103+
cachedData = _b.sent();
105104
if (cachedData.success && cachedData.fresh && shouldUseCache) {
106105
this._log("Using fresh cache for " + fullPath);
107106
return [2 /*return*/, cachedData.data];
@@ -113,7 +112,7 @@ var OfflineFirstAPI = (function () {
113112
parsedResponseData = void 0;
114113
return [4 /*yield*/, this._fetch(fullPath, fetchOptions)];
115114
case 4:
116-
res = _a.sent();
115+
res = _b.sent();
117116
// If the network request fails, return the cached data if it's valid, a throw an error
118117
if (!res.success) {
119118
if (cachedData.success && cachedData.data) {
@@ -127,22 +126,29 @@ var OfflineFirstAPI = (function () {
127126
this._log('raw network response', res);
128127
if (!fetchHeaders) return [3 /*break*/, 5];
129128
parsedResponseData = res.data.headers && res.data.headers.map ? res.data.headers.map : {};
130-
return [3 /*break*/, 7];
131-
case 5: return [4 /*yield*/, res.data.json()];
132-
case 6:
133-
parsedResponseData = _a.sent();
134-
_a.label = 7;
129+
return [3 /*break*/, 9];
130+
case 5:
131+
if (!((options && options.rawData) || serviceDefinition.rawData)) return [3 /*break*/, 6];
132+
_a = res.data;
133+
return [3 /*break*/, 8];
134+
case 6: return [4 /*yield*/, res.data.json()];
135135
case 7:
136+
_a = _b.sent();
137+
_b.label = 8;
138+
case 8:
139+
parsedResponseData = _a;
140+
_b.label = 9;
141+
case 9:
136142
// Cache if it hasn't been disabled and if the network request has been successful
137143
if (res.data.ok && shouldUseCache) {
138144
this._cache(serviceDefinition, service, requestId, parsedResponseData, expiration);
139145
}
140146
this._log('parsed network response', parsedResponseData);
141147
return [2 /*return*/, parsedResponseData];
142-
case 8:
143-
err_1 = _a.sent();
148+
case 10:
149+
err_1 = _b.sent();
144150
throw new Error(err_1);
145-
case 9: return [2 /*return*/];
151+
case 11: return [2 /*return*/];
146152
}
147153
});
148154
});
@@ -377,11 +383,10 @@ var OfflineFirstAPI = (function () {
377383
* @memberof OfflineFirstAPI
378384
*/
379385
OfflineFirstAPI.prototype._shouldUseCache = function (serviceDefinition, options) {
380-
var cacheDisabledFromOptions = options && options.disableCache;
381-
if (typeof cacheDisabledFromOptions !== 'undefined') {
382-
return !cacheDisabledFromOptions;
386+
if (options && typeof options.disableCache !== 'undefined') {
387+
return !options.disableCache;
383388
}
384-
else if (typeof serviceDefinition.disableCache !== 'undefined') {
389+
else if (serviceDefinition && typeof serviceDefinition.disableCache !== 'undefined') {
385390
return !serviceDefinition.disableCache;
386391
}
387392
else {
@@ -606,11 +611,11 @@ var OfflineFirstAPI = (function () {
606611
OfflineFirstAPI.prototype._mergeServicesWithDefaultValues = function (services) {
607612
var _this = this;
608613
return _mapValues(services, function (service, serviceName) {
609-
if (service.domain && !_this._APIOptions.domains[service.domain]) {
614+
if (service.domain && typeof _this._APIOptions.domains[service.domain] === 'undefined') {
610615
throw new Error("Domain key " + service.domain + " specified for service " + serviceName + " hasn't been declared. \n" +
611616
'Please provide it in your OfflineFirstAPI parameters or leave it blank to use the default one.');
612617
}
613-
if (service.prefix && !_this._APIOptions.prefixes[service.prefix]) {
618+
if (service.prefix && typeof _this._APIOptions.prefixes[service.prefix] === 'undefined') {
614619
throw new Error("Prefix key " + service.domain + " specified for service " + serviceName + " hasn't been declared. \n" +
615620
'Please provide it in your OfflineFirstAPI parameters or leave it blank to use the default one.');
616621
}

src/index.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ const DEFAULT_API_OPTIONS = {
2828
const DEFAULT_SERVICE_OPTIONS = {
2929
method: 'GET',
3030
domain: 'default',
31-
prefix: 'default',
32-
disableCache: false
31+
prefix: 'default'
3332
};
3433

3534
const DEFAULT_CACHE_DRIVER = AsyncStorage;
@@ -103,7 +102,7 @@ export default class OfflineFirstAPI {
103102
if (fetchHeaders) {
104103
parsedResponseData = res.data.headers && res.data.headers.map ? res.data.headers.map : {};
105104
} else {
106-
parsedResponseData = await res.data.json();
105+
parsedResponseData = (options && options.rawData) || serviceDefinition.rawData ? res.data : await res.data.json();
107106
}
108107

109108
// Cache if it hasn't been disabled and if the network request has been successful
@@ -290,10 +289,9 @@ export default class OfflineFirstAPI {
290289
* @memberof OfflineFirstAPI
291290
*/
292291
private _shouldUseCache (serviceDefinition: IAPIService, options: IFetchOptions): boolean {
293-
const cacheDisabledFromOptions = options && options.disableCache;
294-
if (typeof cacheDisabledFromOptions !== 'undefined') {
295-
return !cacheDisabledFromOptions;
296-
} else if (typeof serviceDefinition.disableCache !== 'undefined') {
292+
if (options && typeof options.disableCache !== 'undefined') {
293+
return !options.disableCache;
294+
} else if (serviceDefinition && typeof serviceDefinition.disableCache !== 'undefined') {
297295
return !serviceDefinition.disableCache;
298296
} else {
299297
return !this._APIOptions.disableCache;
@@ -500,13 +498,13 @@ export default class OfflineFirstAPI {
500498
*/
501499
private _mergeServicesWithDefaultValues (services: IAPIServices): IAPIServices {
502500
return _mapValues(services, (service: IAPIService, serviceName: string) => {
503-
if (service.domain && !this._APIOptions.domains[service.domain]) {
501+
if (service.domain && typeof this._APIOptions.domains[service.domain] === 'undefined') {
504502
throw new Error(
505503
`Domain key ${service.domain} specified for service ${serviceName} hasn't been declared. \n` +
506504
'Please provide it in your OfflineFirstAPI parameters or leave it blank to use the default one.'
507505
);
508506
}
509-
if (service.prefix && !this._APIOptions.prefixes[service.prefix]) {
507+
if (service.prefix && typeof this._APIOptions.prefixes[service.prefix] === 'undefined') {
510508
throw new Error(
511509
`Prefix key ${service.domain} specified for service ${serviceName} hasn't been declared. \n` +
512510
'Please provide it in your OfflineFirstAPI parameters or leave it blank to use the default one.'

src/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export interface IAPIService {
2222
disableCache?: boolean;
2323
capService?: boolean;
2424
capLimit?: number;
25+
rawData?: boolean;
2526
};
2627

2728
export interface IAPIServices {

0 commit comments

Comments
 (0)