UNPKG

@builder.io/partytown

Version:

Relocate resource intensive third-party scripts off of the main thread and into a web worker.

73 lines (67 loc) 4.72 kB
'use strict'; const PartytownSnippet = "/* Partytown 0.10.3-dev1734732935152 - MIT builder.io */\nconst t={preserveBehavior:!1},e=e=>{if(\"string\"==typeof e)return[e,t];const[n,r=t]=e;return[n,{...t,...r}]},n=Object.freeze((t=>{const e=new Set;let n=[];do{Object.getOwnPropertyNames(n).forEach((t=>{\"function\"==typeof n[t]&&e.add(t)}))}while((n=Object.getPrototypeOf(n))!==Object.prototype);return Array.from(e)})());!function(t,r,o,i,a,s,c,d,l,p,u=t,f){function h(){f||(f=1,\"/\"==(c=(s.lib||\"/~partytown/\")+(s.debug?\"debug/\":\"\"))[0]&&(l=r.querySelectorAll('script[type=\"text/partytown\"]'),i!=t?i.dispatchEvent(new CustomEvent(\"pt1\",{detail:t})):(d=setTimeout(v,999999999),r.addEventListener(\"pt0\",w),a?y(1):o.serviceWorker?o.serviceWorker.register(c+(s.swPath||\"partytown-sw.js\"),{scope:c}).then((function(t){t.active?y():t.installing&&t.installing.addEventListener(\"statechange\",(function(t){\"activated\"==t.target.state&&y()}))}),console.error):v())))}function y(e){p=r.createElement(e?\"script\":\"iframe\"),t._pttab=Date.now(),e||(p.style.display=\"block\",p.style.width=\"0\",p.style.height=\"0\",p.style.border=\"0\",p.style.visibility=\"hidden\",p.setAttribute(\"aria-hidden\",!0)),p.src=c+\"partytown-\"+(e?\"atomics.js?v=0.10.3-dev1734732935152\":\"sandbox-sw.html?\"+t._pttab),r.querySelector(s.sandboxParent||\"body\").appendChild(p)}function v(n,o){for(w(),i==t&&(s.forward||[]).map((function(n){const[r]=e(n);delete t[r.split(\".\")[0]]})),n=0;n<l.length;n++)(o=r.createElement(\"script\")).innerHTML=l[n].innerHTML,o.nonce=s.nonce,r.head.appendChild(o);p&&p.parentNode.removeChild(p)}function w(){clearTimeout(d)}s=t.partytown||{},i==t&&(s.forward||[]).map((function(r){const[o,{preserveBehavior:i}]=e(r);u=t,o.split(\".\").map((function(e,r,o){var a;u=u[o[r]]=r+1<o.length?u[o[r]]||(a=o[r+1],n.includes(a)?[]:{}):(()=>{let e=null;if(i){const{methodOrProperty:n,thisObject:r}=((t,e)=>{let n=t;for(let t=0;t<e.length-1;t+=1)n=n[e[t]];return{thisObject:n,methodOrProperty:e.length>0?n[e[e.length-1]]:void 0}})(t,o);\"function\"==typeof n&&(e=(...t)=>n.apply(r,...t))}return function(){let n;return e&&(n=e(arguments)),(t._ptf=t._ptf||[]).push(o,arguments),n}})()}))})),\"complete\"==r.readyState?h():(t.addEventListener(\"DOMContentLoaded\",h),t.addEventListener(\"load\",h))}(window,document,navigator,top,window.crossOriginIsolated);"; /** * The `type` attribute for Partytown scripts, which does two things: * * 1. Prevents the `<script>` from executing on the main thread. * 2. Is used as a selector so the Partytown library can find all scripts to execute in a web worker. * * @public */ const SCRIPT_TYPE = `text/partytown`; const getMethods = (obj) => { const properties = new Set(); let currentObj = obj; do { Object.getOwnPropertyNames(currentObj).forEach((item) => { if (typeof currentObj[item] === 'function') { properties.add(item); } }); } while ((currentObj = Object.getPrototypeOf(currentObj)) !== Object.prototype); return Array.from(properties); }; Object.freeze(getMethods([])); function serializeConfig(config) { return JSON.stringify(config, (key, value) => { if (typeof value === 'function') { value = String(value); if (value.startsWith(key + '(')) { value = 'function ' + value; } } if (key === 'loadScriptsOnMainThread') { value = value.map((scriptUrl) => Array.isArray(scriptUrl) ? scriptUrl : [ typeof scriptUrl === 'string' ? 'string' : 'regexp', typeof scriptUrl === 'string' ? scriptUrl : scriptUrl.source, ]); } return value; }); } const createSnippet = (config, snippetCode) => { const { forward = [], ...filteredConfig } = config || {}; const configStr = serializeConfig(filteredConfig); return [ `!(function(w,p,f,c){`, `if(!window.crossOriginIsolated && !navigator.serviceWorker) return;`, Object.keys(filteredConfig).length > 0 ? `c=w[p]=Object.assign(w[p]||{},${configStr});` : `c=w[p]=w[p]||{};`, `c[f]=(c[f]||[])`, forward.length > 0 ? `.concat(${JSON.stringify(forward)})` : ``, `})(window,'partytown','forward');`, snippetCode, ].join(''); }; /** * Function that returns the Partytown snippet as a string, which can be * used as the innerHTML of the inlined Partytown script in the head. * * @public */ const partytownSnippet = (config) => createSnippet(config, PartytownSnippet); exports.SCRIPT_TYPE = SCRIPT_TYPE; exports.partytownSnippet = partytownSnippet;