Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules/
demos/web/.next
yarn.lock
demos/web/package-lock.json
.idea
3 changes: 3 additions & 0 deletions .watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ignore_dirs": []
}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ Key | Type | Description | Example
`ignoreHeadersWhenCaching` | `boolean` | Optional, your requests will be cached independently from the headers you sent. | `true` (defaults to `false`)
`capServices` | `boolean` | Optional, enable capping for every service, defaults to `false`, see [limiting the size of your cache](#limiting-the-size-of-your-cache) | `true` (defaults to `false`)
`capLimit` | `number` | Optional quantity of cached items for each service, see [limiting the size of your cache](#limiting-the-size-of-your-cache) | `100` (defaults to `50`)
`networkFirst` | `boolean` | Optional, changes the flow by performing the network call before checking the cache | `true` (defaults to `false`)

## Services options

Expand All @@ -234,6 +235,7 @@ Key | Type | Description | Example
`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) | `42` (defaults to `50`)
`ignoreHeadersWhenCaching` | `boolean` | Optional, your requests will be cached independently from the headers you sent. | `true` (defaults to `false`)
`rawData` | `boolean` | Disables JSON parsing from your network requests, useful if you want to fetch XML or anything else from your api | `true` (defaults to `false`)
`networkFirst` | `boolean` | Optional, changes the flow by performing the network call before checking the cache. It overrides the one set in your API option | `true` (defaults to `false`)

## Fetch options

Expand Down
8 changes: 4 additions & 4 deletions dist/drivers/sqlite.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
Expand All @@ -44,7 +44,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
};
var _this = this;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = function (SQLite, options) { return __awaiter(_this, void 0, void 0, function () {
exports.default = (function (SQLite, options) { return __awaiter(_this, void 0, void 0, function () {
var db, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
Expand All @@ -71,7 +71,7 @@ exports.default = function (SQLite, options) { return __awaiter(_this, void 0, v
case 4: return [2 /*return*/];
}
});
}); };
}); });
function getItem(db) {
return function (key) {
return new Promise(function (resolve, reject) {
Expand Down
18 changes: 9 additions & 9 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, t.value];
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
Expand Down Expand Up @@ -57,7 +57,7 @@ var DEFAULT_API_OPTIONS = {
cachePrefix: 'APIPelineCache',
ignoreHeadersWhenCaching: false,
capServices: false,
capLimit: 50
capLimit: 50,
};
var DEFAULT_SERVICE_OPTIONS = {
method: 'GET',
Expand All @@ -66,7 +66,7 @@ var DEFAULT_SERVICE_OPTIONS = {
};
var HTTP_METHODS = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE'];
exports.drivers = { sqliteDriver: sqlite_1.default };
var APIpeline = (function () {
var APIpeline = /** @class */ (function () {
function APIpeline(options, services, driver) {
this._APIServices = {};
this._warnedAboutMissingDriver = false;
Expand Down Expand Up @@ -114,7 +114,7 @@ var APIpeline = (function () {
return [4 /*yield*/, this._getCachedData(service, requestId, fullPath, shouldUseCache)];
case 3:
cachedData = _c.sent();
if (cachedData.success && cachedData.fresh) {
if ((!this._APIOptions.networkFirst && !options.networkFirst && !serviceDefinition.networkFirst) && cachedData.success && cachedData.fresh) {
this._log("Using fresh cache for " + fullPath);
return [2 /*return*/, cachedData.data];
}
Expand All @@ -129,7 +129,7 @@ var APIpeline = (function () {
// If the network request fails, return the cached data if it's valid, a throw an error
if (!res.success) {
if (cachedData.success && cachedData.data) {
this._log("Using stale cache for " + fullPath + " (network request failed)");
this._log("Using " + (cachedData.fresh ? 'fresh' : 'stale') + " cache for " + fullPath + " (network request failed)");
return [2 /*return*/, cachedData.data];
}
else {
Expand Down Expand Up @@ -192,8 +192,8 @@ var APIpeline = (function () {
};
APIpeline.prototype.clearCache = function (service) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
var keysToRemove, _a, _b, _i, serviceName, keysForService, err_3;
var _this = this;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
Expand Down Expand Up @@ -506,8 +506,8 @@ var APIpeline = (function () {
*/
APIpeline.prototype._getAllKeysForService = function (service) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
var keys, serviceDictionaryKey, dictionary, dictionaryKeys, err_8;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
Expand Down Expand Up @@ -588,7 +588,7 @@ var APIpeline = (function () {
});
};
APIpeline.prototype._buildRequestId = function (serviceDefinition, fullPath, fetchHeaders, mergedOptions, // fully merged options
fetchOptions // fetch options
fetchOptions // fetch options
) {
var ignoreHeadersWhenCaching = this._APIOptions.ignoreHeadersWhenCaching ||
serviceDefinition.ignoreHeadersWhenCaching ||
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "apipeline",
"version": "3.0.1",
"version": "3.1.0",
"description": "Feature-rich and pluggable offline-first API wrapper for the browser, node.js and react-native. Easily wire-up your API and make your app work offline in minutes !",
"main": "./dist/index.js",
"types": "./src/index.d.ts",
Expand Down
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const DEFAULT_API_OPTIONS = {
cachePrefix: 'APIPelineCache',
ignoreHeadersWhenCaching: false,
capServices: false,
capLimit: 50
capLimit: 50,
};

const DEFAULT_SERVICE_OPTIONS: IAPIService = {
Expand Down Expand Up @@ -100,7 +100,7 @@ export default class APIpeline {
}
const cachedData = await this._getCachedData(service, requestId, fullPath, shouldUseCache);

if (cachedData.success && cachedData.fresh) {
if ((!this._APIOptions.networkFirst && !options.networkFirst && !serviceDefinition.networkFirst) && cachedData.success && cachedData.fresh) {
this._log(`Using fresh cache for ${fullPath}`);
return cachedData.data;
}
Expand All @@ -115,7 +115,7 @@ export default class APIpeline {
// If the network request fails, return the cached data if it's valid, a throw an error
if (!res.success) {
if (cachedData.success && cachedData.data) {
this._log(`Using stale cache for ${fullPath} (network request failed)`);
this._log(`Using ${cachedData.fresh ? 'fresh' : 'stale'} cache for ${fullPath} (network request failed)`);
return cachedData.data;
} else {
throw new Error(`Cannot fetch data for ${service} online, no cache either.`);
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface IAPIOptions {
ignoreHeadersWhenCaching?: boolean;
capServices?: boolean;
capLimit?: number;
networkFirst?: boolean;
}

export interface IAPIService {
Expand All @@ -30,6 +31,7 @@ export interface IAPIService {
capService?: boolean;
capLimit?: number;
rawData?: boolean;
networkFirst?: boolean;
}

export interface IAPIServices {
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"target": "es5",
"baseUrl": "./",
"lib": ["es2015"],
"lib": ["es2015", "dom"],
"pretty": true,
"jsx": "react-native",
"outDir": "./dist",
Expand Down