This is an automated email from the ASF dual-hosted git repository.

jky pushed a commit to branch mv3-migrate
in repository https://gitbox.apache.org/repos/asf/flagon.git

commit f53b0890cd13521ff8e0f76989eadc2179dd68d6
Author: Jason Young <[email protected]>
AuthorDate: Fri May 23 15:48:21 2025 -0700

    tab event logs and major mv3 migration changes
---
 .../flagon-userale-ext/src/background/index.ts     |   86 +-
 .../src/background/messages/config_change.ts       |   21 +-
 .../src/background/messages/http_session.ts        |    3 -
 .../src/background/messages/issue_report.ts        |    0
 .../flagon-userale-ext/src/background/ports/log.ts |   31 +-
 .../packages/flagon-userale-ext/src/content.ts     |   25 +-
 .../packages/flagon-userale-ext/src/popup.tsx      |   25 +-
 .../flagon-userale-ext/src/utils/messaging.ts      |   12 +
 .../flagon-userale-ext/src/utils/storage.ts        |    8 +-
 .../packages/flagon-userale/build/esm/main.d.ts    |  235 -----
 .../packages/flagon-userale/build/esm/main.mjs     | 1083 --------------------
 .../packages/flagon-userale/build/esm/main.mjs.map |    1 -
 .../packages/flagon-userale/build/main.d.ts        |   60 +-
 .../userale/packages/flagon-userale/build/main.mjs |  402 +++-----
 .../packages/flagon-userale/build/main.mjs.map     |    2 +-
 .../packages/flagon-userale/src/attachHandlers.ts  |    8 +-
 .../flagon-userale/src/getInitialSettings.ts       |   57 +-
 .../userale/packages/flagon-userale/src/main.ts    |   32 +-
 .../packages/flagon-userale/src/packageLogs.ts     |   27 +-
 .../packages/flagon-userale/src/sendLogs.ts        |   89 +-
 .../userale/packages/flagon-userale/tsconfig.json  |    6 +-
 .../userale/packages/flagon-userale/tsup.config.js |    2 +-
 22 files changed, 436 insertions(+), 1779 deletions(-)

diff --git 
a/products/userale/packages/flagon-userale-ext/src/background/index.ts 
b/products/userale/packages/flagon-userale-ext/src/background/index.ts
index ee5cda3..6e8df51 100644
--- a/products/userale/packages/flagon-userale-ext/src/background/index.ts
+++ b/products/userale/packages/flagon-userale-ext/src/background/index.ts
@@ -1,12 +1,84 @@
-import * as userale from "flagon-userale";
-import { getStoredOptions,} from "~/utils/storage";
+import { getStoredOptions } from "~/utils/storage";
+import { setOptions } from "./messages/config_change";
+import { sendToContent } from "~utils/messaging";
 
-console.log("Service worker loaded!");
+// Top level await is not supported so immediately execute this async function 
to set options from storage
+(async () => {
+    const options = await getStoredOptions();
+    setOptions(options);
+})();
 
-//TODO apply logging url from getstoredoptions to userale.setup
+// Takes a tabId and event data, gets the tab, and sends it
+function sendTabEvent(tabId: number, data: Record<string, any>, type: string) {
+  chrome.tabs.get(tabId, (tab) => {
+    if (!tab) return
+    sendTabEventFromTab(tab, data, type)
+  });
+}
 
-userale.setup();
+// Sends an event directly from a tab object
+function sendTabEventFromTab(tab: chrome.tabs.Tab, data: Record<string, any>, 
type: string) {
+  const payload = {
+    type,
+    tab,
+    data
+  };
 
-//TODO Create browser session id similar to how http session id is created and 
export it be used in background/ports/log.ts
+  sendToContent(tab.id!, { type: "tab-event", payload }).catch((err) =>
+    console.warn(`Failed to send ${type} to tab ${tab.id}:`, err.message)
+  );
+}
 
-//TODO attach tab event listeners and add log them to userale. This can mostly 
be copied from the old code, but use .log() instead of .packagecustomlog()
\ No newline at end of file
+// Tab event handlers 
+// 
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs
+
+// TODO handle events that are sent when the tab isn't active.
+// For example:
+// onCreated events are sent before the content script listener is ready.
+// onDeleted events are sent afeter the content script listener is shut down.
+
+chrome.tabs.onActivated.addListener((activeInfo) =>
+  sendTabEvent(activeInfo.tabId, activeInfo, "tabs.onActivated")
+);
+
+chrome.tabs.onAttached.addListener((tabId, attachInfo) =>
+  sendTabEvent(tabId, attachInfo, "tabs.onAttached")
+);
+
+chrome.tabs.onCreated.addListener((tab) =>
+  sendTabEventFromTab(tab, {}, "tabs.onCreated")
+);
+
+chrome.tabs.onDetached.addListener((tabId, detachInfo) =>
+  sendTabEvent(tabId, detachInfo, "tabs.onDetached")
+);
+
+chrome.tabs.onMoved.addListener((tabId, moveInfo) =>
+  sendTabEvent(tabId, moveInfo, "tabs.onMoved")
+);
+
+chrome.tabs.onRemoved.addListener((tabId, removeInfo) =>
+  sendTabEvent(tabId, removeInfo, "tabs.onRemoved")
+);
+
+chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) =>
+  sendTabEventFromTab(tab, changeInfo, "tabs.onUpdated")
+);
+
+chrome.tabs.onZoomChange.addListener((zoomChangeInfo) =>
+  sendTabEvent(zoomChangeInfo.tabId, zoomChangeInfo, "tabs.onZoomChange")
+);
+
+chrome.tabs.onHighlighted.addListener((highlightInfo) => {
+    // Note: No tabId is available, so send with windowId and tabIds
+    const data = { ...highlightInfo }
+    // Loop over highlightInfo.tabIds and call sendTabEvent on each
+    for (const tabId of highlightInfo.tabIds) {
+        sendTabEvent(tabId, data, "tabs.onHighlighted")
+    }
+});
+
+chrome.tabs.onReplaced.addListener((addedTabId, removedTabId) => {
+    const data = { addedTabId, removedTabId }
+    sendTabEvent(addedTabId, data, "tabs.onReplaced")
+});
\ No newline at end of file
diff --git 
a/products/userale/packages/flagon-userale-ext/src/background/messages/config_change.ts
 
b/products/userale/packages/flagon-userale-ext/src/background/messages/config_change.ts
index a4e71a9..8ee0bf4 100644
--- 
a/products/userale/packages/flagon-userale-ext/src/background/messages/config_change.ts
+++ 
b/products/userale/packages/flagon-userale-ext/src/background/messages/config_change.ts
@@ -1,10 +1,23 @@
 import type { PlasmoMessaging } from "@plasmohq/messaging";
 import * as userale from "flagon-userale";
-import { getStoredOptions } from "~/utils/storage";
+import type { StoredOptions } from "~utils/storage";
  
+let allowListRegExp: RegExp;
+
 const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
-  // call 
-  userale.options(req);
+  setOptions(req.body);
 }
- 
+
+export function setOptions(options: StoredOptions) {
+  console.log(options);
+  userale.options({url: options.loggingUrl});
+  allowListRegExp = new RegExp(options.allowList);
+}
+
+export function getAllowListRegExp() {
+  console.log("getAllowListRegExp");
+  console.log(allowListRegExp);
+  return allowListRegExp;
+}
+
 export default handler
\ No newline at end of file
diff --git 
a/products/userale/packages/flagon-userale-ext/src/background/messages/http_session.ts
 
b/products/userale/packages/flagon-userale-ext/src/background/messages/http_session.ts
deleted file mode 100644
index 1bb712b..0000000
--- 
a/products/userale/packages/flagon-userale-ext/src/background/messages/http_session.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// This is a bit complicated, but once tab logs are added in main. You can 
create a mapping of tab ids (a browser construct) to http session ids (a 
userale construct).
-// The content script should send a message containing its http session id, 
and it should be added to the mapping here, then use the mapping in 
background/index.ts to set the http session field of tab logs.
-// This is also the least import part, so save it for last.
\ No newline at end of file
diff --git 
a/products/userale/packages/flagon-userale-ext/src/background/messages/issue_report.ts
 
b/products/userale/packages/flagon-userale-ext/src/background/messages/issue_report.ts
deleted file mode 100644
index e69de29..0000000
diff --git 
a/products/userale/packages/flagon-userale-ext/src/background/ports/log.ts 
b/products/userale/packages/flagon-userale-ext/src/background/ports/log.ts
index 3a08910..6e0fe6f 100644
--- a/products/userale/packages/flagon-userale-ext/src/background/ports/log.ts
+++ b/products/userale/packages/flagon-userale-ext/src/background/ports/log.ts
@@ -1,17 +1,28 @@
 import type { PlasmoMessaging } from "@plasmohq/messaging";
 import * as userale from "flagon-userale";
- 
+import { getAllowListRegExp } from "~/background/messages/config_change";
+
 const handler: PlasmoMessaging.PortHandler = async (req, res) => {
-  console.log(req);
-  // todo apply browser session id to logs
-  // // log.browserSessionId = browserSessionId;
-  // todo filter logs based off filter url in getstorageoptions
-  // // req = filterUrl(req);
-  if (req) {
-    console.log(req);
-    userale.log(req);
+  let log = req.body
+  log.browserSessionId = browserSessionId;
+  let allowListRegExp = getAllowListRegExp();
+  console.log(allowListRegExp);
+  if (allowListRegExp.test(log.pageUrl)) {
+    userale.log(log);
   }
-  
+}
+
+let browserSessionId = generateSessionId();
+
+// TODO move this to a shared utils workspace (this is from 
packages/flagon-userale/src/, but shouldn't be publicly exported)
+function generateSessionId(): string {
+    // 32 digit hex -> 128 bits of info -> 2^64 ~= 10^19 sessions needed for 
50% chance of collison
+    const len = 32;
+    const arr = new Uint8Array(len / 2);
+    self.crypto.getRandomValues(arr);
+    return Array.from(arr, (dec) => {
+      return dec.toString(16).padStart(2, "0");
+    }).join("");
 }
  
 export default handler;
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale-ext/src/content.ts 
b/products/userale/packages/flagon-userale-ext/src/content.ts
index 967507d..e2e5551 100644
--- a/products/userale/packages/flagon-userale-ext/src/content.ts
+++ b/products/userale/packages/flagon-userale-ext/src/content.ts
@@ -11,10 +11,29 @@ const logPort = getPort("log");
 
 userale.addCallbacks({
   rerouteLog(log) {
-    console.log(log)
-    logPort.postMessage(log);
+    console.log(log);
+    logPort.postMessage({body: log});
     return false;
   }
 });
 
-userale.start();
\ No newline at end of file
+chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
+  if( message.type == "tab-event") {
+    const { type, tab, data } = message.payload;
+    userale.packageCustomLog(
+      {type},
+      () => { return data; },
+      true,
+    );
+    sendResponse({ status: "received" });
+  } else if (message.type === "issue-report") {
+    userale.packageCustomLog(
+      {type: message.type},
+      () => { return message.payload; },
+      true,
+    );
+    sendResponse({ status: "received" });
+  }  
+
+  return true 
+})
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale-ext/src/popup.tsx 
b/products/userale/packages/flagon-userale-ext/src/popup.tsx
index 2c88894..43a8ee4 100644
--- a/products/userale/packages/flagon-userale-ext/src/popup.tsx
+++ b/products/userale/packages/flagon-userale-ext/src/popup.tsx
@@ -1,15 +1,32 @@
 import { useState } from "react";
 import Options from "~/options";
