Giter Site home page Giter Site logo

Comments (17)

mischnic avatar mischnic commented on June 17, 2024 1

It worked for me:

config:

"cache": {
  "runtimeCaching": [
    {
      "urlPattern": "http://localhost:1234/cache.jpg",
      "handler": "staleWhileRevalidate",
      "options": {
        "broadcastUpdate": {
          "channelName": "api-updates"
        }
      }
    }
  ]
}

index.js

const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
        console.log(event);
});

index.html contained <img src="http://localhost:1234/cache.jpg">.
Changing out cache.jpg fires the eventlistener.

Did you use staleWhileRevalidate?

from parcel-plugin-sw-cache.

mischnic avatar mischnic commented on June 17, 2024

You could inject you own code with importScripts: ['push-notifications.js']
However, as the documtation says:

When NOT to use generateSW

You want to use other Service Worker features (i.e. Web Push).
You want to import additional scripts or add additional logic.

So you would be better off using injectManifest (see example).

Here is the documentation from workbox (last is a demo, look at the code in devtools)

from parcel-plugin-sw-cache.

goofblob avatar goofblob commented on June 17, 2024

The inject approach would indeed work. But the API that comes with this plugin actually goes quite a long way.

So for example:
"runtimeCaching": [ { "urlPattern": [ "https://path.to.api" ], "handler": "staleWhileRevalidate", "options": { "cacheName": "app-data", "plugins": [ { "broadcastUpdate": { "channelName": "api-updates" } } ] } }]

This does in fact build successfully. And the output to sw.js is non-breaking. But unfortunately it passes the broadcastUpdate object as is.

So this then would be a feature request, if this is doable. Take this object:

{ "broadcastUpdate": { "channelName": "api-updates" } }

... and produce:

new workbox.broadcastUpdate.Plugin({ channelName: 'api-updates', })

...in the output sw.js as per the documentation you have mentioned.

I think this would be very much in the spirit of this plugin, in that it is producing a fully functional SW out of just the json config in package.json

But you know... only if it's not too much bother :-)

from parcel-plugin-sw-cache.

mischnic avatar mischnic commented on June 17, 2024

This plugin is only an interface to workbox-build, so it basically only calls generateSW or injectManifest. I don't really want to change the serviceworker "manually" after the generation, it seems like this could cause some bugs. If workbox-build doesn't offer enough options for you, please open an issue at https://github.com/GoogleChrome/workbox/issues.

