(Web|Service) Worker import UMD script - How to check context

Asked

Viewed 31 times

0

How to check if the script is being called from a (Web|Service) Worker?

I have been using UMD for a long time and am migrating my projects to support SW ... although I use many features available only on objects window and document many features (utilities) I wish to share in SW (import) but I have to "duplicate" these resources separating them into new files to actually import (importScripts()) because it’s the same thing I do when using Web Workers.

I started to look at it in a more "critical" way and ask myself:

How to identify in which context the code is being executed?

Based on this "context" move to export only one set of utilities... for now what I have based on this:

;((root, factory) => {
    // UMD (Universal Module Definition) [improved]
    if ( typeof define === 'function' && define.amd ) {
        define(['exports'], factory)
    } else if ( typeof exports !== 'undefined' ) {
        factory(exports)
    } else {
        factory(root)
    }
})(this, exports => {    

    let A, B, C    

    const A = 'a'
    const B = 'b'
    const C = 'c'    

    function Plugin(){}
    // prototype
    Plugin.prototype.functionA = function(param) {}
    Plugin.prototype.functionB = function(param) {}
    Plugin.prototype.functionC = function(param) {}    

    exports.CorePlugin = new Plugin()
});

Exporting everything that is "exportable" to the object window:

window.CorePlugin 

How could something like this:

function SWPlugin() {
    // um conjunto de ferramentas exclusivas para Service Worker
}

function WWPlugin() {
    // exportar um conjunto de ferramentas exclusivas para Web Worker
}

function Plugin() {
    // a exportação padrão para `window`
}

// verificar
if ( ISWORKER ) {
    exports.CorePlugin = new WWPlugin()
} else if ( ISSERVICE ) {
    exports.CorePlugin = new SWPlugin()
} else {
    exports.CorePlugin = new Plugin()
}

1 answer

0

Using self I was able to reach the expected result

let IsServiceWorkerContext = ( ('WorkerGlobalScope' in self) && ('ServiceWorkerGlobalScope' in self) ) ? true : false,
    IsWebWorkerContext     = ( ('WorkerGlobalScope' in self) && !('ServiceWorkerGlobalScope' in self) ) ? true : false,
    IsWebBrowserContext    = ( ('window' in self && 'document' in self) && !IsServiceWorkerContext && !IsWebWorkerContext) ? true : false

The only change was to prevent in the global "scope" (of the module) the use of objects such as window, document, among others that are not available in Web Workers and Service Worker.

const noop = () => {}
const dc = IsWebBrowserContext ? document : false,
    wd = IsWebBrowserContext ? window : self,
    nv = wd.navigator,
    ua = nv.userAgent,
    ls = IsWebBrowserContext ? wd.localStorage : noop(),
    ss = IsWebBrowserContext ? wd.sessionStorage : noop(),
    XHR = IsWebBrowserContext ? ( new XMLHttpRequest() ) : noop(),
    FD  = ( new FormData() ),
    // global get APIS...
    indexedDB      = wd.indexedDB || false,
    IDBTransaction = wd.IDBTransaction || false,
    IDBKeyRange    = wd.IDBKeyRange || false,
    URL            = wd.URL || false,
    Geolocation    = IsWebBrowserContext ? nv.geolocation : noop(),
    RegLogout      = IsWebBrowserContext ? nv.sendBeacon : noop(),
    Notifics       = IsWebBrowserContext ? wd.Notification : noop(),
    Fetch          = wd.fetch || false,
    Storage        = IsWebBrowserContext ? wd.Storage : noop(),
    Worker         = IsWebBrowserContext ? wd.Worker : noop(),
    ServiceWorker  = IsWebBrowserContext ? nv.serviceWorker : noop(),
    Promise        = wd.Promise || false

Use logic (check context) in some self-executable functions and "prototype" functions and objects specific to "context".

if ( IsServiceWorkerContext ) {
    Plugin.prototype.example1 = noop()
    Plugin.prototype.example2 = noop()
} else if ( IsWebWorkerContext ) {
    Plugin.prototype.example1 = noop()
    Plugin.prototype.example3 = noop()
} else if ( IsWebBrowserContext ) {
    Plugin.prototype.example4 = noop()
    Plugin.prototype.example5 = noop()
    //...
}
exports.CorePlugin = new Plugin()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.