Skip to content

Commit

Permalink
refactor: change how we process prefetches after SW install, clean up…
Browse files Browse the repository at this point in the history
… code
  • Loading branch information
kkemple committed Jul 24, 2018
1 parent 0d8eabe commit 4fe78a0
Show file tree
Hide file tree
Showing 6 changed files with 595 additions and 418 deletions.
2 changes: 1 addition & 1 deletion packages/gatsby-plugin-offline/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"dependencies": {
"@babel/runtime": "7.0.0-beta.52",
"cheerio": "^1.0.0-rc.2",
"sw-precache": "^5.0.0"
"sw-precache": "^5.2.1"
},
"devDependencies": {
"@babel/cli": "7.0.0-beta.52",
Expand Down
39 changes: 39 additions & 0 deletions packages/gatsby-plugin-offline/src/gatsby-browser.js
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
exports.registerServiceWorker = () => true

let swNotInstalled = true
const pathnameResources = []

exports.onPrefetchPathname = ({ pathname, getResourcesForPathname }) => {
if (swNotInstalled && `serviceWorker` in navigator) {
pathnameResources.push(
new Promise(resolve => {
getResourcesForPathname(pathname, resources => {
resolve(resources)
})
})
)
}
}

exports.onServiceWorkerInstalled = () => {
swNotInstalled = false

// grab nodes from head of document
const nodes = document.querySelectorAll(
`head > script[src], head > link[as=script]`
)

// get all script URLs
const scripts = [].slice
.call(nodes)
.map(node => (node.src ? node.src : node.href))

Promise.all(pathnameResources).then(pageResources => {
pageResources.forEach(pageResource => {
const [script] = scripts.filter(s =>
s.includes(pageResource.page.componentChunkName)
)
fetch(pageResource.page.jsonURL)
fetch(script)
})
})
}
13 changes: 8 additions & 5 deletions packages/gatsby/cache-dir/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const fetchPageResourceMap = () => {
return fetchingPageResourceMapPromise
}

const createJsonURL = jsonName => `${__PATH_PREFIX__}/static/d/${jsonName}.json`

const fetchResource = resourceName => {
// Find resource
let resourceFunction
Expand All @@ -52,9 +54,7 @@ const fetchResource = resourceName => {
} else {
resourceFunction = () => {
const fetchPromise = new Promise((resolve, reject) => {
const url = `${__PATH_PREFIX__}/static/d/${
jsonDataPaths[resourceName]
}.json`
const url = createJsonURL(jsonDataPaths[resourceName])
var req = new XMLHttpRequest()
req.open(`GET`, url, true)
req.withCredentials = true
Expand Down Expand Up @@ -198,7 +198,10 @@ const queue = {
// Tell plugins with custom prefetching logic that they should start
// prefetching this path.
if (!prefetchTriggered[path]) {
apiRunner(`onPrefetchPathname`, { pathname: path })
apiRunner(`onPrefetchPathname`, {
pathname: path,
getResourcesForPathname: queue.getResourcesForPathname,
})
prefetchTriggered[path] = true
}

Expand Down Expand Up @@ -355,7 +358,7 @@ const queue = {
getResourceModule(page.jsonName),
]).then(([component, json]) => {
const pageResources = { component, json, page }

pageResources.page.jsonURL = createJsonURL(jsonDataPaths[page.jsonName])
pathScriptsCache[path] = pageResources
cb(pageResources)

Expand Down
12 changes: 10 additions & 2 deletions packages/gatsby/cache-dir/register-service-worker.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import emitter from "./emitter"
import { apiRunner } from "./api-runner-browser"

if (`serviceWorker` in navigator) {
navigator.serviceWorker
.register(`${__PATH_PREFIX__}/sw.js`)
.then(function(reg) {
reg.addEventListener(`updatefound`, () => {
apiRunner(`onServiceWorkerUpdateFound`)
// The updatefound event implies that reg.installing is set; see
// https://w3c.github.io/ServiceWorker/#service-worker-registration-updatefound-event
const installingWorker = reg.installing
Expand All @@ -21,12 +22,19 @@ if (`serviceWorker` in navigator) {
// At this point, everything has been precached.
// It's the perfect time to display a "Content is cached for offline use." message.
console.log(`Content is now available offline!`)
emitter.emit(`sw:installed`)

// post to service worker that install is complete
apiRunner(`onServiceWorkerInstalled`)
}
break

case `redundant`:
console.error(`The installing service worker became redundant.`)
apiRunner(`onServiceWorkerRedundant`)
break

case `active`:
apiRunner(`onServiceWorkerActive`)
break
}
})
Expand Down
21 changes: 21 additions & 0 deletions packages/gatsby/src/utils/api-browser-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ exports.wrapRootComponent = true
* for plugins with custom prefetching logic.
* @param {object} $0
* @param {object} $0.pathname The pathname whose resources should now be prefetched
* @param {object} $0.getResourcesForPathname Function for fetching resources related to pathname
*/
exports.onPrefetchPathname = true

Expand All @@ -126,3 +127,23 @@ exports.disableCorePrefetching = true
* };
*/
exports.replaceHydrateFunction = true

/**
* Inform plugins of when a service worker has been installed.
*/
exports.onServiceWorkerInstalled = true

/**
* Inform plugins of when a service worker has an update available.
*/
exports.onServiceWorkerUpdateFound = true

/**
* Inform plugins of when a service worker has become active.
*/
exports.onServiceWorkerActive = true

/**
* Inform plugins of when a service worker is redundant.
*/
exports.onServiceWorkerRedundant = true
Loading

0 comments on commit 4fe78a0

Please sign in to comment.