However, I think that this is already in the workbox-build configuration: (from https://developers.google.com/web/tools/workbox/modules/workbox-build#full_generatesw_config)

runtimeCaching: [{
    urlPattern: /api/,
    handler: 'networkFirst',
    options: {
      networkTimeoutSeconds: 10,
      cacheName: 'my-api-cache',
      // Configure the broadcast cache update plugin.
      broadcastUpdate: {
        channelName: 'my-update-channel',
      },
      // Add in any additional plugin logic you need.
      plugins: [
        {cacheDidUpdate: () => /* custom plugin code */}
      ],
    },
  }]

If this code doesn't work, open an issue with workbox and tell them that either the docs are wrong or that something isn't working properly.

from parcel-plugin-sw-cache.

goofblob avatar goofblob commented on June 17, 2024

What I am saying is that some options passed to generateSW work properly, while others do not.

So this works:

    "runtimeCaching": [
      {
        "urlPattern": [
          "https://api"
        ],
        "handler": "staleWhileRevalidate",
        "options": {
          "cacheName": "api"
        }
      }

But this does not:

    "runtimeCaching": [
      {
        "urlPattern": [
          "https://api"
        ],
        "handler": "staleWhileRevalidate",
        "options": {
          "cacheName": "api",
          "broadcastUpdate": {
            "channelName": "my-update-channel",
           }
        }
      }

So the plug-in does not interface with that aspect of generateSW. If given the latter config, the sw.js is not produced in ./dist/

from parcel-plugin-sw-cache.

mischnic avatar mischnic commented on June 17, 2024

I will look into this.

from parcel-plugin-sw-cache.

mischnic avatar mischnic commented on June 17, 2024

Seems to be a problem with the documentation and workbox itself: GoogleChrome/workbox/issues/1289

from parcel-plugin-sw-cache.

mischnic avatar mischnic commented on June 17, 2024

This will get fixed in the next workbox release.
The docs are correct, so your code should work then (couldn't test it yet):

    "runtimeCaching": [
      {
        "urlPattern": [
          "https://api"
        ],
        "handler": "staleWhileRevalidate",
        "options": {
          "cacheName": "api",
          "broadcastUpdate": {
            "channelName": "my-update-channel",
           }
        }
      }

from parcel-plugin-sw-cache.

goofblob avatar goofblob commented on June 17, 2024

Ah... I see.

I will leave this issue open until we hear from upstream and we can test it.

Thanks!

from parcel-plugin-sw-cache.

mischnic avatar mischnic commented on June 17, 2024

There is another issue with workbox 😞 (GoogleChrome/workbox#1334).


@goofblob The fix is in workbox beta.1. Could you please test it?
I get (in the browser):
Uncaught channel-name-required: You must provide a channelName to construct a BroadcastCacheUpdate instance.

"cache": {
		"inDev": true,
		"runtimeCaching": [
			{
				"urlPattern": "https://raw.githubusercontent.com/parcel-bundler/website/01a1f7dd/src/assets/[email protected]",
				"handler": "cacheFirst",
				"options": {
					"broadcastUpdate": {
						"channelName": "my-update-channel"
					}
				}
			}
		]
	}

from parcel-plugin-sw-cache.

goofblob avatar goofblob commented on June 17, 2024

Hmm... I do not get that specific log error, but:

  1. I get Unhandled promise rejection: TypeError: Cannot read property 'error' of undefined at workbox.generateSW.then.catch (~path/node_modules/parcel-plugin-sw-cache/index.js:114:12)

  2. The event does not seem to trigger - I've tested both locally and in a test deploy environment. I can't quite figure out why this happens, because I am not getting any useful error messages, but it might relate to the error message you are getting.

The reason I believe this might be the case is the following. The Workbox spec says that the broadast channel should be registered with the following syntax:

workbox.strategies.staleWhileRevalidate({
    plugins: [
      new workbox.broadcastUpdate.Plugin({
        channelName: 'api-updates',
      })
    ]
  })

But the plugin generates:

workbox.strategies.staleWhileRevalidate({
    plugins: [
      new workbox.broadcastUpdate.Plugin({
        "channelName": "api-updates",
      })
    ]
  })

The difference is "channelName". Ideally that difference in syntax should not make a difference, but given how goofy and finnecky these things can be...

For the sake of completeness, I listed to the broadcast within an onLoad listener on the index page as follows:

            const updatesChannel = new BroadcastChannel('api-updates');
            updatesChannel.addEventListener('message', (event) => {
                const { cacheName, updatedUrl } = event.data.payload;
                console.log("Master List Updated \n");
                console.log(event.data.payload);
            });

This is more or less taken as is from the Workbox documentation.

from parcel-plugin-sw-cache.

mischnic avatar mischnic commented on June 17, 2024

That error of undefined is caused by a change in parcel, so the actual workbox error doesn't get logged.

from parcel-plugin-sw-cache.

mischnic avatar mischnic commented on June 17, 2024

The service worker generation works with

{
	"urlPattern": "...",
	"handler": "cacheFirst",
	"options": {
		"broadcastUpdate": {
			"channelName": "api-updates"
		},
		"cacheableResponse": {
			"statuses": [
				0
			]
		}
	}
}

and workbox-3-beta1.

I however can't test the actual functionality.


The logger is fixed in version 0.2.0

from parcel-plugin-sw-cache.

goofblob avatar goofblob commented on June 17, 2024

Hmm...

In order to test it, we need to listen to the broadcastUpdate event:

const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', (event) => {
        console.log(event.data.payload);
});

Problem is that if I put this in index.html the Parcel bundler complains that it doesn't know what BroadcastChannel is. If I put it lower down in one of my components, it bundles it successfully. But then it does not seem to trigger.

from parcel-plugin-sw-cache.

goofblob avatar goofblob commented on June 17, 2024

Hmm... Still not working for me.

Yes, I did use staleWhileRevalidate.

In package.json I have:

"runtimeCaching": [
      {
        "urlPattern": [
          "https://link.to/api.json"
        ],
        "handler": "staleWhileRevalidate",
        "options": {
          "cacheName": "api",
          "broadcastUpdate": {
            "channelName": "api-update"
          }
        }
      }
]

And in index.js I have:

// LISTEN FOR API UPDATES
    const updatesChannel = new BroadcastChannel('api-update');
    updatesChannel.addEventListener('message', (event) => {
        console.log("API Updated.");
        console.log(event.data.payload);
    });

But when I make changes to the API, and go through the reloads of the site nothing happens. So I get served the stale .json from the Service Worker cache just fine on the first go, and then the refreshed one on the second go. But I do not get the "API Updated." console message on the first go when the .json has been successfully refreshed in the background. Or the payload.

If it works in your tests, then that must mean that the functionality does work. There is something else about my setup that interferes. So if you can see nothing wrong with my code here, I think you can close the issue. I'll just have to bash my head against my code a bit more until it works.

Thanks again for your work on the plugin!

from parcel-plugin-sw-cache.

mischnic avatar mischnic commented on June 17, 2024

Workbox checks the headers to determine whether the file updated, by default ['content-length', 'etag', 'last-modified']; if these headers don't change, the event won't fire.

https://developers.google.com/web/tools/workbox/reference-docs/prerelease/workbox.broadcastUpdate.Plugin

With my example: The event fires on the first reload (after getting the old response) and the new response gets returned on the second reload.

from parcel-plugin-sw-cache.

goofblob avatar goofblob commented on June 17, 2024

Right. That's how it is intended to work.

What happens in my use case is that the update does happen in the background, and that is reflected in the second reload. But the updatesChannel event listener does not get triggered to give me the console output it should on the first load.

My intended use for this is that I want to serve stale data from the service worker cache on the first load, and then automatically update that data without reload when/if the background service worker process finds fresh API data. But if the event does not get triggered, I cannot do this live API data update.

It's not mission critical, but that is pretty much the standard use case for staleWhileRevalidate, and it's bugging me that I have not yet managed to get it working.

But as I say, if the event triggers in your example, there is something I'm doing wrong on my end, so this would not be an issue with the plugin.

from parcel-plugin-sw-cache.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.