cookie-store icon indicating copy to clipboard operation
cookie-store copied to clipboard

Monitoring Cookies feature

Open rmedaer opened this issue 5 years ago • 8 comments

The current Cookie Store API draft defines a Monitoring Cookies feature. It allows user to "observe changes to cookies" and therefore "avoid polling".

As far as I saw, this is not (yet) implemented in this library. It would be great to have this feature.

rmedaer avatar Aug 24 '20 09:08 rmedaer

Yes! This is an amazing feature and I do plan to tackle it soon. I've just been so busy but I will make sure to prioritize this in my todo list. Thanks for opening issue though so we have this feature tracked.

markcellus avatar Aug 24 '20 11:08 markcellus

Hint for documents, where CookieStore class should likely extend EventTarget (yes, there is a polyfill for that too):

const {get, set} = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
Object.defineProperty(Document.prototype, 'cookie', {
  get,
  set(value) {
    const prev = get.call(this);
    set.call(this, value);
    const curr = get.call(this);
    if (prev !== curr) {
      const event = new CustomEvent('change');
      event.changed = [];
      event.deleted = [];
      // add changed/deleted logic
      cookieStore.dispatchEvent(event);
    }
  }
});

The Service Worker variant might not be possible, as if I remember correctly there's no document in there, neither a Document.prototype to pollute, since that won't be reflected ... meaning the change event might also postMessage the service worker messaging changes, but I think it'd be great to have document version first, and see how that works, then think about the SW only patch, because the rest of the code in a SW would be pointless.

I hope any of this hints helps 👋

WebReflection avatar Nov 18 '20 13:11 WebReflection

P.S. to batch multiple changes/delete at once, the dispatch event could be delayed a part

let timer = 0;
const changed = [];
const deleted = [];
const dispatch = () => {
  timer = 0;
  const event = new CustomEvent('change');
  event.changed = changed.splice(0);
  event.deleted = deleted.splice(0);
  cookieStore.dispatchEvent(event);
};
// ... previous code ...
  if (prev !== curr) {
      // populate arrays with more entries
      changed.push( ... );
      deleted.push( ... );
      if (!timer)
        timer = setTimeout(dispatch, 1000 / 60);
    }

Above logic will dispatch batched changes, keeping both list of changes clean per each dispatch and in between dispatches.

WebReflection avatar Nov 18 '20 14:11 WebReflection

P.S.2 if anyone agrees with this proposal I might file a PR although I don't TS much so I hope hints are already helpful, thanks.

WebReflection avatar Nov 18 '20 14:11 WebReflection

This is very helpful @WebReflection. It looks like I may have some time to try to tackle this in the next couple of weeks (if @keithamus and his crew don't get to it before me :wink:)

markcellus avatar Nov 28 '20 15:11 markcellus

Since #116 has been merged, could this one be marked as resolved? And maybe a new version could be released? 😉

iplus26 avatar May 05 '22 03:05 iplus26

My understanding of Cookie Store API is that if you change a cookie from what ever method (Javascript or HTTP response), you'll get a signal through the CookieStore.change_event no matter the "tab" or ServiceWorker you are in.

Despite that the @keithamus ' commit/MR is really useful within a given window scope, I don't think it solves (yet) the feature as equivalent as Cookie Store API described by WICG.

Disclaimer: but all of this is based on my non-tested assumption. Someone to confirm ?

rmedaer avatar May 08 '22 08:05 rmedaer

That's my understanding and interpretation of the spec too. This polyfill can really only do a "best effort" by overriding the document.cookie setter to observe for assignments to that, which will help with library code that uses that field rather than the CookieStore but has limited further use.

I'll add it might be possible to get the events working cross-worker and cross-tab with postMessage and BroadcastChannel, but that'll explode the size of this polyfill and potentially conflict with other listeners to those

keithamus avatar May 09 '22 07:05 keithamus