Skip to content

Commit

Permalink
fix(sw.js): fix cache store
Browse files Browse the repository at this point in the history
fix cache store that cache svery request on current page
  • Loading branch information
nerdeveloper committed Oct 10, 2019
1 parent f78644b commit e7bc06b
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 182 deletions.
3 changes: 0 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ sudo: false
language: node_js
node_js:
- "10"
branches:
only:
- master
notifications:
email: false

Expand Down
222 changes: 55 additions & 167 deletions public/sw.js
Original file line number Diff line number Diff line change
@@ -1,180 +1,68 @@
/* eslint-disable @typescript-eslint/no-use-before-define */
//This is the service worker with the Advanced caching

const CACHE = "pwabuilder-adv-cache";
const precacheFiles = [
/* Add an array of files to precache for your app */
];

// TODO: replace the following with the correct offline fallback page i.e.: const offlineFallbackPage = "offline.html";
const offlineFallbackPage = "ToDo-replace-this-name.html";

const networkFirstPaths = [
/* Add an array of regex of paths that should go network first */
// Example: /\/api\/.*/
];

const avoidCachingPaths = [
/* Add an array of regex of paths that shouldn't be cached */
// Example: /\/api\/.*/
/\/Images\/.*/,
/\/free\/.*/,
/\/bootstrap\/.*/,
/\/user\/.*/,
/\/ajax\/.*/,
/\/repos\/.*/,
/\/recaptcha\/.*/,
/\/auth\/.*/,
/\/socket.io\/.*/,
/\/avatar\/.*/,
/\/delete\/.*/,
/\/create\/.*/,

"https://source.unsplash.com",
"https://code.jquery.com/jquery-3.2.1.slim.min.js",
const CACHE_NAME = "pwabuilder-adv-cache";
const {INSTALL, FETCH} = {
INSTALL: "install",
FETCH: "fetch",
};
const URLS_TO_CACHE = [
"./",
"./dist/style.css",
"./dist/App.bundle.js",
"./sw.js",
"./pwabuilder.js",
"./manifest.json",
"https://buttons.github.io/buttons.js",
];

function pathComparer(requestUrl, pathRegEx) {
return requestUrl.match(new RegExp(pathRegEx));
}

function comparePaths(requestUrl, pathsArray) {
if (requestUrl) {
for (let index = 0; index < pathsArray.length; index++) {
const pathRegEx = pathsArray[index];
if (pathComparer(requestUrl, pathRegEx)) {
return true;
}
}
const preLoad = async () => {
console.log("Installing web app");
try {
const cache = await caches.open(CACHE_NAME);
const cachedUrls = cache.addAll(URLS_TO_CACHE);
return cachedUrls;
} catch (error) {
console.error(error);
}
};

return false;
}

self.addEventListener("install", function(event) {
console.log("[PWA Builder] Install Event processing");

console.log("[PWA Builder] Skip waiting on install");
self.addEventListener(INSTALL, event => {
self.skipWaiting();

event.waitUntil(
caches.open(CACHE).then(function(cache) {
console.log("[PWA Builder] Caching pages during install");

return cache.addAll(precacheFiles).then(function() {
if (offlineFallbackPage === "ToDo-replace-this-name.html") {
return cache.add(
new Response(
"TODO: Update the value of the offlineFallbackPage constant in the serviceworker.",
),
);
}

return cache.add(offlineFallbackPage);
});
}),
);
});

// Allow sw to control of current page
self.addEventListener("activate", function(event) {
console.log("[PWA Builder] Claiming clients for current page");
event.waitUntil(self.clients.claim());
});

// If any fetch fails, it will look for the request in the cache and serve it from there first
self.addEventListener("fetch", function(event) {
if (event.request.method !== "GET") return;

if (comparePaths(event.request.url, networkFirstPaths)) {
networkFirstFetch(event);
} else {
cacheFirstFetch(event);
}
event.waitUntil(preLoad());
console.log("installed latest version");
});

function cacheFirstFetch(event) {
event.respondWith(
fromCache(event.request).then(
function(response) {
// The response was found in the cache so we responde with it and update the entry

// This is where we call the server to get the newest version of the
// file to use the next time we show view
event.waitUntil(
fetch(event.request).then(function(response) {
return updateCache(event.request, response);
}),
);

return response;
},
function() {
// The response was not found in the cache so we look for it on the server
return fetch(event.request)
.then(function(response) {
// If request was success, add or update it in the cache
event.waitUntil(updateCache(event.request, response.clone()));

return response;
})
.catch(function(error) {
// The following validates that the request was for a navigation to a new document
if (event.request.destination !== "document" || event.request.mode !== "navigate") {
return;
}

console.log("[PWA Builder] Network request failed and no cache." + error);
// Use the precached offline page as fallback
return caches.open(CACHE).then(function(cache) {
cache.match(offlineFallbackPage);
});
});
},
),
);
}

function networkFirstFetch(event) {
event.respondWith(
fetch(event.request)
.then(function(response) {
// If request was success, add or update it in the cache
event.waitUntil(updateCache(event.request, response.clone()));
return response;
})
.catch(function(error) {
console.log("[PWA Builder] Network request Failed. Serving content from cache: " + error);
return fromCache(event.request);
}),
);
}

function fromCache(request) {
// Check to see if you have it in the cache
// Return response
// If not in the cache, then return error page
return caches.open(CACHE).then(function(cache) {
return cache.match(request).then(function(matching) {
if (!matching || matching.status === 404) {
return Promise.reject("no-match");
const makeNetWorkRequest = request =>
new Promise(async (resolve, reject) => {
try {
const networkFetchResponse = await fetch(request);
if (networkFetchResponse.status !== 404) {
resolve(networkFetchResponse);
} else {
throw new Error("no resource found");
}

return matching;
});
} catch (error) {
console.error(error);
reject(error);
}
});
}

function updateCache(request, response) {
if (!comparePaths(request.url, avoidCachingPaths)) {
return caches.open(CACHE).then(function(cache) {
return cache.put(request, response);
});
const returnFromCache = async request => {
try {
const cache = await caches.open(CACHE_NAME);
const cacheItemMatchingNetworkRequest = await cache.match(request);
if (!cacheItemMatchingNetworkRequest || cacheItemMatchingNetworkRequest.status == 404) {
return cache.match("/");
} else {
return cacheItemMatchingNetworkRequest;
}
} catch (error) {
console.error(error);
}

return Promise.resolve();
}
};
self.addEventListener(FETCH, event => {
event.respondWith(
makeNetWorkRequest(event.request).catch(() => {
return returnFromCache(event.request);
}),
);
});

// This is an event that can be fired from your page to tell the SW to update the offline page
self.addEventListener("refreshOffline", function() {
Expand Down
12 changes: 0 additions & 12 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,13 @@ app.use(express.static(path.join(__dirname, "../public")));
app.use(express.json());
app.use(express.urlencoded({extended: true}));

const expiryDate = new Date(Date.now() + 60 * 60 * 1000); // 1 hour
app.use(
session({
name: process.env.SESSION_NAME,
secret: process.env.SECRET,
resave: false,
saveUninitialized: false,
store: new MongoStore({mongooseConnection: mongoose.connection}),
cookie: {
expires: expiryDate,
},
}),
);

Expand All @@ -78,14 +74,6 @@ app.use("/auth", authRouter);
app.get("*", function(req: express.Request, res: express.Response) {
return res.status(404).redirect("/404");
});
// 500 - Any server error
app.use(function(err: any, req: express.Request, res: express.Response, next: express.NextFunction) {
res.status(err.status || 500);
res.render("error", {
message: err.message,
error: {},
});
});

if (app.get("env") === "development") {
app.use(errorHandler());
Expand Down

0 comments on commit e7bc06b

Please sign in to comment.