+import { sendToContent } from "~utils/messaging"
 
 function IndexPopup() {
   const [issueType, setIssueType] = useState("Bug");
   const [issueDescription, setIssueDescription] = useState("");
 
-  const handleSubmit = (e: React.FormEvent) => {
-    e.preventDefault();
-    // TODO add messaging
-  };
+  const handleSubmit = async (e: React.FormEvent) => {
+    e.preventDefault()
 
+    try {
+      const [tab] = await chrome.tabs.query({ active: true, currentWindow: 
true });
+      if (!tab?.id) throw new Error("No active tab found");
+      const response = await sendToContent(tab.id, {
+        type: "issue-report",
+        payload: {
+          issueType,
+          issueDescription
+        }
+      });
+      console.log("Content script response:", response)
+      alert("Issue report sent!")
+      setIssueDescription("") // clear after send
+    } catch (error) {
+      console.error("Failed to send message", error)
+      alert("Failed to send issue report.")
+    }
+  }
   return (
     <div>
       <Options />
diff --git 
a/products/userale/packages/flagon-userale-ext/src/utils/messaging.ts 
b/products/userale/packages/flagon-userale-ext/src/utils/messaging.ts
new file mode 100644
index 0000000..b53f411
--- /dev/null
+++ b/products/userale/packages/flagon-userale-ext/src/utils/messaging.ts
@@ -0,0 +1,12 @@
+/**
+ * Sends a message to the content script from the popup, options, or 
background page
+ */
+export async function sendToContent (tabId: number, message: any): 
Promise<any> {
+    return new Promise((resolve, reject) => {
+        chrome.tabs.sendMessage(tabId, message, (response) => {
+            const err = chrome.runtime.lastError
+            if (err) reject(err)
+            else resolve(response)
+        })
+    })
+}
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale-ext/src/utils/storage.ts 
b/products/userale/packages/flagon-userale-ext/src/utils/storage.ts
index f95a274..4e1e261 100644
--- a/products/userale/packages/flagon-userale-ext/src/utils/storage.ts
+++ b/products/userale/packages/flagon-userale-ext/src/utils/storage.ts
@@ -35,6 +35,7 @@ export async function getStoredOptions(): 
Promise<StoredOptions> {
 
 // Only to be used in ~/options
 export async function setStoredOptions(values: Partial<StoredOptions>) {
+  // Validate the new options
   try {
     new RegExp(values.allowList);
     new URL(values.loggingUrl);
@@ -42,9 +43,12 @@ export async function setStoredOptions(values: 
Partial<StoredOptions>) {
     return error;
   }
   
+  // Store the options for after the browser is closed
   await browser.storage.local.set(values);
+
+  // Notify the background script of the change
   return await sendToBackground({
     name: "config_change",
-    body: { values }
+    body: values
   })
-}
+}
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/build/esm/main.d.ts 
b/products/userale/packages/flagon-userale/build/esm/main.d.ts
deleted file mode 100644
index 5e56576..0000000
--- a/products/userale/packages/flagon-userale/build/esm/main.d.ts
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-declare namespace Settings {
-  type Version = string | null;
-  type UserId = string | null;
-  type SessionId = string | null;
-  type UserFromParams = string | null;
-  type ToolName = string | null;
-  type AuthHeader = CallableFunction | string | null;
-  type CustomIndex = string | null;
-  type HeaderObject = { [key: string]: string };
-  type Headers = HeaderObject | null;
-  type ConfigValueTypes =
-    | string
-    | number
-    | boolean
-    | null
-    | Version
-    | UserId
-    | SessionId
-    | UserFromParams
-    | ToolName
-    | AuthHeader
-    | CustomIndex
-    | Headers;
-
-  type TimeFunction = (() => number) | ((ts: number) => number);
-
-  export interface DefaultConfig {
-    [key: string]: ConfigValueTypes;
-  }
-
-  export interface Config extends DefaultConfig {
-    autostart: boolean;
-    authHeader: AuthHeader;
-    browserSessionId: SessionId;
-    custIndex: CustomIndex;
-    headers: Headers;
-    httpSessionId: SessionId;
-    logCountThreshold: number;
-    logDetails: boolean;
-    on?: boolean;
-    resolution: number;
-    sessionId: SessionId;
-    time: TimeFunction;
-    toolName: ToolName;
-    toolVersion?: Version;
-    transmitInterval: number;
-    url: string;
-    userFromParams: UserFromParams;
-    useraleVersion: Version;
-    userId: UserId;
-    version?: Version;
-    websocketsEnabled?: boolean;
-  }
-
-  export interface IConfiguration extends Config {
-    getInstance(): Configuration;
-    configure(newConfig: Config): void;
-  }
-}
-
-// TODO: Switch to protobuf for managing log types
-declare namespace Logging {
-  type JSONObject = {
-    [key: string]:
-      | string
-      | number
-      | boolean
-      | null
-      | undefined
-      | JSONObject
-      | Array<string | number | boolean | null | JSONObject>;
-  };
-  export type Log = JSONObject; // TODO: Intersect this with the default log 
objects (raw & interval)
-  export type CustomLog = JSONObject;
-
-  export type DynamicDetailFunction<E extends Event = Event> = (
-    e: E,
-  ) => JSONObject;
-  export type StaticDetailFunction = () => JSONObject;
-}
-
-declare namespace Events {
-  type FormElement = HTMLInputElement | HTMLSelectElement | 
HTMLTextAreaElement;
-  type ChangeEvent = Event<FormElement>;
-  export type RawEvents =
-    | "dblclick"
-    | "mouseup"
-    | "mousedown"
-    | "dragstart"
-    | "dragend"
-    | "drag"
-    | "drop"
-    | "keydown";
-  export type IntervalEvents =
-    | "click"
-    | "focus"
-    | "blur"
-    | "input"
-    | "change"
-    | "mouseover"
-    | "submit";
-  export type WindowEvents = "load" | "blur" | "focus";
-  export type BufferedEvents = "wheel" | "scroll" | "resize";
-  export type RefreshEvents = "submit";
-  export type AllowedEvents =
-    | RawEvents
-    | IntervalEvents
-    | WindowEvents
-    | BufferedEvents
-    | RefreshEvents;
-
-  export type EventDetailsMap<T extends string> = Partial<{
-    [key in T]:
-      | Logging.DynamicDetailFunction<
-          | MouseEvent
-          | KeyboardEvent
-          | InputEvent
-          | Events.ChangeEvent
-          | WheelEvent
-        >
-      | Logging.StaticDetailFunction
-      | null;
-  }>;
-
-  export type EventBoolMap<T extends string> = Partial<{
-    [key in T]: boolean;
-  }>;
-}
-
-declare namespace Callbacks {
-  export type AuthCallback = () => string;
-  export type HeadersCallback = () => Settings.HeaderObject;
-
-  export type CallbackMap = {
-    [key in string]: CallableFunction;
-  };
-}
-
-/**
- * Defines the way information is extracted from various events.
- * Also defines which events we will listen to.
- * @param  {Settings.Config} options UserALE Configuration object to read from.
- * @param   {Events.AllowedEvents}    type of html event (e.g., 'click', 
'mouseover', etc.), such as passed to addEventListener methods.
- */
-declare function defineCustomDetails(options: Settings.DefaultConfig, type: 
Events.AllowedEvents): Logging.DynamicDetailFunction | null | undefined;
-
-/**
- * Registers the provided callback to be used when updating the auth header.
- * @param {Callbacks.AuthCallback} callback Callback used to fetch the newest 
header. Should return a string.
- * @returns {boolean} Whether the operation succeeded.
- */
-declare function registerAuthCallback(callback: Callbacks.AuthCallback): 
boolean;
-
-/**
- * Adds named callbacks to be executed when logging.
- * @param  {Object } newCallbacks An object containing named callback 
functions.
- */
-declare function addCallbacks(...newCallbacks: Record<symbol | string, 
CallableFunction>[]): Callbacks.CallbackMap;
-/**
- * Removes callbacks by name.
- * @param  {String[]} targetKeys A list of names of functions to remove.
- */
-declare function removeCallbacks(targetKeys: string[]): void;
-/**
- * Transforms the provided HTML event into a log and appends it to the log 
queue.
- * @param  {Event} e         The event to be logged.
- * @param  {Function} detailFcn The function to extract additional log 
parameters from the event.
- * @return {boolean}           Whether the event was logged.
- */
-declare function packageLog(e: Event, detailFcn?: 
Logging.DynamicDetailFunction | null): boolean;
-/**
- * Packages the provided customLog to include standard meta data and appends 
it to the log queue.
- * @param  {Logging.CustomLog} customLog        The behavior to be logged.
- * @param  {Logging.DynamicDetailFunction} detailFcn     The function to 
extract additional log parameters from the event.
- * @param  {boolean} userAction     Indicates user behavior (true) or system 
behavior (false)
- * @return {boolean}           Whether the event was logged.
- */
-declare function packageCustomLog(customLog: Logging.CustomLog, detailFcn: 
Logging.DynamicDetailFunction | Logging.StaticDetailFunction, userAction: 
boolean): boolean;
-/**
- * Builds a string CSS selector from the provided element
- * @param  {EventTarget} ele The element from which the selector is built.
- * @return {string}     The CSS selector for the element, or Unknown if it 
can't be determined.
- */
-declare function getSelector(ele: EventTarget): string;
-/**
- * Builds an array of elements from the provided event target, to the root 
element.
- * @param  {Event} e Event from which the path should be built.
- * @return {HTMLElement[]}   Array of elements, starting at the event target, 
ending at the root element.
- */
-declare function buildPath(e: Event): string[];
-
-declare let started: boolean;
-declare let wsock: WebSocket;
-
-declare const version: string;
-/**
- * Used to start the logging process if the
- * autostart configuration option is set to false.
- */
-declare function start(): void;
-/**
- * Halts the logging process. Logs will no longer be sent.
- */
-declare function stop(): void;
-/**
- * Updates the current configuration
- * object with the provided values.
- * @param  {Partial<Settings.Config>} newConfig The configuration options to 
use.
- * @return {Settings.Config}           Returns the updated configuration.
- */
-declare function options(newConfig: Partial<Settings.Config> | undefined): 
Settings.Config;
-/**
- * Appends a log to the log queue.
- * @param  {Logging.CustomLog} customLog The log to append.
- * @return {boolean}          Whether the operation succeeded.
- */
-declare function log(customLog: Logging.CustomLog | undefined): boolean;
-
-export { addCallbacks, buildPath, defineCustomDetails as details, getSelector, 
log, options, packageCustomLog, packageLog, registerAuthCallback, 
removeCallbacks, start, started, stop, version, wsock };
diff --git a/products/userale/packages/flagon-userale/build/esm/main.mjs 
b/products/userale/packages/flagon-userale/build/esm/main.mjs
deleted file mode 100644
index 40bdfcc..0000000
--- a/products/userale/packages/flagon-userale/build/esm/main.mjs
+++ /dev/null
@@ -1,1083 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements. See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to you under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License. You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing, software
-  distributed under the License is distributed on an "AS IS" BASIS,
-  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  See the License for the specific language governing permissions and
-  limitations under the License.*/
-// package.json
-var version = "2.4.0";
-
-// src/getInitialSettings.ts
-var sessionId = null;
-var httpSessionId = null;
-function getInitialSettings() {
-  if (sessionId === null) {
-    sessionId = getsessionId(
-      "userAlesessionId",
-      "session_" + String(Date.now())
-    );
-  }
-  if (httpSessionId === null) {
-    httpSessionId = getsessionId(
-      "userAleHttpSessionId",
-      generatehttpSessionId()
-    );
-  }
-  const script = document.currentScript || function() {
-    const scripts = document.getElementsByTagName("script");
-    return scripts[scripts.length - 1];
-  }();
-  const get = script ? script.getAttribute.bind(script) : function() {
-    return null;
-  };
-  const headers = get("data-headers");
-  const settings = {
-    authHeader: get("data-auth") || null,
-    autostart: get("data-autostart") === "false" ? false : true,
-    browserSessionId: null,
-    custIndex: get("data-index") || null,
-    headers: headers ? JSON.parse(headers) : null,
-    httpSessionId,
-    logCountThreshold: +(get("data-threshold") || 5),
-    logDetails: get("data-log-details") === "true" ? true : false,
-    resolution: +(get("data-resolution") || 500),
-    sessionId: get("data-session") || sessionId,
-    time: timeStampScale(document.createEvent("CustomEvent")),
-    toolName: get("data-tool") || null,
-    toolVersion: get("data-version") || null,
-    transmitInterval: +(get("data-interval") || 5e3),
-    url: get("data-url") || "http://localhost:8000";,
-    useraleVersion: get("data-userale-version") || null,
-    userFromParams: get("data-user-from-params") || null,
-    userId: get("data-user") || null
-  };
-  return settings;
-}
-function getsessionId(sessionKey, value) {
-  if (window.sessionStorage.getItem(sessionKey) === null) {
-    window.sessionStorage.setItem(sessionKey, JSON.stringify(value));
-    return value;
-  }
-  return JSON.parse(window.sessionStorage.getItem(sessionKey) || "");
-}
-function timeStampScale(e) {
-  let tsScaler;
-  if (e.timeStamp && e.timeStamp > 0) {
-    const delta = Date.now() - e.timeStamp;
-    if (delta < 0) {
-      tsScaler = function() {
-        return e.timeStamp / 1e3;
-      };
-    } else if (delta > e.timeStamp) {
-      const navStart = performance.timeOrigin;
-      tsScaler = function(ts) {
-        return ts + navStart;
-      };
-    } else {
-      tsScaler = function(ts) {
-        return ts;
-      };
-    }
-  } else {
-    tsScaler = function() {
-      return Date.now();
-    };
-  }
-  return tsScaler;
-}
-function generatehttpSessionId() {
-  const len = 32;
-  const arr = new Uint8Array(len / 2);
-  window.crypto.getRandomValues(arr);
-  return Array.from(arr, (dec) => {
-    return dec.toString(16).padStart(2, "0");
-  }).join("");
-}
-
-// src/configure.ts
-var _Configuration = class {
-  constructor() {
-    this.autostart = false;
-    this.authHeader = null;
-    this.browserSessionId = null;
-    this.custIndex = null;
-    this.headers = null;
-    this.httpSessionId = null;
-    this.logCountThreshold = 0;
-    this.logDetails = false;
-    this.on = false;
-    this.resolution = 0;
-    this.sessionId = null;
-    this.time = () => Date.now();
-    this.toolName = null;
-    this.toolVersion = null;
-    this.transmitInterval = 0;
-    this.url = "";
-    this.userFromParams = null;
-    this.useraleVersion = null;
-    this.userId = null;
-    this.version = null;
-    this.websocketsEnabled = false;
-    if (_Configuration.instance === null) {
-      this.initialize();
-    }
-  }
-  static getInstance() {
-    if (_Configuration.instance === null) {
-      _Configuration.instance = new _Configuration();
-    }
-    return _Configuration.instance;
-  }
-  initialize() {
-    const settings = getInitialSettings();
-    this.update(settings);
-  }
-  reset() {
-    this.initialize();
-  }
-  update(newConfig) {
-    Object.keys(newConfig).forEach((option) => {
-      if (option === "userFromParams") {
-        const userParamString = newConfig[option];
-        const userId = userParamString ? 
_Configuration.getUserIdFromParams(userParamString) : null;
-        if (userId) {
-          this["userId"] = userId;
-        }
-      }
-      const hasNewUserFromParams = newConfig["userFromParams"];
-      const willNullifyUserId = option === "userId" && newConfig[option] === 
null;
-      if (willNullifyUserId && hasNewUserFromParams) {
-        return;
-      }
-      const newOption = newConfig[option];
-      if (newOption !== void 0) {
-        this[option] = newOption;
-      }
-    });
-  }
-  static getUserIdFromParams(param) {
-    const userField = param;
-    const regex = new RegExp("[?&]" + userField + "(=([^&#]*)|&|#|$)");
-    const results = window.location.href.match(regex);
-    if (results && results[2]) {
-      return decodeURIComponent(results[2].replace(/\+/g, " "));
-    }
-    return null;
-  }
-};
-var Configuration = _Configuration;
-Configuration.instance = null;
-
-// 
../../node_modules/.pnpm/[email protected]/node_modules/detect-browser/es/index.js
-var __spreadArray = function(to, from, pack) {
-  if (pack || arguments.length === 2)
-    for (var i = 0, l = from.length, ar; i < l; i++) {
-      if (ar || !(i in from)) {
-        if (!ar)
-          ar = Array.prototype.slice.call(from, 0, i);
-        ar[i] = from[i];
-      }
-    }
-  return to.concat(ar || Array.prototype.slice.call(from));
-};
-var BrowserInfo = function() {
-  function BrowserInfo2(name, version3, os) {
-    this.name = name;
-    this.version = version3;
-    this.os = os;
-    this.type = "browser";
-  }
-  return BrowserInfo2;
-}();
-var NodeInfo = function() {
-  function NodeInfo2(version3) {
-    this.version = version3;
-    this.type = "node";
-    this.name = "node";
-    this.os = process.platform;
-  }
-  return NodeInfo2;
-}();
-var SearchBotDeviceInfo = function() {
-  function SearchBotDeviceInfo2(name, version3, os, bot) {
-    this.name = name;
-    this.version = version3;
-    this.os = os;
-    this.bot = bot;
-    this.type = "bot-device";
-  }
-  return SearchBotDeviceInfo2;
-}();
-var BotInfo = function() {
-  function BotInfo2() {
-    this.type = "bot";
-    this.bot = true;
-    this.name = "bot";
-    this.version = null;
-    this.os = null;
-  }
-  return BotInfo2;
-}();
-var ReactNativeInfo = function() {
-  function ReactNativeInfo2() {
-    this.type = "react-native";
-    this.name = "react-native";
-    this.version = null;
-    this.os = null;
-  }
-  return ReactNativeInfo2;
-}();
-var SEARCHBOX_UA_REGEX = 
/alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web 
preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/;
-var SEARCHBOT_OS_REGEX = 
/(nuhk|curl|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask\ 
Jeeves\/Teoma|ia_archiver)/;
-var REQUIRED_VERSION_PARTS = 3;
-var userAgentRules = [
-  ["aol", /AOLShield\/([0-9\._]+)/],
-  ["edge", /Edge\/([0-9\._]+)/],
-  ["edge-ios", /EdgiOS\/([0-9\._]+)/],
-  ["yandexbrowser", /YaBrowser\/([0-9\._]+)/],
-  ["kakaotalk", /KAKAOTALK\s([0-9\.]+)/],
-  ["samsung", /SamsungBrowser\/([0-9\.]+)/],
-  ["silk", /\bSilk\/([0-9._-]+)\b/],
-  ["miui", /MiuiBrowser\/([0-9\.]+)$/],
-  ["beaker", /BeakerBrowser\/([0-9\.]+)/],
-  ["edge-chromium", /EdgA?\/([0-9\.]+)/],
-  [
-    "chromium-webview",
-    /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/
-  ],
-  ["chrome", /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],
-  ["phantomjs", /PhantomJS\/([0-9\.]+)(:?\s|$)/],
-  ["crios", /CriOS\/([0-9\.]+)(:?\s|$)/],
-  ["firefox", /Firefox\/([0-9\.]+)(?:\s|$)/],
-  ["fxios", /FxiOS\/([0-9\.]+)/],
-  ["opera-mini", /Opera Mini.*Version\/([0-9\.]+)/],
-  ["opera", /Opera\/([0-9\.]+)(?:\s|$)/],
-  ["opera", /OPR\/([0-9\.]+)(:?\s|$)/],
-  ["pie", /^Microsoft Pocket Internet Explorer\/(\d+\.\d+)$/],
-  ["pie", /^Mozilla\/\d\.\d+\s\(compatible;\s(?:MSP?IE|MSInternet Explorer) 
(\d+\.\d+);.*Windows CE.*\)$/],
-  ["netfront", /^Mozilla\/\d\.\d+.*NetFront\/(\d.\d)/],
-  ["ie", /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],
-  ["ie", /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],
-  ["ie", /MSIE\s(7\.0)/],
-  ["bb10", /BB10;\sTouch.*Version\/([0-9\.]+)/],
-  ["android", /Android\s([0-9\.]+)/],
-  ["ios", /Version\/([0-9\._]+).*Mobile.*Safari.*/],
-  ["safari", /Version\/([0-9\._]+).*Safari/],
-  ["facebook", /FB[AS]V\/([0-9\.]+)/],
-  ["instagram", /Instagram\s([0-9\.]+)/],
-  ["ios-webview", /AppleWebKit\/([0-9\.]+).*Mobile/],
-  ["ios-webview", /AppleWebKit\/([0-9\.]+).*Gecko\)$/],
-  ["curl", /^curl\/([0-9\.]+)$/],
-  ["searchbot", SEARCHBOX_UA_REGEX]
-];
-var operatingSystemRules = [
-  ["iOS", /iP(hone|od|ad)/],
-  ["Android OS", /Android/],
-  ["BlackBerry OS", /BlackBerry|BB10/],
-  ["Windows Mobile", /IEMobile/],
-  ["Amazon OS", /Kindle/],
-  ["Windows 3.11", /Win16/],
-  ["Windows 95", /(Windows 95)|(Win95)|(Windows_95)/],
-  ["Windows 98", /(Windows 98)|(Win98)/],
-  ["Windows 2000", /(Windows NT 5.0)|(Windows 2000)/],
-  ["Windows XP", /(Windows NT 5.1)|(Windows XP)/],
-  ["Windows Server 2003", /(Windows NT 5.2)/],
-  ["Windows Vista", /(Windows NT 6.0)/],
-  ["Windows 7", /(Windows NT 6.1)/],
-  ["Windows 8", /(Windows NT 6.2)/],
-  ["Windows 8.1", /(Windows NT 6.3)/],
-  ["Windows 10", /(Windows NT 10.0)/],
-  ["Windows ME", /Windows ME/],
-  ["Windows CE", /Windows CE|WinCE|Microsoft Pocket Internet Explorer/],
-  ["Open BSD", /OpenBSD/],
-  ["Sun OS", /SunOS/],
-  ["Chrome OS", /CrOS/],
-  ["Linux", /(Linux)|(X11)/],
-  ["Mac OS", /(Mac_PowerPC)|(Macintosh)/],
-  ["QNX", /QNX/],
-  ["BeOS", /BeOS/],
-  ["OS/2", /OS\/2/]
-];
-function detect(userAgent) {
-  if (!!userAgent) {
-    return parseUserAgent(userAgent);
-  }
-  if (typeof document === "undefined" && typeof navigator !== "undefined" && 
navigator.product === "ReactNative") {
-    return new ReactNativeInfo();
-  }
-  if (typeof navigator !== "undefined") {
-    return parseUserAgent(navigator.userAgent);
-  }
-  return getNodeVersion();
-}
-function matchUserAgent(ua) {
-  return ua !== "" && userAgentRules.reduce(function(matched, _a) {
-    var browser = _a[0], regex = _a[1];
-    if (matched) {
-      return matched;
-    }
-    var uaMatch = regex.exec(ua);
-    return !!uaMatch && [browser, uaMatch];
-  }, false);
-}
-function parseUserAgent(ua) {
-  var matchedRule = matchUserAgent(ua);
-  if (!matchedRule) {
-    return null;
-  }
-  var name = matchedRule[0], match = matchedRule[1];
-  if (name === "searchbot") {
-    return new BotInfo();
-  }
-  var versionParts = match[1] && 
match[1].split(".").join("_").split("_").slice(0, 3);
-  if (versionParts) {
-    if (versionParts.length < REQUIRED_VERSION_PARTS) {
-      versionParts = __spreadArray(__spreadArray([], versionParts, true), 
createVersionParts(REQUIRED_VERSION_PARTS - versionParts.length), true);
-    }
-  } else {
-    versionParts = [];
-  }
-  var version3 = versionParts.join(".");
-  var os = detectOS(ua);
-  var searchBotMatch = SEARCHBOT_OS_REGEX.exec(ua);
-  if (searchBotMatch && searchBotMatch[1]) {
-    return new SearchBotDeviceInfo(name, version3, os, searchBotMatch[1]);
-  }
-  return new BrowserInfo(name, version3, os);
-}
-function detectOS(ua) {
-  for (var ii = 0, count = operatingSystemRules.length; ii < count; ii++) {
-    var _a = operatingSystemRules[ii], os = _a[0], regex = _a[1];
-    var match = regex.exec(ua);
-    if (match) {
-      return os;
-    }
-  }
-  return null;
-}
-function getNodeVersion() {
-  var isNode = typeof process !== "undefined" && process.version;
-  return isNode ? new NodeInfo(process.version.slice(1)) : null;
-}
-function createVersionParts(count) {
-  var output = [];
-  for (var ii = 0; ii < count; ii++) {
-    output.push("0");
-  }
-  return output;
-}
-
-// src/packageLogs.ts
-var browserInfo = detect();
-var logs;
-var config;
-var intervalId;
-var intervalType;
-var intervalPath;
-var intervalTimer;
-var intervalCounter;
-var intervalLog;
-var filterHandler = null;
-var mapHandler = null;
-var cbHandlers = {};
-function addCallbacks(...newCallbacks) {
-  newCallbacks.forEach((source) => {
-    let descriptors = {};
-    descriptors = Object.keys(source).reduce((descriptors2, key) => {
-      descriptors2[key] = Object.getOwnPropertyDescriptor(source, key);
-      return descriptors2;
-    }, descriptors);
-    Object.getOwnPropertySymbols(source).forEach((sym) => {
-      const descriptor = Object.getOwnPropertyDescriptor(source, sym);
-      if (descriptor?.enumerable) {
-        descriptors[sym] = descriptor;
-      }
-    });
-    Object.defineProperties(cbHandlers, descriptors);
-  });
-  return cbHandlers;
-}
-function removeCallbacks(targetKeys) {
-  targetKeys.forEach((key) => {
-    if (Object.prototype.hasOwnProperty.call(cbHandlers, key)) {
-      delete cbHandlers[key];
-    }
-  });
-}
-function initPackager(newLogs, newConfig) {
-  logs = newLogs;
-  config = newConfig;
-  cbHandlers = {};
-  intervalId = null;
-  intervalType = null;
-  intervalPath = null;
-  intervalTimer = null;
-  intervalCounter = 0;
-  intervalLog = null;
-}
-function packageLog(e, detailFcn) {
-  if (!config.on) {
-    return false;
-  }
-  let details = null;
-  if (detailFcn) {
-    details = detailFcn(e);
-  }
-  const timeFields = extractTimeFields(
-    e.timeStamp && e.timeStamp > 0 ? config.time(e.timeStamp) : Date.now()
-  );
-  let log2 = {
-    target: e.target ? getSelector(e.target) : null,
-    path: buildPath(e),
-    pageUrl: window.location.href,
-    pageTitle: document.title,
-    pageReferrer: document.referrer,
-    browser: detectBrowser(),
-    clientTime: timeFields.milli,
-    microTime: timeFields.micro,
-    location: getLocation(e),
-    scrnRes: getScreenRes(),
-    type: e.type,
-    logType: "raw",
-    userAction: true,
-    details,
-    userId: config.userId,
-    toolVersion: config.toolVersion,
-    toolName: config.toolName,
-    useraleVersion: config.useraleVersion,
-    sessionId: config.sessionId,
-    httpSessionId: config.httpSessionId,
-    browserSessionId: config.browserSessionId,
-    attributes: buildAttrs(e),
-    style: buildCSS(e)
-  };
-  if (typeof filterHandler === "function" && !filterHandler(log2)) {
-    return false;
-  }
-  if (typeof mapHandler === "function") {
-    log2 = mapHandler(log2, e);
-  }
-  for (const func of Object.values(cbHandlers)) {
-    if (typeof func === "function") {
-      log2 = func(log2, e);
-      if (!log2) {
-        return false;
-      }
-    }
-  }
-  logs.push(log2);
-  return true;
-}
-function packageCustomLog(customLog, detailFcn, userAction) {
-  if (!config.on) {
-    return false;
-  }
-  let details = null;
-  if (detailFcn.length === 0) {
-    const staticDetailFcn = detailFcn;
-    details = staticDetailFcn();
-  }
-  const metaData = {
-    pageUrl: window.location.href,
-    pageTitle: document.title,
-    pageReferrer: document.referrer,
-    browser: detectBrowser(),
-    clientTime: Date.now(),
-    scrnRes: getScreenRes(),
-    logType: "custom",
-    userAction,
-    details,
-    userId: config.userId,
-    toolVersion: config.toolVersion,
-    toolName: config.toolName,
-    useraleVersion: config.useraleVersion,
-    sessionId: config.sessionId,
-    httpSessionId: config.httpSessionId,
-    browserSessionId: config.browserSessionId
-  };
-  let log2 = Object.assign(metaData, customLog);
-  if (typeof filterHandler === "function" && !filterHandler(log2)) {
-    return false;
-  }
-  if (typeof mapHandler === "function") {
-    log2 = mapHandler(log2);
-  }
-  for (const func of Object.values(cbHandlers)) {
-    if (typeof func === "function") {
-      log2 = func(log2, null);
-      if (!log2) {
-        return false;
-      }
-    }
-  }
-  logs.push(log2);
-  return true;
-}
-function extractTimeFields(timeStamp) {
-  return {
-    milli: Math.floor(timeStamp),
-    micro: Number((timeStamp % 1).toFixed(3))
-  };
-}
-function packageIntervalLog(e) {
-  try {
-    const target = e.target ? getSelector(e.target) : null;
-    const path = buildPath(e);
-    const type = e.type;
-    const timestamp = Math.floor(
-      e.timeStamp && e.timeStamp > 0 ? config.time(e.timeStamp) : Date.now()
-    );
-    if (intervalId == null) {
-      intervalId = target;
-      intervalType = type;
-      intervalPath = path;
-      intervalTimer = timestamp;
-      intervalCounter = 0;
-    }
-    if ((intervalId !== target || intervalType !== type) && intervalTimer) {
-      intervalLog = {
-        target: intervalId,
-        path: intervalPath,
-        pageUrl: window.location.href,
-        pageTitle: document.title,
-        pageReferrer: document.referrer,
-        browser: detectBrowser(),
-        count: intervalCounter,
-        duration: timestamp - intervalTimer,
-        startTime: intervalTimer,
-        endTime: timestamp,
-        type: intervalType,
-        logType: "interval",
-        targetChange: intervalId !== target,
-        typeChange: intervalType !== type,
-        userAction: false,
-        userId: config.userId,
-        toolVersion: config.toolVersion,
-        toolName: config.toolName,
-        useraleVersion: config.useraleVersion,
-        sessionId: config.sessionId,
-        httpSessionId: config.httpSessionId,
-        browserSessionId: config.browserSessionId
-      };
-      if (typeof filterHandler === "function" && !filterHandler(intervalLog)) {
-        return false;
-      }
-      if (typeof mapHandler === "function") {
-        intervalLog = mapHandler(intervalLog, e);
-      }
-      for (const func of Object.values(cbHandlers)) {
-        if (typeof func === "function") {
-          intervalLog = func(intervalLog, null);
-          if (!intervalLog) {
-            return false;
-          }
-        }
-      }
-      if (intervalLog)
-        logs.push(intervalLog);
-      intervalId = target;
-      intervalType = type;
-      intervalPath = path;
-      intervalTimer = timestamp;
-      intervalCounter = 0;
-    }
-    if (intervalId == target && intervalType == type && intervalCounter) {
-      intervalCounter = intervalCounter + 1;
-    }
-    return true;
-  } catch {
-    return false;
-  }
-}
-function getLocation(e) {
-  if (e instanceof MouseEvent) {
-    if (e.pageX != null) {
-      return { x: e.pageX, y: e.pageY };
-    } else if (e.clientX != null) {
-      return {
-        x: document.documentElement.scrollLeft + e.clientX,
-        y: document.documentElement.scrollTop + e.clientY
-      };
-    }
-  } else {
-    return { x: null, y: null };
-  }
-}
-function getScreenRes() {
-  return { width: window.innerWidth, height: window.innerHeight };
-}
-function getSelector(ele) {
-  if (ele instanceof HTMLElement || ele instanceof Element) {
-    if (ele.localName) {
-      return ele.localName + (ele.id ? "#" + ele.id : "") + (ele.className ? 
"." + ele.className : "");
-    } else if (ele.nodeName) {
-      return ele.nodeName + (ele.id ? "#" + ele.id : "") + (ele.className ? 
"." + ele.className : "");
-    }
-  } else if (ele instanceof Document) {
-    return "#document";
-  } else if (ele === globalThis) {
-    return "Window";
-  }
-  return "Unknown";
-}
-function buildPath(e) {
-  const path = e.composedPath();
-  return selectorizePath(path);
-}
-function selectorizePath(path) {
-  let i = 0;
-  let pathEle;
-  const pathSelectors = [];
-  while (pathEle = path[i]) {
-    pathSelectors.push(getSelector(pathEle));
-    ++i;
-    pathEle = path[i];
-  }
-  return pathSelectors;
-}
-function detectBrowser() {
-  return {
-    browser: browserInfo ? browserInfo.name : "",
-    version: browserInfo ? browserInfo.version : ""
-  };
-}
-function buildAttrs(e) {
-  const attributes = {};
-  const attributeBlackList = ["style"];
-  if (e.target && e.target instanceof Element) {
-    for (const attr of e.target.attributes) {
-      if (attributeBlackList.includes(attr.name))
-        continue;
-      let val = attr.value;
-      try {
-        val = JSON.parse(val);
-      } catch (error) {
-      }
-      attributes[attr.name] = val;
-    }
-  }
-  return attributes;
-}
-function buildCSS(e) {
-  const properties = {};
-  if (e.target && e.target instanceof HTMLElement) {
-    const styleObj = e.target.style;
-    for (let i = 0; i < styleObj.length; i++) {
-      const prop = styleObj[i];
-      properties[prop] = styleObj.getPropertyValue(prop);
-    }
-  }
-  return properties;
-}
-
-// src/attachHandlers.ts
-var events;
-var bufferBools;
-var bufferedEvents;
-var refreshEvents;
-var intervalEvents = [
-  "click",
-  "focus",
-  "blur",
-  "input",
-  "change",
-  "mouseover",
-  "submit"
-];
-var windowEvents = ["load", "blur", "focus"];
-function extractMouseDetails(e) {
-  return {
-    clicks: e.detail,
-    ctrl: e.ctrlKey,
-    alt: e.altKey,
-    shift: e.shiftKey,
-    meta: e.metaKey
-  };
-}
-function extractKeyboardDetails(e) {
-  return {
-    key: e.key,
-    code: e.code,
-    ctrl: e.ctrlKey,
-    alt: e.altKey,
-    shift: e.shiftKey,
-    meta: e.metaKey
-  };
-}
-function extractChangeDetails(e) {
-  return {
-    value: e.target.value
-  };
-}
-function extractWheelDetails(e) {
-  return {
-    x: e.deltaX,
-    y: e.deltaY,
-    z: e.deltaZ
-  };
-}
-function extractScrollDetails() {
-  return {
-    x: window.scrollX,
-    y: window.scrollY
-  };
-}
-function extractResizeDetails() {
-  return {
-    width: window.outerWidth,
-    height: window.outerHeight
-  };
-}
-function defineDetails(config3) {
-  events = {
-    click: extractMouseDetails,
-    dblclick: extractMouseDetails,
-    mousedown: extractMouseDetails,
-    mouseup: extractMouseDetails,
-    focus: null,
-    blur: null,
-    input: config3.logDetails ? extractKeyboardDetails : null,
-    change: config3.logDetails ? extractChangeDetails : null,
-    dragstart: null,
-    dragend: null,
-    drag: null,
-    drop: null,
-    keydown: config3.logDetails ? extractKeyboardDetails : null,
-    mouseover: null
-  };
-  bufferBools = {};
-  bufferedEvents = {
-    wheel: extractWheelDetails,
-    scroll: extractScrollDetails,
-    resize: extractResizeDetails
-  };
-  refreshEvents = {
-    submit: null
-  };
-}
-function defineCustomDetails(options2, type) {
-  const eventType = {
-    click: extractMouseDetails,
-    dblclick: extractMouseDetails,
-    mousedown: extractMouseDetails,
-    mouseup: extractMouseDetails,
-    focus: null,
-    blur: null,
-    load: null,
-    input: options2.logDetails ? extractKeyboardDetails : null,
-    change: options2.logDetails ? extractChangeDetails : null,
-    dragstart: null,
-    dragend: null,
-    drag: null,
-    drop: null,
-    keydown: options2.logDetails ? extractKeyboardDetails : null,
-    mouseover: null,
-    wheel: extractWheelDetails,
-    scroll: extractScrollDetails,
-    resize: extractResizeDetails,
-    submit: null
-  };
-  return eventType[type];
-}
-function attachHandlers(config3) {
-  try {
-    defineDetails(config3);
-    Object.keys(events).forEach(function(ev) {
-      document.addEventListener(
-        ev,
-        function(e) {
-          packageLog(e, events[ev]);
-        },
-        true
-      );
-    });
-    intervalEvents.forEach(function(ev) {
-      document.addEventListener(
-        ev,
-        function(e) {
-          packageIntervalLog(e);
-        },
-        true
-      );
-    });
-    Object.keys(bufferedEvents).forEach(
-      function(ev) {
-        bufferBools[ev] = true;
-        window.addEventListener(
-          ev,
-          function(e) {
-            if (bufferBools[ev]) {
-              bufferBools[ev] = false;
-              packageLog(e, bufferedEvents[ev]);
-              setTimeout(function() {
-                bufferBools[ev] = true;
-              }, config3.resolution);
-            }
-          },
-          true
-        );
-      }
-    );
-    Object.keys(refreshEvents).forEach(
-      function(ev) {
-        document.addEventListener(
-          ev,
-          function(e) {
-            packageLog(e, events[ev]);
-          },
-          true
-        );
-      }
-    );
-    windowEvents.forEach(function(ev) {
-      window.addEventListener(
-        ev,
-        function(e) {
-          packageLog(e, function() {
-            return { window: true };
-          });
-        },
-        true
-      );
-    });
-    return true;
-  } catch {
-    return false;
-  }
-}
-
-// src/utils/auth/index.ts
-var authCallback = null;
-function updateAuthHeader(config3) {
-  if (authCallback) {
-    try {
-      config3.authHeader = authCallback();
-    } catch (e) {
-      console.error(`Error encountered while setting the auth header: ${e}`);
-    }
-  }
-}
-function registerAuthCallback(callback) {
-  try {
-    verifyCallback(callback);
-    authCallback = callback;
-    return true;
-  } catch (e) {
-    return false;
-  }
-}
-function verifyCallback(callback) {
-  if (typeof callback !== "function") {
-    throw new Error("Userale auth callback must be a function");
-  }
-  const result = callback();
-  if (typeof result !== "string") {
-    throw new Error("Userale auth callback must return a string");
-  }
-}
-
-// src/utils/headers/index.ts
-var headersCallback = null;
-function updateCustomHeaders(config3) {
-  if (headersCallback) {
-    try {
-      config3.headers = headersCallback();
-    } catch (e) {
-      console.error(`Error encountered while setting the headers: ${e}`);
-    }
-  }
-}
-
-// src/sendLogs.ts
-var sendIntervalId;
-function initSender(logs3, config3) {
-  if (sendIntervalId) {
-    clearInterval(sendIntervalId);
-  }
-  sendIntervalId = sendOnInterval(logs3, config3);
-  sendOnClose(logs3, config3);
-}
-function sendOnInterval(logs3, config3) {
-  return setInterval(function() {
-    if (!config3.on) {
-      return;
-    }
-    if (logs3.length >= config3.logCountThreshold) {
-      sendLogs(logs3.slice(0), config3, 0);
-      logs3.splice(0);
-    }
-  }, config3.transmitInterval);
-}
-function sendOnClose(logs3, config3) {
-  window.addEventListener("pagehide", function() {
-    if (!config3.on) {
-      return;
-    }
-    if (logs3.length > 0) {
-      if (config3.websocketsEnabled) {
-        const data = JSON.stringify(logs3);
-        wsock.send(data);
-      } else {
-        const headers = new Headers();
-        headers.set("Content-Type", "applicaiton/json;charset=UTF-8");
-        if (config3.authHeader) {
-          headers.set("Authorization", config3.authHeader.toString());
-        }
-        fetch(config3.url, {
-          keepalive: true,
-          method: "POST",
-          headers,
-          body: JSON.stringify(logs3)
-        }).catch((error) => {
-          console.error(error);
-        });
-      }
-      logs3.splice(0);
-    }
-  });
-}
-function sendLogs(logs3, config3, retries) {
-  const data = JSON.stringify(logs3);
-  if (config3.websocketsEnabled) {
-    wsock.send(data);
-  } else {
-    const req = new XMLHttpRequest();
-    req.open("POST", config3.url);
-    updateAuthHeader(config3);
-    if (config3.authHeader) {
-      req.setRequestHeader(
-        "Authorization",
-        typeof config3.authHeader === "function" ? config3.authHeader() : 
config3.authHeader
-      );
-    }
-    req.setRequestHeader("Content-type", "application/json;charset=UTF-8");
-    updateCustomHeaders(config3);
-    if (config3.headers) {
-      Object.entries(config3.headers).forEach(([header, value]) => {
-        req.setRequestHeader(header, value);
-      });
-    }
-    req.onreadystatechange = function() {
-      if (req.readyState === 4 && req.status !== 200) {
-        if (retries > 0) {
-          sendLogs(logs3, config3, retries--);
-        }
-      }
-    };
-    req.send(data);
-  }
-}
-
-// src/main.ts
-var config2 = Configuration.getInstance();
-var logs2 = [];
-var startLoadTimestamp = Date.now();
-var endLoadTimestamp;
-try {
-  window.onload = function() {
-    endLoadTimestamp = Date.now();
-  };
-} catch (error) {
-  endLoadTimestamp = Date.now();
-}
-var started = false;
-var wsock;
-config2.update({
-  useraleVersion: version
-});
-initPackager(logs2, config2);
-getWebsocketsEnabled(config2);
-if (config2.autostart) {
-  setup(config2);
-}
-function setup(config3) {
-  if (!started) {
-    setTimeout(function() {
-      let state;
-      try {
-        state = document.readyState;
-      } catch (error) {
-        initSender(logs2, config3);
-      }
-      if (config3.autostart && (state === "interactive" || state === 
"complete")) {
-        attachHandlers(config3);
-        initSender(logs2, config3);
-        started = config3.on = true;
-        packageCustomLog(
-          {
-            type: "load",
-            details: { pageLoadTime: endLoadTimestamp - startLoadTimestamp }
-          },
-          () => ({}),
-          false
-        );
-      } else {
-        setup(config3);
-      }
-    }, 100);
-  }
-}
-function getWebsocketsEnabled(config3) {
-  wsock = new WebSocket(config3.url.replace("http://";, "ws://"));
-  wsock.onerror = () => {
-    console.log("no websockets detected");
-  };
-  wsock.onopen = () => {
-    console.log("connection established with websockets");
-    config3.websocketsEnabled = true;
-  };
-  wsock.onclose = () => {
-    sendOnClose(logs2, config3);
-  };
-}
-var version2 = version;
-function start() {
-  if (!started || config2.autostart === false) {
-    started = config2.on = true;
-    config2.update({ autostart: true });
-  }
-}
-function stop() {
-  started = config2.on = false;
-  config2.update({ autostart: false });
-}
-function options(newConfig) {
-  if (newConfig) {
-    config2.update(newConfig);
-  }
-  return config2;
-}
-function log(customLog) {
-  if (customLog) {
-    logs2.push(customLog);
-    return true;
-  } else {
-    return false;
-  }
-}
-export {
-  addCallbacks,
-  buildPath,
-  defineCustomDetails as details,
-  getSelector,
-  log,
-  options,
-  packageCustomLog,
-  packageLog,
-  registerAuthCallback,
-  removeCallbacks,
-  start,
-  started,
-  stop,
-  version2 as version,
-  wsock
-};
-//# sourceMappingURL=main.mjs.map
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/build/esm/main.mjs.map 
b/products/userale/packages/flagon-userale/build/esm/main.mjs.map
deleted file mode 100644
index 66a020b..0000000
--- a/products/userale/packages/flagon-userale/build/esm/main.mjs.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["../../src/getInitialSettings.ts","../../src/configure.ts","../../../../node_modules/.pnpm/[email protected]/node_modules/detect-browser/es/index.js","../../src/packageLogs.ts","../../src/attachHandlers.ts","../../src/utils/auth/index.ts","../../src/utils/headers/index.ts","../../src/sendLogs.ts","../../src/main.ts"],"sourcesContent":["/*\n
 * Licensed to the Apache Software Foundation (ASF) under one or more\n * 
contributor license agreements.  See the NOTICE f [...]
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/build/main.d.ts 
b/products/userale/packages/flagon-userale/build/main.d.ts
index e08e30d..5e56576 100644
--- a/products/userale/packages/flagon-userale/build/main.d.ts
+++ b/products/userale/packages/flagon-userale/build/main.d.ts
@@ -65,6 +65,7 @@ declare namespace Settings {
     useraleVersion: Version;
     userId: UserId;
     version?: Version;
+    websocketsEnabled?: boolean;
   }
 
   export interface IConfiguration extends Config {
@@ -151,56 +152,6 @@ declare namespace Callbacks {
   };
 }
 
-declare class Configuration$1 {
-    [key: string]: Settings.ConfigValueTypes;
-    private static instance;
-    autostart: boolean;
-    authHeader: Settings.AuthHeader;
-    browserSessionId: Settings.SessionId;
-    custIndex: Settings.CustomIndex;
-    headers: Settings.Headers;
-    httpSessionId: Settings.SessionId;
-    logCountThreshold: number;
-    logDetails: boolean;
-    on: boolean;
-    resolution: number;
-    sessionId: Settings.SessionId;
-    time: Settings.TimeFunction;
-    toolName: Settings.ToolName;
-    toolVersion: Settings.Version;
-    transmitInterval: number;
-    url: string;
-    userFromParams: Settings.UserFromParams;
-    useraleVersion: Settings.Version;
-    userId: Settings.UserId;
-    version: Settings.Version;
-    websocketsEnabled: boolean;
-    private constructor();
-    static getInstance(): Configuration$1;
-    private initialize;
-    /**
-     * Resets the configuration to its initial state.
-     */
-    reset(): void;
-    /**
-     * Shallow merges a newConfig with the configuration class, updating it.
-     * Retrieves/updates the userid if userFromParams is provided.
-     * @param  {Partial<Settings.Config>} newConfig Configuration object to 
merge into the current config.
-     */
-    update(newConfig: Partial<Settings.Config>): void;
-    /**
-     * Attempts to extract the userid from the query parameters of the URL.
-     * @param  {string} param The name of the query parameter containing the 
userid.
-     * @return {string | null}       The extracted/decoded userid, or null if 
none is found.
-     */
-    static getUserIdFromParams(param: string): string | null;
-    /**
-     *
-     * @return {bool}
-     */
-    isWebSocket(): boolean;
-}
-
 /**
  * Defines the way information is extracted from various events.
  * Also defines which events we will listen to.
@@ -255,13 +206,8 @@ declare function getSelector(ele: EventTarget): string;
 declare function buildPath(e: Event): string[];
 
 declare let started: boolean;
+declare let wsock: WebSocket;
 
-/**
- * Hooks the global event listener, and starts up the
- * logging interval.
- * @param  {Configuration} config Configuration settings for the logger
- */
-declare function setup(config: Configuration$1): void;
 declare const version: string;
 /**
  * Used to start the logging process if the
@@ -286,4 +232,4 @@ declare function options(newConfig: 
Partial<Settings.Config> | undefined): Setti
  */
 declare function log(customLog: Logging.CustomLog | undefined): boolean;
 
-export { addCallbacks, buildPath, defineCustomDetails as details, getSelector, 
log, options, packageCustomLog, packageLog, registerAuthCallback, 
removeCallbacks, setup, start, started, stop, version };
+export { addCallbacks, buildPath, defineCustomDetails as details, getSelector, 
log, options, packageCustomLog, packageLog, registerAuthCallback, 
removeCallbacks, start, started, stop, version, wsock };
diff --git a/products/userale/packages/flagon-userale/build/main.mjs 
b/products/userale/packages/flagon-userale/build/main.mjs
index f4cc151..8e511bc 100644
--- a/products/userale/packages/flagon-userale/build/main.mjs
+++ b/products/userale/packages/flagon-userale/build/main.mjs
@@ -1,17 +1,17 @@
 /* Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements. See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to you under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License. You may obtain a copy of the License at
+  contributor license agreements. See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to you under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License. You may obtain a copy of the License at
 
-http://www.apache.org/licenses/LICENSE-2.0
+  http://www.apache.org/licenses/LICENSE-2.0
 
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.*/
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.*/
 // package.json
 var version = "2.4.0";
 
@@ -19,6 +19,29 @@ var version = "2.4.0";
 var sessionId = null;
 var httpSessionId = null;
 function getInitialSettings() {
+  if (typeof WorkerGlobalScope !== "undefined" && self instanceof 
WorkerGlobalScope) {
+    const settings2 = {
+      authHeader: null,
+      autostart: true,
+      browserSessionId: null,
+      custIndex: null,
+      headers: null,
+      httpSessionId: null,
+      logCountThreshold: 5,
+      logDetails: false,
+      resolution: 500,
+      sessionId,
+      time: (ts) => ts !== void 0 ? ts : Date.now(),
+      toolName: null,
+      toolVersion: null,
+      transmitInterval: 5e3,
+      url: "http://localhost:8000";,
+      useraleVersion: null,
+      userFromParams: null,
+      userId: null
+    };
+    return settings2;
+  }
   if (sessionId === null) {
     sessionId = getsessionId(
       "userAlesessionId",
@@ -62,11 +85,11 @@ function getInitialSettings() {
   return settings;
 }
 function getsessionId(sessionKey, value) {
-  if (window.sessionStorage.getItem(sessionKey) === null) {
-    window.sessionStorage.setItem(sessionKey, JSON.stringify(value));
+  if (self.sessionStorage.getItem(sessionKey) === null) {
+    self.sessionStorage.setItem(sessionKey, JSON.stringify(value));
     return value;
   }
-  return JSON.parse(window.sessionStorage.getItem(sessionKey) || "");
+  return JSON.parse(self.sessionStorage.getItem(sessionKey) || "");
 }
 function timeStampScale(e) {
   let tsScaler;
@@ -137,12 +160,8 @@ var _Configuration = class {
     return _Configuration.instance;
   }
   initialize() {
-    try {
-      const settings = getInitialSettings();
-      this.update(settings);
-    } catch (error) {
-      console.log(error);
-    }
+    const settings = getInitialSettings();
+    this.update(settings);
   }
   reset() {
     this.initialize();
@@ -176,214 +195,11 @@ var _Configuration = class {
     }
     return null;
   }
-  isWebSocket() {
-    return this.url.startsWith("ws://") || this.url.startsWith("wss://");
-  }
 };
 var Configuration = _Configuration;
 Configuration.instance = null;
 
-// 
../../node_modules/.pnpm/[email protected]/node_modules/detect-browser/es/index.js
-var __spreadArray = function(to, from, pack) {
-  if (pack || arguments.length === 2)
-    for (var i = 0, l = from.length, ar; i < l; i++) {
-      if (ar || !(i in from)) {
-        if (!ar)
-          ar = Array.prototype.slice.call(from, 0, i);
-        ar[i] = from[i];
-      }
-    }
-  return to.concat(ar || Array.prototype.slice.call(from));
-};
-var BrowserInfo = function() {
-  function BrowserInfo2(name, version3, os) {
-    this.name = name;
-    this.version = version3;
-    this.os = os;
-    this.type = "browser";
-  }
-  return BrowserInfo2;
-}();
-var NodeInfo = function() {
-  function NodeInfo2(version3) {
-    this.version = version3;
-    this.type = "node";
-    this.name = "node";
-    this.os = process.platform;
-  }
-  return NodeInfo2;
-}();
-var SearchBotDeviceInfo = function() {
-  function SearchBotDeviceInfo2(name, version3, os, bot) {
-    this.name = name;
-    this.version = version3;
-    this.os = os;
-    this.bot = bot;
-    this.type = "bot-device";
-  }
-  return SearchBotDeviceInfo2;
-}();
-var BotInfo = function() {
-  function BotInfo2() {
-    this.type = "bot";
-    this.bot = true;
-    this.name = "bot";
-    this.version = null;
-    this.os = null;
-  }
-  return BotInfo2;
-}();
-var ReactNativeInfo = function() {
-  function ReactNativeInfo2() {
-    this.type = "react-native";
-    this.name = "react-native";
-    this.version = null;
-    this.os = null;
-  }
-  return ReactNativeInfo2;
-}();
-var SEARCHBOX_UA_REGEX = 
/alexa|bot|crawl(er|ing)|facebookexternalhit|feedburner|google web 
preview|nagios|postrank|pingdom|slurp|spider|yahoo!|yandex/;
-var SEARCHBOT_OS_REGEX = 
/(nuhk|curl|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask\ 
Jeeves\/Teoma|ia_archiver)/;
-var REQUIRED_VERSION_PARTS = 3;
-var userAgentRules = [
-  ["aol", /AOLShield\/([0-9\._]+)/],
-  ["edge", /Edge\/([0-9\._]+)/],
-  ["edge-ios", /EdgiOS\/([0-9\._]+)/],
-  ["yandexbrowser", /YaBrowser\/([0-9\._]+)/],
-  ["kakaotalk", /KAKAOTALK\s([0-9\.]+)/],
-  ["samsung", /SamsungBrowser\/([0-9\.]+)/],
-  ["silk", /\bSilk\/([0-9._-]+)\b/],
-  ["miui", /MiuiBrowser\/([0-9\.]+)$/],
-  ["beaker", /BeakerBrowser\/([0-9\.]+)/],
-  ["edge-chromium", /EdgA?\/([0-9\.]+)/],
-  [
-    "chromium-webview",
-    /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/
-  ],
-  ["chrome", /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],
-  ["phantomjs", /PhantomJS\/([0-9\.]+)(:?\s|$)/],
-  ["crios", /CriOS\/([0-9\.]+)(:?\s|$)/],
-  ["firefox", /Firefox\/([0-9\.]+)(?:\s|$)/],
-  ["fxios", /FxiOS\/([0-9\.]+)/],
-  ["opera-mini", /Opera Mini.*Version\/([0-9\.]+)/],
-  ["opera", /Opera\/([0-9\.]+)(?:\s|$)/],
-  ["opera", /OPR\/([0-9\.]+)(:?\s|$)/],
-  ["pie", /^Microsoft Pocket Internet Explorer\/(\d+\.\d+)$/],
-  ["pie", /^Mozilla\/\d\.\d+\s\(compatible;\s(?:MSP?IE|MSInternet Explorer) 
(\d+\.\d+);.*Windows CE.*\)$/],
-  ["netfront", /^Mozilla\/\d\.\d+.*NetFront\/(\d.\d)/],
-  ["ie", /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],
-  ["ie", /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],
-  ["ie", /MSIE\s(7\.0)/],
-  ["bb10", /BB10;\sTouch.*Version\/([0-9\.]+)/],
-  ["android", /Android\s([0-9\.]+)/],
-  ["ios", /Version\/([0-9\._]+).*Mobile.*Safari.*/],
-  ["safari", /Version\/([0-9\._]+).*Safari/],
-  ["facebook", /FB[AS]V\/([0-9\.]+)/],
-  ["instagram", /Instagram\s([0-9\.]+)/],
-  ["ios-webview", /AppleWebKit\/([0-9\.]+).*Mobile/],
-  ["ios-webview", /AppleWebKit\/([0-9\.]+).*Gecko\)$/],
-  ["curl", /^curl\/([0-9\.]+)$/],
-  ["searchbot", SEARCHBOX_UA_REGEX]
-];
-var operatingSystemRules = [
-  ["iOS", /iP(hone|od|ad)/],
-  ["Android OS", /Android/],
-  ["BlackBerry OS", /BlackBerry|BB10/],
-  ["Windows Mobile", /IEMobile/],
-  ["Amazon OS", /Kindle/],
-  ["Windows 3.11", /Win16/],
-  ["Windows 95", /(Windows 95)|(Win95)|(Windows_95)/],
-  ["Windows 98", /(Windows 98)|(Win98)/],
-  ["Windows 2000", /(Windows NT 5.0)|(Windows 2000)/],
-  ["Windows XP", /(Windows NT 5.1)|(Windows XP)/],
-  ["Windows Server 2003", /(Windows NT 5.2)/],
-  ["Windows Vista", /(Windows NT 6.0)/],
-  ["Windows 7", /(Windows NT 6.1)/],
-  ["Windows 8", /(Windows NT 6.2)/],
-  ["Windows 8.1", /(Windows NT 6.3)/],
-  ["Windows 10", /(Windows NT 10.0)/],
-  ["Windows ME", /Windows ME/],
-  ["Windows CE", /Windows CE|WinCE|Microsoft Pocket Internet Explorer/],
-  ["Open BSD", /OpenBSD/],
-  ["Sun OS", /SunOS/],
-  ["Chrome OS", /CrOS/],
-  ["Linux", /(Linux)|(X11)/],
-  ["Mac OS", /(Mac_PowerPC)|(Macintosh)/],
-  ["QNX", /QNX/],
-  ["BeOS", /BeOS/],
-  ["OS/2", /OS\/2/]
-];
-function detect(userAgent) {
-  if (!!userAgent) {
-    return parseUserAgent(userAgent);
-  }
-  if (typeof document === "undefined" && typeof navigator !== "undefined" && 
navigator.product === "ReactNative") {
-    return new ReactNativeInfo();
-  }
-  if (typeof navigator !== "undefined") {
-    return parseUserAgent(navigator.userAgent);
-  }
-  return getNodeVersion();
-}
-function matchUserAgent(ua) {
-  return ua !== "" && userAgentRules.reduce(function(matched, _a) {
-    var browser = _a[0], regex = _a[1];
-    if (matched) {
-      return matched;
-    }
-    var uaMatch = regex.exec(ua);
-    return !!uaMatch && [browser, uaMatch];
-  }, false);
-}
-function parseUserAgent(ua) {
-  var matchedRule = matchUserAgent(ua);
-  if (!matchedRule) {
-    return null;
-  }
-  var name = matchedRule[0], match = matchedRule[1];
-  if (name === "searchbot") {
-    return new BotInfo();
-  }
-  var versionParts = match[1] && 
match[1].split(".").join("_").split("_").slice(0, 3);
-  if (versionParts) {
-    if (versionParts.length < REQUIRED_VERSION_PARTS) {
-      versionParts = __spreadArray(__spreadArray([], versionParts, true), 
createVersionParts(REQUIRED_VERSION_PARTS - versionParts.length), true);
-    }
-  } else {
-    versionParts = [];
-  }
-  var version3 = versionParts.join(".");
-  var os = detectOS(ua);
-  var searchBotMatch = SEARCHBOT_OS_REGEX.exec(ua);
-  if (searchBotMatch && searchBotMatch[1]) {
-    return new SearchBotDeviceInfo(name, version3, os, searchBotMatch[1]);
-  }
-  return new BrowserInfo(name, version3, os);
-}
-function detectOS(ua) {
-  for (var ii = 0, count = operatingSystemRules.length; ii < count; ii++) {
-    var _a = operatingSystemRules[ii], os = _a[0], regex = _a[1];
-    var match = regex.exec(ua);
-    if (match) {
-      return os;
-    }
-  }
-  return null;
-}
-function getNodeVersion() {
-  var isNode = typeof process !== "undefined" && process.version;
-  return isNode ? new NodeInfo(process.version.slice(1)) : null;
-}
-function createVersionParts(count) {
-  var output = [];
-  for (var ii = 0; ii < count; ii++) {
-    output.push("0");
-  }
-  return output;
-}
-
 // src/packageLogs.ts
-var browserInfo = detect();
 var logs;
 var config;
 var intervalId;
@@ -444,10 +260,10 @@ function packageLog(e, detailFcn) {
   let log2 = {
     target: e.target ? getSelector(e.target) : null,
     path: buildPath(e),
-    pageUrl: window.location.href,
+    pageUrl: self.location.href,
     pageTitle: document.title,
     pageReferrer: document.referrer,
-    browser: detectBrowser(),
+    browser: self.navigator.userAgent,
     clientTime: timeFields.milli,
     microTime: timeFields.micro,
     location: getLocation(e),
@@ -493,10 +309,8 @@ function packageCustomLog(customLog, detailFcn, 
userAction) {
     details = staticDetailFcn();
   }
   const metaData = {
-    pageUrl: window.location.href,
-    pageTitle: document.title,
-    pageReferrer: document.referrer,
-    browser: detectBrowser(),
+    pageUrl: self.location.href,
+    browser: self.navigator.userAgent,
     clientTime: Date.now(),
     scrnRes: getScreenRes(),
     logType: "custom",
@@ -553,10 +367,10 @@ function packageIntervalLog(e) {
       intervalLog = {
         target: intervalId,
         path: intervalPath,
-        pageUrl: window.location.href,
+        pageUrl: self.location.href,
         pageTitle: document.title,
         pageReferrer: document.referrer,
-        browser: detectBrowser(),
+        browser: self.navigator.userAgent,
         count: intervalCounter,
         duration: timestamp - intervalTimer,
         startTime: intervalTimer,
@@ -619,7 +433,7 @@ function getLocation(e) {
   }
 }
 function getScreenRes() {
-  return { width: window.innerWidth, height: window.innerHeight };
+  return { width: self.innerWidth, height: self.innerHeight };
 }
 function getSelector(ele) {
   if (ele instanceof HTMLElement || ele instanceof Element) {
@@ -650,12 +464,6 @@ function selectorizePath(path) {
   }
   return pathSelectors;
 }
-function detectBrowser() {
-  return {
-    browser: browserInfo ? browserInfo.name : "",
-    version: browserInfo ? browserInfo.version : ""
-  };
-}
 function buildAttrs(e) {
   const attributes = {};
   const attributeBlackList = ["style"];
@@ -798,7 +606,7 @@ function attachHandlers(config3) {
   try {
     defineDetails(config3);
     Object.keys(events).forEach(function(ev) {
-      document.addEventListener(
+      self.addEventListener(
         ev,
         function(e) {
           packageLog(e, events[ev]);
@@ -807,7 +615,7 @@ function attachHandlers(config3) {
       );
     });
     intervalEvents.forEach(function(ev) {
-      document.addEventListener(
+      self.addEventListener(
         ev,
         function(e) {
           packageIntervalLog(e);
@@ -818,7 +626,7 @@ function attachHandlers(config3) {
     Object.keys(bufferedEvents).forEach(
       function(ev) {
         bufferBools[ev] = true;
-        window.addEventListener(
+        self.addEventListener(
           ev,
           function(e) {
             if (bufferBools[ev]) {
@@ -845,7 +653,7 @@ function attachHandlers(config3) {
       }
     );
     windowEvents.forEach(function(ev) {
-      window.addEventListener(
+      self.addEventListener(
         ev,
         function(e) {
           packageLog(e, function() {
@@ -863,6 +671,15 @@ function attachHandlers(config3) {
 
 // src/utils/auth/index.ts
 var authCallback = null;
+function updateAuthHeader(config3) {
+  if (authCallback) {
+    try {
+      config3.authHeader = authCallback();
+    } catch (e) {
+      console.error(`Error encountered while setting the auth header: ${e}`);
+    }
+  }
+}
 function registerAuthCallback(callback) {
   try {
     verifyCallback(callback);
@@ -882,37 +699,51 @@ function verifyCallback(callback) {
   }
 }
 
+// src/utils/headers/index.ts
+var headersCallback = null;
+function updateCustomHeaders(config3) {
+  if (headersCallback) {
+    try {
+      config3.headers = headersCallback();
+    } catch (e) {
+      console.error(`Error encountered while setting the headers: ${e}`);
+    }
+  }
+}
+
 // src/sendLogs.ts
 var sendIntervalId;
-var wsock;
 function initSender(logs3, config3) {
   if (sendIntervalId) {
     clearInterval(sendIntervalId);
   }
-  wsock = new WebSocket(config3.url);
-  wsock.onerror = () => {
-    console.log("no websockets detected");
-  };
-  wsock.onopen = () => {
-    console.log("connection established with websockets");
-  };
-  wsock.onclose = () => {
-    sendOnClose(logs3, config3);
-  };
+  sendIntervalId = sendOnInterval(logs3, config3);
   sendOnClose(logs3, config3);
 }
+function sendOnInterval(logs3, config3) {
+  return setInterval(function() {
+    if (!config3.on) {
+      return;
+    }
+    if (logs3.length >= config3.logCountThreshold) {
+      sendLogs(logs3.slice(0), config3, 0);
+      logs3.splice(0);
+    }
+  }, config3.transmitInterval);
+}
 function sendOnClose(logs3, config3) {
-  window.addEventListener("pagehide", function() {
+  self.addEventListener("pagehide", function() {
     if (!config3.on) {
       return;
     }
     if (logs3.length > 0) {
-      if (config3.isWebSocket()) {
+      const url = new URL(config3.url);
+      if (url.protocol === "ws:" || url.protocol === "wss:") {
         const data = JSON.stringify(logs3);
         wsock.send(data);
       } else {
         const headers = new Headers();
-        headers.set("Content-Type", "application/json;charset=UTF-8");
+        headers.set("Content-Type", "applicaiton/json;charset=UTF-8");
         if (config3.authHeader) {
           headers.set("Authorization", config3.authHeader.toString());
         }
@@ -929,20 +760,61 @@ function sendOnClose(logs3, config3) {
     }
   });
 }
+async function sendLogs(logs3, config3, retries) {
+  const data = JSON.stringify(logs3);
+  const url = new URL(config3.url);
+  if (url.protocol === "ws:" || url.protocol === "wss:") {
+    wsock.send(data);
+    return;
+  }
+  const headers = new Headers({
+    "Content-Type": "application/json;charset=UTF-8"
+  });
+  updateAuthHeader(config3);
+  if (config3.authHeader) {
+    const authHeaderValue = typeof config3.authHeader === "function" ? 
config3.authHeader() : config3.authHeader;
+    headers.set("Authorization", authHeaderValue);
+  }
+  updateCustomHeaders(config3);
+  if (config3.headers) {
+    for (const [header, value] of Object.entries(config3.headers)) {
+      headers.set(header, value);
+    }
+  }
+  async function attemptSend(remainingRetries) {
+    try {
+      const response = await fetch(config3.url, {
+        method: "POST",
+        headers,
+        body: data
+      });
+      if (!response.ok) {
+        if (remainingRetries > 0) {
+          return attemptSend(remainingRetries - 1);
+        } else {
+          throw new Error(`Failed to send logs: ${response.statusText}`);
+        }
+      }
+    } catch (error) {
+      if (remainingRetries > 0) {
+        return attemptSend(remainingRetries - 1);
+      }
+      throw error;
+    }
+  }
+  return attemptSend(retries);
+}
 
 // src/main.ts
 var config2 = Configuration.getInstance();
 var logs2 = [];
 var startLoadTimestamp = Date.now();
 var endLoadTimestamp;
-try {
-  window.onload = function() {
-    endLoadTimestamp = Date.now();
-  };
-} catch (error) {
+self.onload = function() {
   endLoadTimestamp = Date.now();
-}
+};
 var started = false;
+var wsock;
 config2.update({
   useraleVersion: version
 });
@@ -957,7 +829,7 @@ function setup(config3) {
       try {
         state = document.readyState;
       } catch (error) {
-        return;
+        state = "complete";
       }
       if (config3.autostart && (state === "interactive" || state === 
"complete")) {
         attachHandlers(config3);
@@ -1013,10 +885,10 @@ export {
   packageLog,
   registerAuthCallback,
   removeCallbacks,
-  setup,
   start,
   started,
   stop,
-  version2 as version
+  version2 as version,
+  wsock
 };
 //# sourceMappingURL=main.mjs.map
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/build/main.mjs.map 
b/products/userale/packages/flagon-userale/build/main.mjs.map
index fcf8d8b..3c5430b 100644
--- a/products/userale/packages/flagon-userale/build/main.mjs.map
+++ b/products/userale/packages/flagon-userale/build/main.mjs.map
@@ -1 +1 @@
-{"version":3,"sources":["../src/getInitialSettings.ts","../src/configure.ts","../../../node_modules/.pnpm/[email protected]/node_modules/detect-browser/es/index.js","../src/packageLogs.ts","../src/attachHandlers.ts","../src/utils/auth/index.ts","../src/sendLogs.ts","../src/main.ts"],"sourcesContent":["/*\n
 * Licensed to the Apache Software Foundation (ASF) under one or more\n * 
contributor license agreements.  See the NOTICE file distributed with\n * this 
work for additional informati [...]
\ No newline at end of file
+{"version":3,"sources":["../src/getInitialSettings.ts","../src/configure.ts","../src/packageLogs.ts","../src/attachHandlers.ts","../src/utils/auth/index.ts","../src/utils/headers/index.ts","../src/sendLogs.ts","../src/main.ts"],"sourcesContent":["/*\n
 * Licensed to the Apache Software Foundation (ASF) under one or more\n * 
contributor license agreements.  See the NOTICE file distributed with\n * this 
work for additional information regarding copyright ownership.\n * The ASF 
licenses this [...]
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/src/attachHandlers.ts 
b/products/userale/packages/flagon-userale/src/attachHandlers.ts
index 36975fb..18cc2cf 100644
--- a/products/userale/packages/flagon-userale/src/attachHandlers.ts
+++ b/products/userale/packages/flagon-userale/src/attachHandlers.ts
@@ -201,7 +201,7 @@ export function attachHandlers(config: Configuration): 
boolean {
     defineDetails(config);
 
     (Object.keys(events) as Events.AllowedEvents[]).forEach(function (ev) {
-      document.addEventListener(
+      self.addEventListener(
         ev,
         function (e) {
           packageLog(e, events[ev]);
@@ -211,7 +211,7 @@ export function attachHandlers(config: Configuration): 
boolean {
     });
 
     intervalEvents.forEach(function (ev) {
-      document.addEventListener(
+      self.addEventListener(
         ev,
         function (e) {
           packageIntervalLog(e);
@@ -224,7 +224,7 @@ export function attachHandlers(config: Configuration): 
boolean {
       function (ev) {
         bufferBools[ev] = true;
 
-        window.addEventListener(
+        self.addEventListener(
           ev,
           function (e) {
             if (bufferBools[ev]) {
@@ -253,7 +253,7 @@ export function attachHandlers(config: Configuration): 
boolean {
     );
 
     windowEvents.forEach(function (ev) {
-      window.addEventListener(
+      self.addEventListener(
         ev,
         function (e) {
           packageLog(e, function () {
diff --git a/products/userale/packages/flagon-userale/src/getInitialSettings.ts 
b/products/userale/packages/flagon-userale/src/getInitialSettings.ts
index 46f7844..ed8b758 100644
--- a/products/userale/packages/flagon-userale/src/getInitialSettings.ts
+++ b/products/userale/packages/flagon-userale/src/getInitialSettings.ts
@@ -26,19 +26,46 @@ let httpSessionId: string | null = null;
  * @return {Object} The extracted configuration object
  */
 export function getInitialSettings(): Settings.Config {
-  if (sessionId === null) {
-    sessionId = getsessionId(
-      "userAlesessionId",
-      "session_" + String(Date.now()),
-    );
-  }
 
-  if (httpSessionId === null) {
-    httpSessionId = getsessionId(
-      "userAleHttpSessionId",
-      generatehttpSessionId(),
-    );
-  }
+  if (typeof WorkerGlobalScope !== "undefined" &&
+    self instanceof WorkerGlobalScope) {
+      const settings: Settings.Config = {
+        authHeader: null,
+        autostart: true,
+        browserSessionId: null,
+        custIndex: null,
+        headers: null,
+        httpSessionId: null,
+        logCountThreshold: +(5),
+        logDetails: false,
+        resolution: +(500),
+        sessionId: sessionId,
+        time: (ts?: number) => (ts !== undefined ? ts : Date.now()),
+        toolName: null,
+        toolVersion: null,
+        transmitInterval: +(5000),
+        url: "http://localhost:8000";,
+        useraleVersion: null,
+        userFromParams: null,
+        userId: null,
+      };
+      return settings;
+    }
+
+    if (sessionId === null) {
+      sessionId = getsessionId(
+        "userAlesessionId",
+        "session_" + String(Date.now()),
+      );
+    }
+
+    if (httpSessionId === null) {
+      httpSessionId = getsessionId(
+        "userAleHttpSessionId",
+        generatehttpSessionId(),
+      );
+    }
+    
 
   const script =
     document.currentScript ||
@@ -83,12 +110,12 @@ export function getInitialSettings(): Settings.Config {
  *
  */
 export function getsessionId(sessionKey: string, value: any) {
-  if (window.sessionStorage.getItem(sessionKey) === null) {
-    window.sessionStorage.setItem(sessionKey, JSON.stringify(value));
+  if (self.sessionStorage.getItem(sessionKey) === null) {
+    self.sessionStorage.setItem(sessionKey, JSON.stringify(value));
     return value;
   }
 
-  return JSON.parse(window.sessionStorage.getItem(sessionKey) || "");
+  return JSON.parse(self.sessionStorage.getItem(sessionKey) || "");
 }
 
 /**
diff --git a/products/userale/packages/flagon-userale/src/main.ts 
b/products/userale/packages/flagon-userale/src/main.ts
index 9f75c21..45336f4 100644
--- a/products/userale/packages/flagon-userale/src/main.ts
+++ b/products/userale/packages/flagon-userale/src/main.ts
@@ -19,7 +19,7 @@ import { version as userAleVersion } from "../package.json";
 import { Configuration } from "@/configure";
 import { attachHandlers } from "@/attachHandlers";
 import { initPackager, packageCustomLog } from "@/packageLogs";
-import { initSender, sendOnClose } from "@/sendLogs";
+import { initSender } from "@/sendLogs";
 
 import type { Settings, Logging } from "@/types";
 
@@ -28,13 +28,9 @@ const logs: Array<Logging.Log> = [];
 
 const startLoadTimestamp = Date.now();
 let endLoadTimestamp: number;
-try {
-  window.onload = function() {
-    endLoadTimestamp = Date.now();
-  };
-} catch (error) {
+self.onload = function() {
   endLoadTimestamp = Date.now();
-}
+};
 
 export let started = false;
 export let wsock: WebSocket;
@@ -53,7 +49,6 @@ config.update({
   useraleVersion: userAleVersion,
 });
 initPackager(logs, config);
-// getWebsocketsEnabled(config);
 if (config.autostart) {
   setup(config);
 }
@@ -70,7 +65,8 @@ function setup(config: Configuration) {
       try {
         state = document.readyState;
       } catch (error) {
-        initSender(logs, config);
+        // Assume there is no DOM and this is a web worker context
+        state = "complete";
       }
 
       if (
@@ -95,24 +91,6 @@ function setup(config: Configuration) {
   }
 }
 
-/**
- * Checks to see if the specified backend URL supporsts Websockets
- * and updates the config accordingly
- */
-function getWebsocketsEnabled(config: Configuration) {
-  wsock = new WebSocket(config.url.replace("http://";, "ws://"));
-  wsock.onerror = () => {
-    console.log("no websockets detected");
-  };
-  wsock.onopen = () => {
-    console.log("connection established with websockets");
-    config.websocketsEnabled = true;
-  };
-  wsock.onclose = () => {
-    sendOnClose(logs, config);
-  };
-}
-
 // Export the Userale API
 export const version = userAleVersion;
 
diff --git a/products/userale/packages/flagon-userale/src/packageLogs.ts 
b/products/userale/packages/flagon-userale/src/packageLogs.ts
index 2cb0cbe..10da80f 100644
--- a/products/userale/packages/flagon-userale/src/packageLogs.ts
+++ b/products/userale/packages/flagon-userale/src/packageLogs.ts
@@ -15,10 +15,8 @@
  * limitations under the License.
  */
 
-import { detect } from "detect-browser";
 import { Callbacks, Logging } from "@/types";
 import { Configuration } from "@/configure";
-const browserInfo = detect();
 
 export let logs: Array<Logging.Log>;
 let config: Configuration;
@@ -119,10 +117,10 @@ export function packageLog(
   let log: Logging.Log = {
     target: e.target ? getSelector(e.target) : null,
     path: buildPath(e),
-    pageUrl: window.location.href,
+    pageUrl: self.location.href,
     pageTitle: document.title,
     pageReferrer: document.referrer,
-    browser: detectBrowser(),
+    browser: self.navigator.userAgent,
     clientTime: timeFields.milli,
     microTime: timeFields.micro,
     location: getLocation(e),
@@ -191,10 +189,10 @@ export function packageCustomLog(
   }
 
   const metaData = {
-    pageUrl: window.location.href,
-    pageTitle: document.title,
-    pageReferrer: document.referrer,
-    browser: detectBrowser(),
+    pageUrl: self.location.href,
+    // pageTitle: document.title,
+    // pageReferrer: document.referrer,
+    browser: self.navigator.userAgent,
     clientTime: Date.now(),
     scrnRes: getScreenRes(),
     logType: "custom",
@@ -276,10 +274,10 @@ export function packageIntervalLog(e: Event) {
       intervalLog = {
         target: intervalId,
         path: intervalPath,
-        pageUrl: window.location.href,
+        pageUrl: self.location.href,
         pageTitle: document.title,
         pageReferrer: document.referrer,
-        browser: detectBrowser(),
+        browser: self.navigator.userAgent,
         count: intervalCounter,
         duration: timestamp - intervalTimer, // microseconds
         startTime: intervalTimer,
@@ -362,7 +360,7 @@ export function getLocation(e: Event) {
  * @return {Object} An object containing the innerWidth and InnerHeight
  */
 export function getScreenRes() {
-  return { width: window.innerWidth, height: window.innerHeight };
+  return { width: self.innerWidth, height: self.innerHeight };
 }
 
 /**
@@ -420,13 +418,6 @@ export function selectorizePath(path: EventTarget[]) {
   return pathSelectors;
 }
 
-export function detectBrowser() {
-  return {
-    browser: browserInfo ? browserInfo.name : "",
-    version: browserInfo ? browserInfo.version : "",
-  };
-}
-
 /**
  * Builds an object containing attributes of an element.
  * Attempts to parse all attribute values as JSON text.
diff --git a/products/userale/packages/flagon-userale/src/sendLogs.ts 
b/products/userale/packages/flagon-userale/src/sendLogs.ts
index 2c9e6fc..0456e0e 100644
--- a/products/userale/packages/flagon-userale/src/sendLogs.ts
+++ b/products/userale/packages/flagon-userale/src/sendLogs.ts
@@ -68,13 +68,15 @@ export function sendOnClose(
   logs: Array<Logging.Log>,
   config: Configuration,
 ): void {
-  window.addEventListener("pagehide", function() {
+  self.addEventListener("pagehide", function() {
     if (!config.on) {
       return;
     }
 
     if (logs.length > 0) {
-      if (config.websocketsEnabled) {
+      const url = new URL(config.url);
+    
+      if (url.protocol === "ws:" || url.protocol === "wss:") {
         const data = JSON.stringify(logs);
         wsock.send(data);
       } else {
@@ -106,51 +108,64 @@ export function sendOnClose(
  * @param  {Configuration} config     configuration singleton.
  * @param  {Number} retries Maximum number of attempts to send the logs.
  */
-
-// @todo expose config object to sendLogs replate url with config.url
-export function sendLogs(
+export async function sendLogs(
   logs: Array<Logging.Log>,
   config: Configuration,
   retries: number,
-) {
+): Promise<void> {
   const data = JSON.stringify(logs);
+  const url = new URL(config.url);
 
-  if (config.websocketsEnabled) {
+  if (url.protocol === "ws:" || url.protocol === "wss:") {
     wsock.send(data);
-  } else {
-    const req = new XMLHttpRequest();
-
-    req.open("POST", config.url);
-
-    // Update headers
-    updateAuthHeader(config);
-    if (config.authHeader) {
-      req.setRequestHeader(
-        "Authorization",
-        typeof config.authHeader === "function"
-          ? config.authHeader()
-          : config.authHeader,
-      );
+    return;
+  }
+
+  // Build headers
+  const headers = new Headers({
+    "Content-Type": "application/json;charset=UTF-8",
+  });
+
+  updateAuthHeader(config);
+  if (config.authHeader) {
+    const authHeaderValue =
+      typeof config.authHeader === "function"
+        ? config.authHeader()
+        : config.authHeader;
+    headers.set("Authorization", authHeaderValue);
+  }
+
+  // Update custom headers last to allow them to over-write the defaults. This 
assumes
+  // the user knows what they are doing and may want to over-write the 
defaults.
+  updateCustomHeaders(config);
+  if (config.headers) {
+    for (const [header, value] of Object.entries(config.headers)) {
+      headers.set(header, value);
     }
-    req.setRequestHeader("Content-type", "application/json;charset=UTF-8");
-
-    // Update custom headers last to allow them to over-write the defaults. 
This assumes
-    // the user knows what they are doing and may want to over-write the 
defaults.
-    updateCustomHeaders(config);
-    if (config.headers) {
-      Object.entries(config.headers).forEach(([header, value]) => {
-        req.setRequestHeader(header, value);
+  }
+
+  async function attemptSend(remainingRetries: number): Promise<void> {
+    try {
+      const response = await fetch(config.url, {
+        method: "POST",
+        headers,
+        body: data,
       });
-    }
 
-    req.onreadystatechange = function() {
-      if (req.readyState === 4 && req.status !== 200) {
-        if (retries > 0) {
-          sendLogs(logs, config, retries--);
+      if (!response.ok) {
+        if (remainingRetries > 0) {
+          return attemptSend(remainingRetries - 1);
+        } else {
+          throw new Error(`Failed to send logs: ${response.statusText}`);
         }
       }
-    };
-
-    req.send(data);
+    } catch (error) {
+      if (remainingRetries > 0) {
+        return attemptSend(remainingRetries - 1);
+      }
+      throw error;
+    }
   }
+
+  return attemptSend(retries);
 }
diff --git a/products/userale/packages/flagon-userale/tsconfig.json 
b/products/userale/packages/flagon-userale/tsconfig.json
index 129b7b2..12d6a32 100644
--- a/products/userale/packages/flagon-userale/tsconfig.json
+++ b/products/userale/packages/flagon-userale/tsconfig.json
@@ -13,12 +13,14 @@
         "isolatedModules": true,
         "jsx": "preserve",
         "lib": [
+            "ES2021",
+            "WebWorker",
             "dom",
             "dom.iterable",
             "esnext"
         ],
         "module": "esnext",
-        "moduleResolution": "node",
+        "moduleResolution": "bundler",
         "noEmit": true,
         "noFallthroughCasesInSwitch": true,
         "noImplicitReturns": false,
@@ -34,7 +36,7 @@
         "skipLibCheck": true,
         "sourceMap": true,
         "strict": true,
-        "target": "es2015",
+        "target": "ES2021",
         "typeRoots": [
             "node_modules/@types/"
         ],
diff --git a/products/userale/packages/flagon-userale/tsup.config.js 
b/products/userale/packages/flagon-userale/tsup.config.js
index 7e734de..5bed426 100644
--- a/products/userale/packages/flagon-userale/tsup.config.js
+++ b/products/userale/packages/flagon-userale/tsup.config.js
@@ -4,7 +4,7 @@ export default defineConfig([
   {
     tsconfig: './tsconfig.json',
     entry: ['src/main.ts'],
-    outDir: 'build/esm',
+    outDir: 'build',
     format: ['esm'],
     name: 'userale',
     target: 'es2021',


Reply via email to