1 |
|
2 | (window => {
|
3 | const isPromise = v => "object" == typeof v && v && v.then;
|
4 | const noop = () => true;
|
5 | const len = obj => obj.length;
|
6 | const getConstructorName = obj => {
|
7 | try {
|
8 | return obj.constructor.name;
|
9 | } catch (e) {}
|
10 | return "";
|
11 | };
|
12 | const startsWith = (str, val) => str.startsWith(val);
|
13 | const isValidMemberName = memberName => !(startsWith(memberName, "webkit") || startsWith(memberName, "toJSON") || startsWith(memberName, "constructor") || startsWith(memberName, "toString") || startsWith(memberName, "_"));
|
14 | const randomId = () => Math.round(999999999 * Math.random() + 4);
|
15 | const InstanceIdKey = Symbol();
|
16 | const CreatedKey = Symbol();
|
17 | const instances = new Map;
|
18 | const mainRefs = new Map;
|
19 | const winCtxs = {};
|
20 | const windowIds = new WeakMap;
|
21 | const getAndSetInstanceId = (instance, instanceId, nodeName) => {
|
22 | if (instance) {
|
23 | if (instance === instance.window) {
|
24 | return 0;
|
25 | }
|
26 | if ("#document" === (nodeName = instance.nodeName)) {
|
27 | return 1;
|
28 | }
|
29 | if ("HTML" === nodeName) {
|
30 | return 2;
|
31 | }
|
32 | if ("HEAD" === nodeName) {
|
33 | return 3;
|
34 | }
|
35 | if ("BODY" === nodeName) {
|
36 | return 4;
|
37 | }
|
38 | "number" != typeof (instanceId = instance[InstanceIdKey]) && setInstanceId(instance, instanceId = randomId());
|
39 | return instanceId;
|
40 | }
|
41 | return -1;
|
42 | };
|
43 | const getInstance = (winId, instanceId, winCtx, win, doc) => {
|
44 | winCtx = winCtxs[winId];
|
45 | if (winCtx) {
|
46 | win = winCtx.$window$;
|
47 | if (win) {
|
48 | doc = win.document;
|
49 | return 0 === instanceId ? win : 1 === instanceId ? doc : 2 === instanceId ? doc.documentElement : 3 === instanceId ? doc.head : 4 === instanceId ? doc.body : instances.get(instanceId);
|
50 | }
|
51 | }
|
52 | };
|
53 | const setInstanceId = (instance, instanceId, now) => {
|
54 | if (instance) {
|
55 | instances.set(instanceId, instance);
|
56 | instance[InstanceIdKey] = instanceId;
|
57 | instance[CreatedKey] = now = Date.now();
|
58 | if (now > lastCleanup + 5e3) {
|
59 | instances.forEach(((storedInstance, instanceId) => {
|
60 | storedInstance[CreatedKey] < lastCleanup && storedInstance.nodeType && !storedInstance.isConnected && instances.delete(instanceId);
|
61 | }));
|
62 | lastCleanup = now;
|
63 | }
|
64 | }
|
65 | };
|
66 | let lastCleanup = 0;
|
67 | const mainWindow = window.parent;
|
68 | const doc = document;
|
69 | const config = mainWindow.partytown || {};
|
70 | const libPath = (config.lib || "/~partytown/") + "debug/";
|
71 | const logMain = msg => {
|
72 | console.debug.apply(console, [ "%cMain 🌎", "background: #717171; color: white; padding: 2px 3px; border-radius: 2px; font-size: 0.8em;", msg ]);
|
73 | };
|
74 | const winIds = [];
|
75 | const normalizedWinId = winId => {
|
76 | winIds.includes(winId) || winIds.push(winId);
|
77 | return winIds.indexOf(winId) + 1;
|
78 | };
|
79 | const serializeForWorker = ($winId$, value, added, type, cstrName) => void 0 !== value && (type = typeof value) ? "string" === type || "number" === type || "boolean" === type || null == value ? [ 0, value ] : "function" === type ? [ 6 ] : (added = added || new Set) && Array.isArray(value) ? added.has(value) ? [ 1, [] ] : added.add(value) && [ 1, value.map((v => serializeForWorker($winId$, v, added))) ] : "object" === type ? "" === (cstrName = getConstructorName(value)) ? [ 2, {} ] : "Window" === cstrName ? [ 3, {
|
80 | $winId$: $winId$,
|
81 | $instanceId$: 0
|
82 | } ] : "HTMLCollection" === cstrName || "NodeList" === cstrName ? [ 7, Array.from(value).map((v => serializeForWorker($winId$, v, added)[1])) ] : "Event" === cstrName ? [ 5, serializeObjectForWorker($winId$, value, added) ] : "CSSRuleList" === cstrName ? [ 12, Array.from(value).map(serializeCssRuleForWorker) ] : startsWith(cstrName, "CSS") && cstrName.endsWith("Rule") ? [ 11, serializeCssRuleForWorker(value) ] : "CSSStyleDeclaration" === cstrName ? [ 13, serializeObjectForWorker($winId$, value, added) ] : "Attr" === cstrName ? [ 10, [ value.name, value.value ] ] : value.nodeType ? [ 3, {
|
83 | $winId$: $winId$,
|
84 | $instanceId$: getAndSetInstanceId(value),
|
85 | $nodeName$: value.nodeName
|
86 | } ] : [ 2, serializeObjectForWorker($winId$, value, added, true, true) ] : void 0 : value;
|
87 | const serializeObjectForWorker = (winId, obj, added, includeFunctions, includeEmptyStrings, serializedObj, propName, propValue) => {
|
88 | serializedObj = {};
|
89 | if (!added.has(obj)) {
|
90 | added.add(obj);
|
91 | for (propName in obj) {
|
92 | if (isValidMemberName(propName)) {
|
93 | propValue = obj[propName];
|
94 | (includeFunctions || "function" != typeof propValue) && (includeEmptyStrings || "" !== propValue) && (serializedObj[propName] = serializeForWorker(winId, propValue, added));
|
95 | }
|
96 | }
|
97 | }
|
98 | return serializedObj;
|
99 | };
|
100 | const serializeCssRuleForWorker = cssRule => {
|
101 | let obj = {};
|
102 | let key;
|
103 | for (key in cssRule) {
|
104 | validCssRuleProps.includes(key) && (obj[key] = cssRule[key]);
|
105 | }
|
106 | return obj;
|
107 | };
|
108 | const deserializeFromWorker = (worker, serializedTransfer, serializedType, serializedValue) => {
|
109 | if (serializedTransfer) {
|
110 | serializedType = serializedTransfer[0];
|
111 | serializedValue = serializedTransfer[1];
|
112 | return 0 === serializedType ? serializedValue : 4 === serializedType ? deserializeRefFromWorker(worker, serializedValue) : 1 === serializedType ? serializedValue.map((v => deserializeFromWorker(worker, v))) : 3 === serializedType ? getInstance(serializedValue.$winId$, serializedValue.$instanceId$) : 5 === serializedType ? constructEvent(deserializeObjectFromWorker(worker, serializedValue)) : 2 === serializedType ? deserializeObjectFromWorker(worker, serializedValue) : 8 === serializedType ? serializedValue : 9 === serializedType ? new window[serializedTransfer[2]](serializedValue) : void 0;
|
113 | }
|
114 | };
|
115 | const deserializeRefFromWorker = (worker, {$winId$: $winId$, $instanceId$: $instanceId$, $refId$: $refId$}, ref) => {
|
116 | ref = mainRefs.get($refId$);
|
117 | if (!ref) {
|
118 | ref = function(...args) {
|
119 | const refHandlerData = {
|
120 | $instanceId$: $instanceId$,
|
121 | $refId$: $refId$,
|
122 | $thisArg$: serializeForWorker($winId$, this),
|
123 | $args$: serializeForWorker($winId$, args)
|
124 | };
|
125 | worker.postMessage([ 7, refHandlerData ]);
|
126 | };
|
127 | mainRefs.set($refId$, ref);
|
128 | }
|
129 | return ref;
|
130 | };
|
131 | const constructEvent = eventProps => new ("detail" in eventProps ? CustomEvent : Event)(eventProps.type, eventProps);
|
132 | const deserializeObjectFromWorker = (worker, serializedValue, obj, key) => {
|
133 | obj = {};
|
134 | for (key in serializedValue) {
|
135 | obj[key] = deserializeFromWorker(worker, serializedValue[key]);
|
136 | }
|
137 | return obj;
|
138 | };
|
139 | const validCssRuleProps = "cssText,selectorText,href,media,namespaceURI,prefix,name,conditionText".split(",");
|
140 | const mainAccessHandler = async (worker, accessReq) => {
|
141 | let accessRsp = {
|
142 | $msgId$: accessReq.$msgId$
|
143 | };
|
144 | let totalTasks = len(accessReq.$tasks$);
|
145 | let i = 0;
|
146 | let task;
|
147 | let winId;
|
148 | let applyPath;
|
149 | let instance;
|
150 | let rtnValue;
|
151 | for (;i < totalTasks; i++) {
|
152 | try {
|
153 | task = accessReq.$tasks$[i];
|
154 | winId = task.$winId$;
|
155 | applyPath = task.$applyPath$;
|
156 | winCtxs[winId] || await new Promise((resolve => {
|
157 | let check = 0;
|
158 | let callback = () => {
|
159 | winCtxs[winId] || check++ > 999 ? resolve() : setTimeout(callback, 9);
|
160 | };
|
161 | callback();
|
162 | }));
|
163 | if (1 === applyPath[0] && applyPath[1] in winCtxs[winId].$window$) {
|
164 | setInstanceId(new winCtxs[winId].$window$[applyPath[1]](...deserializeFromWorker(worker, applyPath[2])), task.$instanceId$);
|
165 | } else {
|
166 | instance = getInstance(winId, task.$instanceId$);
|
167 | if (instance) {
|
168 | rtnValue = applyToInstance(worker, instance, applyPath, task.$groupedGetters$);
|
169 | task.$assignInstanceId$ && setInstanceId(rtnValue, task.$assignInstanceId$);
|
170 | if (isPromise(rtnValue)) {
|
171 | rtnValue = await rtnValue;
|
172 | accessRsp.$isPromise$ = true;
|
173 | }
|
174 | accessRsp.$rtnValue$ = serializeForWorker(winId, rtnValue);
|
175 | } else {
|
176 | accessRsp.$error$ = `Error finding instance "${task.$instanceId$}" on window ${normalizedWinId(winId)} (${winId})`;
|
177 | console.error(accessRsp.$error$, task);
|
178 | }
|
179 | }
|
180 | } catch (e) {
|
181 | i === totalTasks - 1 ? accessRsp.$error$ = String(e.stack || e) : console.error(e);
|
182 | }
|
183 | }
|
184 | return accessRsp;
|
185 | };
|
186 | const applyToInstance = (worker, instance, applyPath, groupedGetters) => {
|
187 | let i = 0;
|
188 | let l = len(applyPath);
|
189 | let next;
|
190 | let current;
|
191 | let previous;
|
192 | let args;
|
193 | let groupedRtnValues;
|
194 | for (;i < l; i++) {
|
195 | current = applyPath[i];
|
196 | next = applyPath[i + 1];
|
197 | previous = applyPath[i - 1];
|
198 | try {
|
199 | if (!Array.isArray(next)) {
|
200 | if ("string" == typeof current || "number" == typeof current) {
|
201 | if (i + 1 === l && groupedGetters) {
|
202 | groupedRtnValues = {};
|
203 | groupedGetters.map((propName => groupedRtnValues[propName] = instance[propName]));
|
204 | return groupedRtnValues;
|
205 | }
|
206 | instance = instance[current];
|
207 | } else {
|
208 | if (0 === next) {
|
209 | instance[previous] = deserializeFromWorker(worker, current);
|
210 | return;
|
211 | }
|
212 | if ("function" == typeof instance[previous]) {
|
213 | args = deserializeFromWorker(worker, current);
|
214 | "insertRule" === previous && args[1] > len(instance.cssRules) && (args[1] = len(instance.cssRules));
|
215 | instance = instance[previous].apply(instance, args);
|
216 | if ("play" === previous) {
|
217 | return Promise.resolve();
|
218 | }
|
219 | }
|
220 | }
|
221 | }
|
222 | } catch (err) {
|
223 | console.debug("Non-blocking setter error:", err);
|
224 | }
|
225 | }
|
226 | return instance;
|
227 | };
|
228 | const registerWindow = (worker, $winId$, $window$) => {
|
229 | if (!windowIds.has($window$)) {
|
230 | windowIds.set($window$, $winId$);
|
231 | const doc = $window$.document;
|
232 | const history = $window$.history;
|
233 | const envData = {
|
234 | $winId$: $winId$,
|
235 | $parentWinId$: windowIds.get($window$.parent),
|
236 | $url$: doc.baseURI
|
237 | };
|
238 | const sendInitEnvData = () => worker.postMessage([ 3, envData ]);
|
239 | const pushState = history.pushState.bind(history);
|
240 | const replaceState = history.replaceState.bind(history);
|
241 | const onLocationChange = () => setTimeout((() => worker.postMessage([ 11, $winId$, doc.baseURI ])));
|
242 | history.pushState = (data, _, url) => {
|
243 | pushState(data, _, url);
|
244 | onLocationChange();
|
245 | };
|
246 | history.replaceState = (data, _, url) => {
|
247 | replaceState(data, _, url);
|
248 | onLocationChange();
|
249 | };
|
250 | $window$.addEventListener("popstate", onLocationChange);
|
251 | $window$.addEventListener("hashchange", onLocationChange);
|
252 | winCtxs[$winId$] = {
|
253 | $winId$: $winId$,
|
254 | $window$: $window$
|
255 | };
|
256 | winCtxs[$winId$].$startTime$ = performance.now();
|
257 | {
|
258 | const winType = envData.$winId$ === envData.$parentWinId$ ? "top" : "iframe";
|
259 | logMain(`Registered ${winType} window ${normalizedWinId($winId$)} (${$winId$})`);
|
260 | }
|
261 | "complete" === doc.readyState ? sendInitEnvData() : $window$.addEventListener("load", sendInitEnvData);
|
262 | }
|
263 | };
|
264 | const readNextScript = (worker, winCtx) => {
|
265 | let $winId$ = winCtx.$winId$;
|
266 | let win = winCtx.$window$;
|
267 | let doc = win.document;
|
268 | let scriptSelector = 'script[type="text/partytown"]:not([data-ptid]):not([data-pterror])';
|
269 | let scriptElm = doc.querySelector('script[type="text/partytown"]:not([data-ptid]):not([data-pterror]):not([async]):not([defer])');
|
270 | let $instanceId$;
|
271 | let scriptData;
|
272 | scriptElm || (scriptElm = doc.querySelector(scriptSelector));
|
273 | if (scriptElm) {
|
274 | scriptElm.dataset.ptid = $instanceId$ = getAndSetInstanceId(scriptElm, $winId$);
|
275 | scriptData = {
|
276 | $winId$: $winId$,
|
277 | $instanceId$: $instanceId$
|
278 | };
|
279 | if (scriptElm.src) {
|
280 | scriptData.$url$ = scriptElm.src;
|
281 | scriptData.$orgUrl$ = scriptElm.dataset.ptsrc || scriptElm.src;
|
282 | } else {
|
283 | scriptData.$content$ = scriptElm.innerHTML;
|
284 | }
|
285 | worker.postMessage([ 6, scriptData ]);
|
286 | } else if (!winCtx.$isInitialized$) {
|
287 | winCtx.$isInitialized$ = 1;
|
288 | ((worker, $winId$, win) => {
|
289 | let queuedForwardCalls = win._ptf;
|
290 | let forwards = (win.partytown || {}).forward || [];
|
291 | let i;
|
292 | let mainForwardFn;
|
293 | let forwardCall = ($forward$, args) => worker.postMessage([ 8, {
|
294 | $winId$: $winId$,
|
295 | $forward$: $forward$,
|
296 | $args$: serializeForWorker($winId$, Array.from(args))
|
297 | } ]);
|
298 | win._ptf = void 0;
|
299 | forwards.map((forwardProps => {
|
300 | mainForwardFn = win;
|
301 | forwardProps.split(".").map(((_, i, arr) => {
|
302 | mainForwardFn = mainForwardFn[arr[i]] = i + 1 < len(arr) ? mainForwardFn[arr[i]] || ("push" === arr[i + 1] ? [] : {}) : (...args) => forwardCall(arr, args);
|
303 | }));
|
304 | }));
|
305 | if (queuedForwardCalls) {
|
306 | for (i = 0; i < len(queuedForwardCalls); i += 2) {
|
307 | forwardCall(queuedForwardCalls[i], queuedForwardCalls[i + 1]);
|
308 | }
|
309 | }
|
310 | })(worker, $winId$, win);
|
311 | doc.dispatchEvent(new CustomEvent("pt0"));
|
312 | {
|
313 | const winType = win === win.top ? "top" : "iframe";
|
314 | logMain(`Executed ${winType} window ${normalizedWinId($winId$)} environment scripts in ${(performance.now() - winCtx.$startTime$).toFixed(1)}ms`);
|
315 | }
|
316 | worker.postMessage([ 4, $winId$ ]);
|
317 | }
|
318 | };
|
319 | const onMessageFromWebWorker = (worker, msg, winCtx) => {
|
320 | if (2 === msg[0]) {
|
321 | registerWindow(worker, randomId(), mainWindow);
|
322 | } else {
|
323 | winCtx = winCtxs[msg[1]];
|
324 | winCtx && (6 === msg[0] ? readNextScript(worker, winCtx) : 5 === msg[0] && ((worker, winCtx, instanceId, errorMsg, script) => {
|
325 | script = winCtx.$window$.document.querySelector(`[data-ptid="${instanceId}"]`);
|
326 | script && (errorMsg ? script.dataset.pterror = errorMsg : script.type += "-x");
|
327 | readNextScript(worker, winCtx);
|
328 | })(worker, winCtx, msg[2], msg[3]));
|
329 | }
|
330 | };
|
331 | const readImplementation = (cstrName, impl, memberName) => {
|
332 | let interfaceMembers = [];
|
333 | let interfaceInfo = [ cstrName, "Object", interfaceMembers ];
|
334 | for (memberName in impl) {
|
335 | readImplementationMember(interfaceMembers, impl, memberName);
|
336 | }
|
337 | return interfaceInfo;
|
338 | };
|
339 | const readOwnImplementation = (interfaces, cstrName, CstrPrototype, impl, interfaceType) => {
|
340 | if ("Object" !== cstrName && !interfaces.some((i => i[0] === cstrName))) {
|
341 | const SuperCstr = Object.getPrototypeOf(CstrPrototype);
|
342 | const superCstrName = getConstructorName(SuperCstr);
|
343 | const interfaceMembers = [];
|
344 | readOwnImplementation(interfaces, superCstrName, SuperCstr, impl, interfaceType);
|
345 | Object.keys(Object.getOwnPropertyDescriptors(CstrPrototype)).map((memberName => readImplementationMember(interfaceMembers, impl, memberName)));
|
346 | interfaces.push([ cstrName, superCstrName, interfaceMembers, interfaceType, impl.nodeName ]);
|
347 | }
|
348 | };
|
349 | const readImplementationMember = (interfaceMembers, implementation, memberName, value, memberType, cstrName) => {
|
350 | try {
|
351 | if (isValidMemberName(memberName) && isNaN(memberName[0]) && "all" !== memberName) {
|
352 | value = implementation[memberName];
|
353 | memberType = typeof value;
|
354 | if ("function" === memberType) {
|
355 | (String(value).includes("[native") || Object.getPrototypeOf(implementation)[memberName]) && interfaceMembers.push([ memberName, 5 ]);
|
356 | } else if ("object" === memberType && null != value) {
|
357 | cstrName = getConstructorName(value);
|
358 | "Object" !== cstrName && self[cstrName] && interfaceMembers.push([ memberName, value.nodeType || cstrName ]);
|
359 | } else {
|
360 | "symbol" !== memberType && (memberName.toUpperCase() === memberName ? interfaceMembers.push([ memberName, 6, value ]) : interfaceMembers.push([ memberName, 6 ]));
|
361 | }
|
362 | }
|
363 | } catch (e) {
|
364 | console.warn(e);
|
365 | }
|
366 | };
|
367 | const htmlConstructorToTagMap = {
|
368 | Anchor: "A",
|
369 | DList: "DL",
|
370 | Image: "IMG",
|
371 | OList: "OL",
|
372 | Paragraph: "P",
|
373 | TableCaption: "CAPTION",
|
374 | TableCell: "TD",
|
375 | TableCol: "COLGROUP",
|
376 | TableRow: "TR",
|
377 | TableSection: "TBODY",
|
378 | UList: "UL"
|
379 | };
|
380 | const getHtmlTagNameFromConstructor = t => {
|
381 | t = t.slice(4).replace("Element", "");
|
382 | return htmlConstructorToTagMap[t] || t;
|
383 | };
|
384 | const readStorage = storageName => {
|
385 | let items = [];
|
386 | let i = 0;
|
387 | let l = len(mainWindow[storageName]);
|
388 | let key;
|
389 | for (;i < l; i++) {
|
390 | key = mainWindow[storageName].key(i);
|
391 | items.push([ key, mainWindow[storageName].getItem(key) ]);
|
392 | }
|
393 | return items;
|
394 | };
|
395 | let worker;
|
396 | (async receiveMessage => {
|
397 | const sharedDataBuffer = new SharedArrayBuffer(1073741824);
|
398 | const sharedData = new Int32Array(sharedDataBuffer);
|
399 | return (worker, msg) => {
|
400 | const msgType = msg[0];
|
401 | const accessReq = msg[1];
|
402 | if (0 === msgType) {
|
403 | const initData = (() => {
|
404 | const startTime = performance.now();
|
405 | const docImpl = doc.implementation.createHTMLDocument();
|
406 | const textNode = docImpl.createTextNode("");
|
407 | const comment = docImpl.createComment("");
|
408 | const frag = docImpl.createDocumentFragment();
|
409 | const svg = docImpl.createElementNS("http://www.w3.org/2000/svg", "svg");
|
410 | const mutationObserver = new MutationObserver(noop);
|
411 | const resizeObserver = new ResizeObserver(noop);
|
412 | const perf = mainWindow.performance;
|
413 | const screen = mainWindow.screen;
|
414 | const elms = Object.getOwnPropertyNames(mainWindow).filter((c => /^HTML.+Element$/.test(c))).map((htmlCstrName => [ docImpl.createElement(getHtmlTagNameFromConstructor(htmlCstrName)) ]));
|
415 | const elm = elms[0][0];
|
416 | const impls = [ [ mainWindow.history ], [ perf ], [ perf.navigation ], [ perf.timing ], [ screen ], [ screen.orientation ], [ mutationObserver, 12 ], [ resizeObserver, 12 ], [ textNode ], [ comment ], [ frag ], [ elm ], [ elm.attributes ], [ elm.classList ], [ elm.dataset ], [ elm.style ], [ svg ], [ docImpl ], [ docImpl.doctype ], ...elms ].filter((implData => implData[0])).map((implData => {
|
417 | const impl = implData[0];
|
418 | const interfaceType = implData[1];
|
419 | const cstrName = getConstructorName(impl);
|
420 | const CstrPrototype = mainWindow[cstrName].prototype;
|
421 | return [ cstrName, CstrPrototype, impl, interfaceType ];
|
422 | }));
|
423 | const $interfaces$ = [ readImplementation("Window", mainWindow), readImplementation("Node", textNode) ];
|
424 | const $config$ = JSON.stringify(config, ((k, v) => {
|
425 | if ("function" == typeof v) {
|
426 | v = String(v);
|
427 | v.startsWith(k + "(") && (v = "function " + v);
|
428 | }
|
429 | return v;
|
430 | }));
|
431 | const initWebWorkerData = {
|
432 | $config$: $config$,
|
433 | $libPath$: new URL(libPath, mainWindow.location) + "",
|
434 | $interfaces$: $interfaces$,
|
435 | $localStorage$: readStorage("localStorage"),
|
436 | $sessionStorage$: readStorage("sessionStorage")
|
437 | };
|
438 | impls.map((([cstrName, CstrPrototype, impl, intefaceType]) => readOwnImplementation($interfaces$, cstrName, CstrPrototype, impl, intefaceType)));
|
439 | logMain(`Read ${$interfaces$.length} interfaces in ${(performance.now() - startTime).toFixed(1)}ms`);
|
440 | return initWebWorkerData;
|
441 | })();
|
442 | initData.$sharedDataBuffer$ = sharedDataBuffer;
|
443 | worker.postMessage([ 1, initData ]);
|
444 | } else {
|
445 | 9 === msgType ? receiveMessage(accessReq, (accessRsp => {
|
446 | const stringifiedData = JSON.stringify(accessRsp);
|
447 | const stringifiedDataLength = stringifiedData.length;
|
448 | for (let i = 0; i < stringifiedDataLength; i++) {
|
449 | sharedData[i + 1] = stringifiedData.charCodeAt(i);
|
450 | }
|
451 | sharedData[0] = stringifiedDataLength;
|
452 | Atomics.notify(sharedData, 0);
|
453 | })) : onMessageFromWebWorker(worker, msg);
|
454 | }
|
455 | };
|
456 | })(((accessReq, responseCallback) => mainAccessHandler(worker, accessReq).then(responseCallback))).then((onMessageHandler => {
|
457 | if (onMessageHandler) {
|
458 | worker = new Worker(libPath + "partytown-ww-atomics.js", {
|
459 | name: "Partytown 🎉"
|
460 | });
|
461 | worker.onmessage = ev => {
|
462 | const msg = ev.data;
|
463 | 10 === msg[0] ? mainAccessHandler(worker, msg[1]) : onMessageHandler(worker, msg);
|
464 | };
|
465 | logMain("Created Partytown web worker (0.2.1)");
|
466 | worker.onerror = ev => console.error("Web Worker Error", ev);
|
467 | mainWindow.addEventListener("pt1", (ev => registerWindow(worker, getAndSetInstanceId(ev.detail.frameElement), ev.detail)));
|
468 | }
|
469 | }));
|
470 | })(window);
|