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 c09677d25e184bf3baf388c8f1e9fb71a24b27c2
Author: Jason Young <jk...@pm.me>
AuthorDate: Tue Jun 24 15:47:25 2025 -0700

    Move from husky to pre-commit
---
 .husky/pre-commit                                  |  83 --------
 .pre-commit-config.yaml                            |  30 +++
 eslint.config.js                                   |  34 ---
 products/userale/eslint.config.js                  |  50 +++++
 products/userale/package.json                      |  11 +-
 .../flagon-userale-ext/src/background/index.ts     |  66 +++---
 .../src/background/messages/config_change.ts       |  22 +-
 .../flagon-userale-ext/src/background/ports/log.ts |  34 +--
 .../packages/flagon-userale-ext/src/content.ts     |  40 ++--
 .../flagon-userale-ext/src/options/logging.tsx     |   2 +-
 .../packages/flagon-userale-ext/src/popup.tsx      |  14 +-
 .../flagon-userale-ext/src/utils/messaging.ts      |  16 +-
 .../flagon-userale-ext/src/utils/storage.ts        |   6 +-
 .../packages/flagon-userale-ext/tsconfig.json      |  26 +--
 .../userale/packages/flagon-userale/.eslintrc.json |  30 ---
 .../packages/flagon-userale/.husky/pre-commit      |  80 --------
 .../flagon-userale/build/attachHandlers.d.ts       |  81 ++++++++
 .../packages/flagon-userale/build/configure.d.ts   |  46 +++++
 .../flagon-userale/build/getInitialSettings.d.ts   |  21 ++
 .../packages/flagon-userale/build/main.d.ts        | 228 ++-------------------
 .../packages/flagon-userale/build/main.global.js   | 208 ++++---------------
 .../flagon-userale/build/main.global.js.map        |   2 +-
 .../userale/packages/flagon-userale/build/main.mjs | 227 ++++----------------
 .../packages/flagon-userale/build/main.mjs.map     |   2 +-
 .../packages/flagon-userale/build/packageLogs.d.ts | 106 ++++++++++
 .../packages/flagon-userale/build/sendLogs.d.ts    |  26 +++
 .../flagon-userale/build/utils/auth/index.d.ts     |  31 +++
 .../flagon-userale/build/utils/headers/index.d.ts  |  31 +++
 .../packages/flagon-userale/build/utils/index.d.ts |   3 +
 .../packages/flagon-userale/eslint.config.ts       |  29 ---
 .../example/react-app-example/src/App.js           |  43 ++--
 .../example/react-app-example/src/index.js         |  12 +-
 .../example/react-app-example/src/setupTests.js    |   2 +-
 .../packages/flagon-userale/example/test-client.js |  32 +++
 .../userale/packages/flagon-userale/package.json   |  18 +-
 .../flagon-userale/src/getInitialSettings.ts       |  76 +++----
 .../userale/packages/flagon-userale/src/main.ts    |  35 ++--
 .../packages/flagon-userale/src/sendLogs.ts        |   4 +-
 .../packages/flagon-userale/test/globals.d.ts      |   2 +
 .../test/{jest.config.js => jest.config.ts}        |   8 +
 .../test/spec/attachHandlers.spec.ts               |   4 +-
 .../flagon-userale/test/spec/sendLogs.spec.ts      |  22 +-
 .../userale/packages/flagon-userale/tsconfig.json  |  67 ++----
 .../packages/flagon-userale/tsconfig.test.json     |   9 +
 .../userale/packages/flagon-userale/tsup.config.js |   2 +-
 .../test/spec/fixtures/extension.fixture.ts        |   2 +-
 products/userale/tsconfig.base.json                |  18 ++
 products/userale/tsconfig.json                     |  30 +--
 48 files changed, 858 insertions(+), 1113 deletions(-)

diff --git a/.husky/pre-commit b/.husky/pre-commit
deleted file mode 100755
index a06fc79..0000000
--- a/.husky/pre-commit
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env sh
-. "$(dirname -- "$0")/_/husky.sh"
-
-npm run lint
-# 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.
-#!/bin/sh
-. "$(dirname "$0")/_/husky.sh"
-
-sound() {
-echo '\a'
-}
-
-echo "Running pre-commit hooks..."
-
-# Check Prettier standards
-npm run format ||
-(
-    sound
-    echo "❌ Prettier Check Failed. Run npm run format, add changes and try 
commit again.";
-    exit 1;
-)
-
-# Check ESLint Standards
-npm run lint ||
-(
-    sound
-    echo "❌ ESLint Check Failed. Make the required changes listed above, add 
changes and try to commit again."
-    exit 1;
-)
-
-# # Check types
-# npm run check-types ||
-# (
-#     sound
-#     echo "❌ Typescript Check Failed. Make the required changes listed above, 
add changes and try to commit again."
-#     exit 1;
-# )
-
-# # If everything passes... Now we can commit
-# echo "✅ Checks passed, trying to build..."
-
-# "npm" run build ||
-# (
-#     sound
-#     echo "❌ Build failed, check errors."
-#     exit 1;
-# )
-
-# echo "✅ Successful build, running tests..."
-# # After build, run unit tests
-# # Right now, runs all tests. Later scope to just unit tets, we can add 
e2e/integration as github actions on merge
-# npm run test ||
-# (
-#     sound
-#     echo "❌ Tests failed: View the logs to see what broke and fix it before 
re-committing."
-#     exit 1;
-# )
-
-# # After build, check license headers
-# # These should be fixed in the postbuild step, but if a new filetype
-# # emerges, this should catch it.
-# npm run license:check ||
-# (
-#     sound
-#     echo "❌ License check failed: View the logs to see what broke and fix it 
before re-committing."
-#     exit 1;
-# )
-
-# If everything passes... Now we can commit
-echo '✅ All tests passed'
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..1b87166
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,30 @@
+repos:
+  - repo: local
+    hooks:
+      - id: userale-format
+        name: Prettier Format Check (userale)
+        entry: bash -c 'cd products/userale && pnpm run format'
+        language: system
+        pass_filenames: false
+        files: ^products/userale/
+
+      - id: userale-lint
+        name: ESLint Check (userale)
+        entry: bash -c 'cd products/userale && pnpm run lint'
+        language: system
+        pass_filenames: false
+        files: ^products/userale/
+
+      - id: userale-build
+        name: Build Check (userale)
+        entry: bash -c 'cd products/userale && pnpm run build'
+        language: system
+        pass_filenames: false
+        files: ^products/userale/
+
+      - id: userale-test
+        name: Tests (userale)
+        entry: bash -c 'cd products/userale && pnpm run test'
+        language: system
+        pass_filenames: false
+        files: ^products/userale/
diff --git a/eslint.config.js b/eslint.config.js
deleted file mode 100644
index cd685ff..0000000
--- a/eslint.config.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// eslint.config.js
-import js from '@eslint/js'
-import ts from '@typescript-eslint/eslint-plugin'
-import parser from '@typescript-eslint/parser'
-
-export default [
-  js.configs.recommended,
-  {
-    files: ['**/*.ts'],
-    languageOptions: {
-      parser,
-      parserOptions: {
-        ecmaVersion: 'latest',
-        sourceType: 'module',
-        // project: './tsconfig.json',
-      },
-    },
-    plugins: {
-      '@typescript-eslint': ts,
-    },
-    rules: {
-      'no-unused-vars': 'off',
-
-      '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' 
}],
-      'no-undef': 'off',
-    },
-  },
-  {
-    files: ['**/*.js'],
-    rules: {
-      'no-unused-vars': 'warn',
-    },
-  },
-]
diff --git a/products/userale/eslint.config.js 
b/products/userale/eslint.config.js
new file mode 100644
index 0000000..c9ae0c6
--- /dev/null
+++ b/products/userale/eslint.config.js
@@ -0,0 +1,50 @@
+import js from '@eslint/js';
+import tseslint from 'typescript-eslint';
+import pluginJest from 'eslint-plugin-jest';
+
+export default [
+    js.configs.recommended,
+    ...tseslint.configs.recommended,
+    {
+        files: ['**/*.{ts,tsx,js,jsx}'],
+        languageOptions: {
+            parser: tseslint.parser,
+            sourceType: 'module',
+            globals: {
+                window: 'readonly',
+                document: 'readonly',
+                navigator: 'readonly',
+                console: 'readonly',
+            },
+        },
+        plugins: {
+            '@typescript-eslint': tseslint.plugin,
+        },
+        rules: {
+            'no-cond-assign': 'warn',
+            'no-constant-condition': 'warn',
+            'no-unused-vars': 'warn',
+            '@typescript-eslint/no-unused-vars': 'warn',
+            '@typescript-eslint/no-explicit-any': 'warn',
+        },
+    },
+    {
+        files: ['test/**/*.{ts,tsx,js,jsx}'],
+        plugins: {
+            jest: pluginJest,
+        },
+        languageOptions: {
+            globals: {
+                describe: 'readonly',
+                test: 'readonly',
+                expect: 'readonly',
+                beforeEach: 'readonly',
+                afterEach: 'readonly',
+                jest: 'readonly',
+            },
+        },
+        rules: {
+        // Optional Jest-specific rules
+        },
+    },
+];
diff --git a/products/userale/package.json b/products/userale/package.json
index f3b5674..016a4df 100644
--- a/products/userale/package.json
+++ b/products/userale/package.json
@@ -3,6 +3,8 @@
   "private": true,
   "version": "1.0.0",
   "scripts": {
+    "format": "prettier --ignore-path .gitignore --write 
'packages/**/{src,test}/**/*.{ts,js,tsx,jsx}'",
+    "lint": "eslint 'packages/**/src/**/*.{ts,js,tsx,jsx}' --fix",
     "build": "pnpm -r run build",
     "test": "playwright test -c ./test/playwright.config.ts && pnpm -r test",
     "pretest": "npx playwright install",
@@ -10,14 +12,21 @@
     "example:watch": "nodemon -w ./example/server example/server/server.js"
   },
   "devDependencies": {
+    "@eslint/js": "^9.29.0",
+    "@ianvs/prettier-plugin-sort-imports": "4.1.1",
     "@playwright/test": "^1.52.0",
     "@types/node": "^22.15.30",
     "body-parser": "^1.20.2",
+    "eslint": "9.29.0",
+    "eslint-plugin-jest": "^29.0.1",
     "express": "^4.18.2",
     "flagon-userale": "workspace:flagon-userale",
     "jsonschema": "^1.4.1",
-    "pnpm": "^10.0.0",
     "nodemon": "^3.0.2",
+    "pnpm": "^10.0.0",
+    "prettier": "3.6.0",
+    "typescript": "^5.8.3",
+    "typescript-eslint": "^7.8.0",
     "ws": "^8.18.0"
   }
 }
\ No newline at end of file
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 6e8df51..d3f1b35 100644
--- a/products/userale/packages/flagon-userale-ext/src/background/index.ts
+++ b/products/userale/packages/flagon-userale-ext/src/background/index.ts
@@ -1,35 +1,41 @@
-import { getStoredOptions } from "~/utils/storage";
-import { setOptions } from "./messages/config_change";
-import { sendToContent } from "~utils/messaging";
+import { getStoredOptions } from "~/utils/storage"
+import { sendToContent } from "~utils/messaging"
+
+import { setOptions } from "./messages/config_change"
 
 // Top level await is not supported so immediately execute this async function 
to set options from storage
-(async () => {
-    const options = await getStoredOptions();
-    setOptions(options);
-})();
+
+;(async () => {
+  const options = await getStoredOptions()
+  setOptions(options)
+})()
 
 // 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)
-  });
+  })
 }
 
 // Sends an event directly from a tab object
-function sendTabEventFromTab(tab: chrome.tabs.Tab, data: Record<string, any>, 
type: string) {
+function sendTabEventFromTab(
+  tab: chrome.tabs.Tab,
+  data: Record<string, any>,
+  type: string
+) {
   const payload = {
     type,
     tab,
     data
-  };
+  }
 
   sendToContent(tab.id!, { type: "tab-event", payload }).catch((err) =>
     console.warn(`Failed to send ${type} to tab ${tab.id}:`, err.message)
-  );
+  )
 }
 
-// Tab event handlers 
+// 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.
@@ -39,46 +45,46 @@ function sendTabEventFromTab(tab: chrome.tabs.Tab, data: 
Record<string, any>, ty
 
 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")
-    }
-});
+  // 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
+  const data = { addedTabId, removedTabId }
+  sendTabEvent(addedTabId, data, "tabs.onReplaced")
+})
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 f895ab4..3dec31b 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,20 +1,22 @@
-import type { PlasmoMessaging } from "@plasmohq/messaging";
-import * as userale from "flagon-userale";
-import type { StoredOptions } from "~utils/storage";
- 
-let allowListRegExp: RegExp;
+import * as userale from "flagon-userale"
+
+import type { PlasmoMessaging } from "@plasmohq/messaging"
+
+import type { StoredOptions } from "~utils/storage"
+
+let allowListRegExp: RegExp
 
 const handler: PlasmoMessaging.MessageHandler = async (req, res) => {
-  setOptions(req.body);
+  setOptions(req.body)
 }
 
 export function setOptions(options: StoredOptions) {
-  userale.options({url: options.loggingUrl});
-  allowListRegExp = new RegExp(options.allowList);
+  userale.options({ url: options.loggingUrl })
+  allowListRegExp = new RegExp(options.allowList)
 }
 
 export function getAllowListRegExp() {
-  return allowListRegExp;
+  return allowListRegExp
 }
 
-export default handler
\ No newline at end of file
+export default handler
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 445e34e..eaade7f 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,28 +1,30 @@
-import type { PlasmoMessaging } from "@plasmohq/messaging";
-import * as userale from "flagon-userale";
-import { getAllowListRegExp } from "~/background/messages/config_change";
+import * as userale from "flagon-userale"
+
+import type { PlasmoMessaging } from "@plasmohq/messaging"
+
+import { getAllowListRegExp } from "~/background/messages/config_change"
 
 const handler: PlasmoMessaging.PortHandler = async (req, res) => {
-  let log = req.body
-  log.browserSessionId = browserSessionId;
-  let allowListRegExp = getAllowListRegExp();
+  const log = req.body
+  log.browserSessionId = browserSessionId
+  const allowListRegExp = getAllowListRegExp()
   if (allowListRegExp.test(log.pageUrl)) {
-    console.log(log);
-    userale.log(log);
+    console.log(log)
+    userale.log(log)
   }
 }
 
-let browserSessionId = generateSessionId();
+const 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("");
+  // 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
diff --git a/products/userale/packages/flagon-userale-ext/src/content.ts 
b/products/userale/packages/flagon-userale-ext/src/content.ts
index e31c14d..46e67b0 100644
--- a/products/userale/packages/flagon-userale-ext/src/content.ts
+++ b/products/userale/packages/flagon-userale-ext/src/content.ts
@@ -12,29 +12,33 @@ const logPort = getPort("log")
 
 userale.addCallbacks({
   rerouteLog(log) {
-    console.log(log);
-    logPort.postMessage({body: log});
-    return false;
+    console.log(log)
+    logPort.postMessage({ body: log })
+    return false
   }
 })
 
 chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
-  if( message.type == "tab-event") {
-    const { type, tab, data } = message.payload;
+  if (message.type == "tab-event") {
+    const { type, tab, data } = message.payload
     userale.packageCustomLog(
-      {type},
-      () => { return data; },
-      true,
-    );
-    sendResponse({ status: "received" });
+      { 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" });
-  }  
+      { type: message.type },
+      () => {
+        return message.payload
+      },
+      true
+    )
+    sendResponse({ status: "received" })
+  }
 
-  return true 
-})
\ No newline at end of file
+  return true
+})
diff --git 
a/products/userale/packages/flagon-userale-ext/src/options/logging.tsx 
b/products/userale/packages/flagon-userale-ext/src/options/logging.tsx
index 6fd221e..1e55f52 100644
--- a/products/userale/packages/flagon-userale-ext/src/options/logging.tsx
+++ b/products/userale/packages/flagon-userale-ext/src/options/logging.tsx
@@ -23,7 +23,7 @@ function Logging() {
     <div>
       <h2>Logging Options</h2>
       <form onSubmit={handleSubmit}>
-      <label htmlFor="logging-url">Logging Endpoint URL:</label>
+        <label htmlFor="logging-url">Logging Endpoint URL:</label>
         <input
           id="logging-url"
           value={loggingUrl}
diff --git a/products/userale/packages/flagon-userale-ext/src/popup.tsx 
b/products/userale/packages/flagon-userale-ext/src/popup.tsx
index 42216a6..15a858d 100644
--- a/products/userale/packages/flagon-userale-ext/src/popup.tsx
+++ b/products/userale/packages/flagon-userale-ext/src/popup.tsx
@@ -1,5 +1,6 @@
-import { useState } from "react";
-import Options from "~/options";
+import { useState } from "react"
+
+import Options from "~/options"
 import { sendToContent } from "~utils/messaging"
 
 function IndexPopup() {
@@ -10,15 +11,18 @@ function IndexPopup() {
     e.preventDefault()
 
     try {
-      const [tab] = await chrome.tabs.query({ active: true, currentWindow: 
true });
-      if (!tab?.id) throw new Error("No active tab found");
+      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
diff --git 
a/products/userale/packages/flagon-userale-ext/src/utils/messaging.ts 
b/products/userale/packages/flagon-userale-ext/src/utils/messaging.ts
index b53f411..18b3a8e 100644
--- a/products/userale/packages/flagon-userale-ext/src/utils/messaging.ts
+++ b/products/userale/packages/flagon-userale-ext/src/utils/messaging.ts
@@ -1,12 +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)
-        })
+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 034fc10..bc064d2 100644
--- a/products/userale/packages/flagon-userale-ext/src/utils/storage.ts
+++ b/products/userale/packages/flagon-userale-ext/src/utils/storage.ts
@@ -43,13 +43,13 @@ export async function setStoredOptions(values: 
Partial<StoredOptions>) {
   } catch (error) {
     return error
   }
-  
+
   // Store the options for after the browser is closed
-  await browser.storage.local.set(values);
+  await browser.storage.local.set(values)
 
   // Notify the background script of the change
   return await sendToBackground({
     name: "config_change",
     body: values
   })
-}
\ No newline at end of file
+}
diff --git a/products/userale/packages/flagon-userale-ext/tsconfig.json 
b/products/userale/packages/flagon-userale-ext/tsconfig.json
index 8af9f45..b25f425 100644
--- a/products/userale/packages/flagon-userale-ext/tsconfig.json
+++ b/products/userale/packages/flagon-userale-ext/tsconfig.json
@@ -1,20 +1,12 @@
 {
-  "extends": "plasmo/templates/tsconfig.base",
-  "exclude": [
-    "node_modules"
-  ],
-  "include": [
-    ".plasmo/index.d.ts",
-    "./**/*.ts",
-    "./**/*.tsx"
-  ],
+  "extends": "../../tsconfig.base.json",
   "compilerOptions": {
-    "moduleResolution": "bundler",
-    "paths": {
-      "~*": [
-        "./src/*"
-      ]
-    },
-    "baseUrl": "."
-  }
+    "composite": true,
+    "declaration": true,
+    "module": "ESNext",
+    "moduleResolution": "node",
+    "noEmit": false
+  },
+  "include": [".plasmo/index.d.ts", "./**/*.ts", "./**/*.tsx"],
+  "exclude": ["node_modules"]
 }
diff --git a/products/userale/packages/flagon-userale/.eslintrc.json 
b/products/userale/packages/flagon-userale/.eslintrc.json
deleted file mode 100644
index b076f65..0000000
--- a/products/userale/packages/flagon-userale/.eslintrc.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  "parserOptions" : {
-    "sourceType" : "module",
-    "ecmaFeatures" : {
-      "modules" : true
-    }
-  },
-  "plugins": ["@typescript-eslint"],
-  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
-  "env" : {
-    "browser" : true,
-    "es6" : true
-  },
-  "rules" : {
-    "no-cond-assign" : "warn",
-    "no-constant-condition" : "warn",
-    "no-unused-vars" : "warn",
-    "@typescript-eslint/no-unused-vars": "warn",
-    "@typescript-eslint/no-explicit-any": "warn"
-  },
-  "overrides": [
-    {
-        "files": ["test/**/*"],
-        "plugins": ["jest"],
-        "env": {
-            "jest": true
-        }
-    }
-  ]
-}
diff --git a/products/userale/packages/flagon-userale/.husky/pre-commit 
b/products/userale/packages/flagon-userale/.husky/pre-commit
deleted file mode 100644
index 2a8d238..0000000
--- a/products/userale/packages/flagon-userale/.husky/pre-commit
+++ /dev/null
@@ -1,80 +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.
-#!/bin/sh
-. "$(dirname "$0")/_/husky.sh"
-
-sound() {
-echo '\a'
-}
-
-echo "Running pre-commit hooks..."
-
-# Check Prettier standards
-npm run format ||
-(
-    sound
-    echo "❌ Prettier Check Failed. Run npm run format, add changes and try 
commit again.";
-    exit 1;
-)
-
-# Check ESLint Standards
-npm run lint ||
-(
-    sound
-    echo "❌ ESLint Check Failed. Make the required changes listed above, add 
changes and try to commit again."
-    exit 1;
-)
-
-# Check types
-npm run check-types ||
-(
-    sound
-    echo "❌ Typescript Check Failed. Make the required changes listed above, 
add changes and try to commit again."
-    exit 1;
-)
-
-# If everything passes... Now we can commit
-echo "✅ Checks passed, trying to build..."
-
-"npm" run build ||
-(
-    sound
-    echo "❌ Build failed, check errors."
-    exit 1;
-)
-
-echo "✅ Successful build, running tests..."
-# After build, run unit tests
-# Right now, runs all tests. Later scope to just unit tets, we can add 
e2e/integration as github actions on merge
-npm run test ||
-(
-    sound
-    echo "❌ Tests failed: View the logs to see what broke and fix it before 
re-committing."
-    exit 1;
-)
-
-# After build, check license headers
-# These should be fixed in the postbuild step, but if a new filetype
-# emerges, this should catch it.
-npm run license:check ||
-(
-    sound
-    echo "❌ License check failed: View the logs to see what broke and fix it 
before re-committing."
-    exit 1;
-)
-
-# If everything passes... Now we can commit
-echo '✅ All tests passed'
-
diff --git a/products/userale/packages/flagon-userale/build/attachHandlers.d.ts 
b/products/userale/packages/flagon-userale/build/attachHandlers.d.ts
new file mode 100644
index 0000000..2ae8cc5
--- /dev/null
+++ b/products/userale/packages/flagon-userale/build/attachHandlers.d.ts
@@ -0,0 +1,81 @@
+import { Events, Logging, Settings } from "@/types";
+import { Configuration } from "@/configure";
+/**
+ * Maps a MouseEvent to an object containing useful information.
+ * @param  {MouseEvent} e Event to extract data from
+ */
+export declare function extractMouseDetails(e: MouseEvent): {
+    clicks: number;
+    ctrl: boolean;
+    alt: boolean;
+    shift: boolean;
+    meta: boolean;
+};
+/** Maps a KeyboardEvent to an object containing useful infromation
+ * @param {KeyboardEvent} e Event to extract data from
+ */
+export declare function extractKeyboardDetails(e: KeyboardEvent): {
+    key: string;
+    code: string;
+    ctrl: boolean;
+    alt: boolean;
+    shift: boolean;
+    meta: boolean;
+};
+/**
+ * Maps an InputEvent to an object containing useful information.
+ * @param  {InputEvent} e Event to extract data from
+ */
+export declare function extractInputDetails(e: InputEvent): {
+    value: string;
+};
+/**
+ * Maps a ChangeEvent to an object containing useful information.
+ * @param  {Events.ChangeEvent} e Event to extract data from
+ */
+export declare function extractChangeDetails(e: Events.ChangeEvent): {
+    value: any;
+};
+/**
+ * Maps a WheelEvent to an object containing useful information.
+ * @param  {WheelEvent} e Event to extract data from
+ */
+export declare function extractWheelDetails(e: WheelEvent): {
+    x: number;
+    y: number;
+    z: number;
+};
+/**
+ * Maps a ScrollEvent to an object containing useful information.
+ */
+export declare function extractScrollDetails(): {
+    x: number;
+    y: number;
+};
+/**
+ * Maps a ResizeEvent to an object containing useful information.
+ */
+export declare function extractResizeDetails(): {
+    width: number;
+    height: number;
+};
+/**
+ * Defines the way information is extracted from various events.
+ * Also defines which events we will listen to.
+ * @param  {Settings.Config} config Configuration object to read from.
+ */
+export declare function defineDetails(config: Settings.DefaultConfig): void;
+/**
+ * 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.
+ */
+export declare function defineCustomDetails(options: Settings.DefaultConfig, 
type: Events.AllowedEvents): Logging.DynamicDetailFunction | null | undefined;
+/**
+ * Hooks the event handlers for each event type of interest.
+ * @param  {Configuration} config Configuration singleton to use.
+ * @return {boolean}        Whether the operation succeeded
+ */
+export declare function attachHandlers(config: Configuration): boolean;
+//# sourceMappingURL=attachHandlers.d.ts.map
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/build/configure.d.ts 
b/products/userale/packages/flagon-userale/build/configure.d.ts
new file mode 100644
index 0000000..e2ca829
--- /dev/null
+++ b/products/userale/packages/flagon-userale/build/configure.d.ts
@@ -0,0 +1,46 @@
+import type { Settings } from "@/types";
+export declare class Configuration {
+    [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;
+    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;
+}
+//# sourceMappingURL=configure.d.ts.map
\ No newline at end of file
diff --git 
a/products/userale/packages/flagon-userale/build/getInitialSettings.d.ts 
b/products/userale/packages/flagon-userale/build/getInitialSettings.d.ts
new file mode 100644
index 0000000..3dd3167
--- /dev/null
+++ b/products/userale/packages/flagon-userale/build/getInitialSettings.d.ts
@@ -0,0 +1,21 @@
+import type { Settings } from "./types";
+/**
+ * Extracts the initial configuration settings from the
+ * currently executing script tag.
+ * @return {Object} The extracted configuration object
+ */
+export declare function getInitialSettings(): Settings.Config;
+/**
+ * defines sessionId, stores it in sessionStorage, checks to see if there is a 
sessionId in
+ * storage when script is started. This prevents events like 'submit', which 
refresh page data
+ * from refreshing the current user session
+ *
+ */
+export declare function getsessionId(sessionKey: string, value: any): any;
+/**
+ * Creates a function to normalize the timestamp of the provided event.
+ * @param  {Event} e An event containing a timeStamp property.
+ * @return {typeof timeStampScale~tsScaler}   The timestamp normalizing 
function.
+ */
+export declare function timeStampScale(e: Event): Settings.TimeFunction;
+//# sourceMappingURL=getInitialSettings.d.ts.map
\ 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 a3cc624..f6df136 100644
--- a/products/userale/packages/flagon-userale/build/main.d.ts
+++ b/products/userale/packages/flagon-userale/build/main.d.ts
@@ -1,234 +1,30 @@
-/*
- * 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 const version: string;
+import type { Settings, Logging } from "@/types";
+export declare let started: boolean;
+export { defineCustomDetails as details } from "@/attachHandlers";
+export { registerAuthCallback as registerAuthCallback } from "@/utils";
+export { addCallbacks as addCallbacks, removeCallbacks as removeCallbacks, 
packageLog as packageLog, packageCustomLog as packageCustomLog, getSelector as 
getSelector, buildPath as buildPath, } from "@/packageLogs";
+export type { Logging } from "@/types";
+export declare const version: string;
 /**
  * Used to start the logging process if the
  * autostart configuration option is set to false.
  */
-declare function start(): void;
+export declare function start(): void;
 /**
  * Halts the logging process. Logs will no longer be sent.
  */
-declare function stop(): void;
+export 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;
+export 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 { Logging, addCallbacks, buildPath, defineCustomDetails as details, 
getSelector, log, options, packageCustomLog, packageLog, registerAuthCallback, 
removeCallbacks, start, started, stop, version };
+export declare function log(customLog: Logging.CustomLog | undefined): boolean;
+//# sourceMappingURL=main.d.ts.map
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/build/main.global.js 
b/products/userale/packages/flagon-userale/build/main.global.js
index 490b8d0..2a715da 100644
--- a/products/userale/packages/flagon-userale/build/main.global.js
+++ b/products/userale/packages/flagon-userale/build/main.global.js
@@ -14,49 +14,18 @@
   See the License for the specific language governing permissions and
   limitations under the License.*/
 (() => {
-  var __defProp = Object.defineProperty;
-  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
-  var __getOwnPropNames = Object.getOwnPropertyNames;
-  var __hasOwnProp = Object.prototype.hasOwnProperty;
-  var __esm = (fn, res) => function __init() {
-    return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
-  };
-  var __export = (target, all) => {
-    for (var name in all)
-      __defProp(target, name, { get: all[name], enumerable: true });
-  };
-  var __copyProps = (to, from, except, desc) => {
-    if (from && typeof from === "object" || typeof from === "function") {
-      for (let key of __getOwnPropNames(from))
-        if (!__hasOwnProp.call(to, key) && key !== except)
-          __defProp(to, key, { get: () => from[key], enumerable: !(desc = 
__getOwnPropDesc(from, key)) || desc.enumerable });
-    }
-    return to;
-  };
-  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: 
true }), mod);
-
   // src/packageLogs.ts
-  var packageLogs_exports = {};
-  __export(packageLogs_exports, {
-    addCallbacks: () => addCallbacks,
-    buildAttrs: () => buildAttrs,
-    buildCSS: () => buildCSS,
-    buildPath: () => buildPath,
-    cbHandlers: () => cbHandlers,
-    extractTimeFields: () => extractTimeFields,
-    filterHandler: () => filterHandler,
-    getLocation: () => getLocation,
-    getScreenRes: () => getScreenRes,
-    getSelector: () => getSelector,
-    initPackager: () => initPackager,
-    logs: () => logs,
-    mapHandler: () => mapHandler,
-    packageCustomLog: () => packageCustomLog,
-    packageIntervalLog: () => packageIntervalLog,
-    packageLog: () => packageLog,
-    removeCallbacks: () => removeCallbacks,
-    selectorizePath: () => selectorizePath
-  });
+  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 = {};
@@ -322,7 +291,7 @@
         let val = attr.value;
         try {
           val = JSON.parse(val);
-        } catch (error) {
+        } catch {
         }
         attributes[attr.name] = val;
       }
@@ -340,30 +309,22 @@
     }
     return properties;
   }
-  var logs, config, intervalId, intervalType, intervalPath, intervalTimer, 
intervalCounter, intervalLog, filterHandler, mapHandler, cbHandlers;
-  var init_packageLogs = __esm({
-    "src/packageLogs.ts"() {
-      "use strict";
-      filterHandler = null;
-      mapHandler = null;
-      cbHandlers = {};
-    }
-  });
 
   // src/attachHandlers.ts
-  var attachHandlers_exports = {};
-  __export(attachHandlers_exports, {
-    attachHandlers: () => attachHandlers,
-    defineCustomDetails: () => defineCustomDetails,
-    defineDetails: () => defineDetails,
-    extractChangeDetails: () => extractChangeDetails,
-    extractInputDetails: () => extractInputDetails,
-    extractKeyboardDetails: () => extractKeyboardDetails,
-    extractMouseDetails: () => extractMouseDetails,
-    extractResizeDetails: () => extractResizeDetails,
-    extractScrollDetails: () => extractScrollDetails,
-    extractWheelDetails: () => extractWheelDetails
-  });
+  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,
@@ -383,11 +344,6 @@
       meta: e.metaKey
     };
   }
-  function extractInputDetails(e) {
-    return {
-      value: e.target.value
-    };
-  }
   function extractChangeDetails(e) {
     return {
       value: e.target.value
@@ -529,25 +485,9 @@
       return false;
     }
   }
-  var events, bufferBools, bufferedEvents, refreshEvents, intervalEvents, 
windowEvents;
-  var init_attachHandlers = __esm({
-    "src/attachHandlers.ts"() {
-      "use strict";
-      init_packageLogs();
-      intervalEvents = [
-        "click",
-        "focus",
-        "blur",
-        "input",
-        "change",
-        "mouseover",
-        "submit"
-      ];
-      windowEvents = ["load", "blur", "focus"];
-    }
-  });
 
   // src/utils/auth/index.ts
+  var authCallback = null;
   function updateAuthHeader(config3) {
     if (authCallback) {
       try {
@@ -562,7 +502,7 @@
       verifyCallback(callback);
       authCallback = callback;
       return true;
-    } catch (e) {
+    } catch {
       return false;
     }
   }
@@ -575,18 +515,9 @@
       throw new Error("Userale auth callback must return a string");
     }
   }
-  function resetAuthCallback() {
-    authCallback = null;
-  }
-  var authCallback;
-  var init_auth = __esm({
-    "src/utils/auth/index.ts"() {
-      "use strict";
-      authCallback = null;
-    }
-  });
 
   // src/utils/headers/index.ts
+  var headersCallback = null;
   function updateCustomHeaders(config3) {
     if (headersCallback) {
       try {
@@ -596,63 +527,6 @@
       }
     }
   }
-  function registerHeadersCallback(callback) {
-    try {
-      verifyCallback2(callback);
-      headersCallback = callback;
-      return true;
-    } catch (e) {
-      return false;
-    }
-  }
-  function verifyCallback2(callback) {
-    if (typeof callback !== "function") {
-      throw new Error("Userale headers callback must be a function");
-    }
-    const result = callback();
-    if (typeof result !== "object") {
-      throw new Error("Userale headers callback must return an object");
-    }
-    for (const [key, value] of Object.entries(result)) {
-      if (typeof key !== "string" || typeof value !== "string") {
-        throw new Error(
-          "Userale header callback must return an object with string keys and 
values"
-        );
-      }
-    }
-  }
-  function resetHeadersCallback() {
-    headersCallback = null;
-  }
-  var headersCallback;
-  var init_headers = __esm({
-    "src/utils/headers/index.ts"() {
-      "use strict";
-      headersCallback = null;
-    }
-  });
-
-  // src/utils/index.ts
-  var utils_exports = {};
-  __export(utils_exports, {
-    authCallback: () => authCallback,
-    headersCallback: () => headersCallback,
-    registerAuthCallback: () => registerAuthCallback,
-    registerHeadersCallback: () => registerHeadersCallback,
-    resetAuthCallback: () => resetAuthCallback,
-    resetHeadersCallback: () => resetHeadersCallback,
-    updateAuthHeader: () => updateAuthHeader,
-    updateCustomHeaders: () => updateCustomHeaders,
-    verifyAuthCallback: () => verifyCallback,
-    verifyHeadersCallback: () => verifyCallback2
-  });
-  var init_utils = __esm({
-    "src/utils/index.ts"() {
-      "use strict";
-      init_auth();
-      init_headers();
-    }
-  });
 
   // package.json
   var version = "2.4.0";
@@ -841,12 +715,7 @@
   var Configuration = _Configuration;
   Configuration.instance = null;
 
-  // src/main.ts
-  init_attachHandlers();
-  init_packageLogs();
-
   // src/sendLogs.ts
-  init_utils();
   var sendIntervalId;
   var wsock;
   function initSender(logs3, config3) {
@@ -946,9 +815,6 @@
   }
 
   // src/main.ts
-  init_attachHandlers();
-  init_utils();
-  init_packageLogs();
   var config2 = Configuration.getInstance();
   var logs2 = [];
   var startLoadTimestamp = Date.now();
@@ -1025,14 +891,14 @@
       options,
       log,
       version,
-      details: (init_attachHandlers(), 
__toCommonJS(attachHandlers_exports)).defineCustomDetails,
-      registerAuthCallback: (init_utils(), 
__toCommonJS(utils_exports)).registerAuthCallback,
-      addCallbacks: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).addCallbacks,
-      removeCallbacks: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).removeCallbacks,
-      packageLog: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).packageLog,
-      packageCustomLog: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).packageCustomLog,
-      getSelector: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).getSelector,
-      buildPath: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).buildPath
+      details: defineCustomDetails,
+      registerAuthCallback,
+      addCallbacks,
+      removeCallbacks,
+      packageLog,
+      packageCustomLog,
+      getSelector,
+      buildPath
     };
   }
 })();
diff --git a/products/userale/packages/flagon-userale/build/main.global.js.map 
b/products/userale/packages/flagon-userale/build/main.global.js.map
index a0eea58..53a70f8 100644
--- a/products/userale/packages/flagon-userale/build/main.global.js.map
+++ b/products/userale/packages/flagon-userale/build/main.global.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../src/packageLogs.ts","../src/attachHandlers.ts","../src/utils/auth/index.ts","../src/utils/headers/index.ts","../src/utils/index.ts","../src/getInitialSettings.ts","../src/configure.ts","../src/main.ts","../src/sendLogs.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 [...]
\ No newline at end of file
+{"version":3,"sources":["../src/packageLogs.ts","../src/attachHandlers.ts","../src/utils/auth/index.ts","../src/utils/headers/index.ts","../src/getInitialSettings.ts","../src/configure.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/build/main.mjs 
b/products/userale/packages/flagon-userale/build/main.mjs
index a9318e2..c61e588 100644
--- a/products/userale/packages/flagon-userale/build/main.mjs
+++ b/products/userale/packages/flagon-userale/build/main.mjs
@@ -12,55 +12,18 @@
   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.*/
-var __defProp = Object.defineProperty;
-var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
-var __getOwnPropNames = Object.getOwnPropertyNames;
-var __hasOwnProp = Object.prototype.hasOwnProperty;
-var __esm = (fn, res) => function __init() {
-  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
-};
-var __export = (target, all) => {
-  for (var name in all)
-    __defProp(target, name, { get: all[name], enumerable: true });
-};
-var __copyProps = (to, from, except, desc) => {
-  if (from && typeof from === "object" || typeof from === "function") {
-    for (let key of __getOwnPropNames(from))
-      if (!__hasOwnProp.call(to, key) && key !== except)
-        __defProp(to, key, { get: () => from[key], enumerable: !(desc = 
__getOwnPropDesc(from, key)) || desc.enumerable });
-  }
-  return to;
-};
-var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: 
true }), mod);
-
-// 
../../node_modules/.pnpm/tsup@5.12.9_@swc+core@1.11.22_@swc+helpers@0.5.17__postcss@8.5.3_ts-node@10.9.2_@swc+co_7dfb40117802bc289cccbf76535c67e5/node_modules/tsup/assets/esm_shims.js
-var init_esm_shims = __esm({
-  
"../../node_modules/.pnpm/tsup@5.12.9_@swc+core@1.11.22_@swc+helpers@0.5.17__postcss@8.5.3_ts-node@10.9.2_@swc+co_7dfb40117802bc289cccbf76535c67e5/node_modules/tsup/assets/esm_shims.js"()
 {
-  }
-});
-
 // src/packageLogs.ts
-var packageLogs_exports = {};
-__export(packageLogs_exports, {
-  addCallbacks: () => addCallbacks,
-  buildAttrs: () => buildAttrs,
-  buildCSS: () => buildCSS,
-  buildPath: () => buildPath,
-  cbHandlers: () => cbHandlers,
-  extractTimeFields: () => extractTimeFields,
-  filterHandler: () => filterHandler,
-  getLocation: () => getLocation,
-  getScreenRes: () => getScreenRes,
-  getSelector: () => getSelector,
-  initPackager: () => initPackager,
-  logs: () => logs,
-  mapHandler: () => mapHandler,
-  packageCustomLog: () => packageCustomLog,
-  packageIntervalLog: () => packageIntervalLog,
-  packageLog: () => packageLog,
-  removeCallbacks: () => removeCallbacks,
-  selectorizePath: () => selectorizePath
-});
+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 = {};
@@ -326,7 +289,7 @@ function buildAttrs(e) {
       let val = attr.value;
       try {
         val = JSON.parse(val);
-      } catch (error) {
+      } catch {
       }
       attributes[attr.name] = val;
     }
@@ -344,31 +307,22 @@ function buildCSS(e) {
   }
   return properties;
 }
-var logs, config, intervalId, intervalType, intervalPath, intervalTimer, 
intervalCounter, intervalLog, filterHandler, mapHandler, cbHandlers;
-var init_packageLogs = __esm({
-  "src/packageLogs.ts"() {
-    "use strict";
-    init_esm_shims();
-    filterHandler = null;
-    mapHandler = null;
-    cbHandlers = {};
-  }
-});
 
 // src/attachHandlers.ts
-var attachHandlers_exports = {};
-__export(attachHandlers_exports, {
-  attachHandlers: () => attachHandlers,
-  defineCustomDetails: () => defineCustomDetails,
-  defineDetails: () => defineDetails,
-  extractChangeDetails: () => extractChangeDetails,
-  extractInputDetails: () => extractInputDetails,
-  extractKeyboardDetails: () => extractKeyboardDetails,
-  extractMouseDetails: () => extractMouseDetails,
-  extractResizeDetails: () => extractResizeDetails,
-  extractScrollDetails: () => extractScrollDetails,
-  extractWheelDetails: () => extractWheelDetails
-});
+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,
@@ -388,11 +342,6 @@ function extractKeyboardDetails(e) {
     meta: e.metaKey
   };
 }
-function extractInputDetails(e) {
-  return {
-    value: e.target.value
-  };
-}
 function extractChangeDetails(e) {
   return {
     value: e.target.value
@@ -534,26 +483,9 @@ function attachHandlers(config3) {
     return false;
   }
 }
-var events, bufferBools, bufferedEvents, refreshEvents, intervalEvents, 
windowEvents;
-var init_attachHandlers = __esm({
-  "src/attachHandlers.ts"() {
-    "use strict";
-    init_esm_shims();
-    init_packageLogs();
-    intervalEvents = [
-      "click",
-      "focus",
-      "blur",
-      "input",
-      "change",
-      "mouseover",
-      "submit"
-    ];
-    windowEvents = ["load", "blur", "focus"];
-  }
-});
 
 // src/utils/auth/index.ts
+var authCallback = null;
 function updateAuthHeader(config3) {
   if (authCallback) {
     try {
@@ -568,7 +500,7 @@ function registerAuthCallback(callback) {
     verifyCallback(callback);
     authCallback = callback;
     return true;
-  } catch (e) {
+  } catch {
     return false;
   }
 }
@@ -581,19 +513,9 @@ function verifyCallback(callback) {
     throw new Error("Userale auth callback must return a string");
   }
 }
-function resetAuthCallback() {
-  authCallback = null;
-}
-var authCallback;
-var init_auth = __esm({
-  "src/utils/auth/index.ts"() {
-    "use strict";
-    init_esm_shims();
-    authCallback = null;
-  }
-});
 
 // src/utils/headers/index.ts
+var headersCallback = null;
 function updateCustomHeaders(config3) {
   if (headersCallback) {
     try {
@@ -603,77 +525,11 @@ function updateCustomHeaders(config3) {
     }
   }
 }
-function registerHeadersCallback(callback) {
-  try {
-    verifyCallback2(callback);
-    headersCallback = callback;
-    return true;
-  } catch (e) {
-    return false;
-  }
-}
-function verifyCallback2(callback) {
-  if (typeof callback !== "function") {
-    throw new Error("Userale headers callback must be a function");
-  }
-  const result = callback();
-  if (typeof result !== "object") {
-    throw new Error("Userale headers callback must return an object");
-  }
-  for (const [key, value] of Object.entries(result)) {
-    if (typeof key !== "string" || typeof value !== "string") {
-      throw new Error(
-        "Userale header callback must return an object with string keys and 
values"
-      );
-    }
-  }
-}
-function resetHeadersCallback() {
-  headersCallback = null;
-}
-var headersCallback;
-var init_headers = __esm({
-  "src/utils/headers/index.ts"() {
-    "use strict";
-    init_esm_shims();
-    headersCallback = null;
-  }
-});
-
-// src/utils/index.ts
-var utils_exports = {};
-__export(utils_exports, {
-  authCallback: () => authCallback,
-  headersCallback: () => headersCallback,
-  registerAuthCallback: () => registerAuthCallback,
-  registerHeadersCallback: () => registerHeadersCallback,
-  resetAuthCallback: () => resetAuthCallback,
-  resetHeadersCallback: () => resetHeadersCallback,
-  updateAuthHeader: () => updateAuthHeader,
-  updateCustomHeaders: () => updateCustomHeaders,
-  verifyAuthCallback: () => verifyCallback,
-  verifyHeadersCallback: () => verifyCallback2
-});
-var init_utils = __esm({
-  "src/utils/index.ts"() {
-    "use strict";
-    init_esm_shims();
-    init_auth();
-    init_headers();
-  }
-});
-
-// src/main.ts
-init_esm_shims();
 
 // package.json
 var version = "2.4.0";
 
-// src/configure.ts
-init_esm_shims();
-
 // src/getInitialSettings.ts
-init_esm_shims();
 var sessionId = null;
 var httpSessionId = null;
 function getInitialSettings() {
@@ -857,13 +713,7 @@ var _Configuration = class {
 var Configuration = _Configuration;
 Configuration.instance = null;
 
-// src/main.ts
-init_attachHandlers();
-init_packageLogs();
-
 // src/sendLogs.ts
-init_esm_shims();
-init_utils();
 var sendIntervalId;
 var wsock;
 function initSender(logs3, config3) {
@@ -963,9 +813,6 @@ async function sendLogs(logs3, config3, retries) {
 }
 
 // src/main.ts
-init_attachHandlers();
-init_utils();
-init_packageLogs();
 var config2 = Configuration.getInstance();
 var logs2 = [];
 var startLoadTimestamp = Date.now();
@@ -1042,14 +889,14 @@ if (typeof window !== "undefined") {
     options,
     log,
     version,
-    details: (init_attachHandlers(), 
__toCommonJS(attachHandlers_exports)).defineCustomDetails,
-    registerAuthCallback: (init_utils(), 
__toCommonJS(utils_exports)).registerAuthCallback,
-    addCallbacks: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).addCallbacks,
-    removeCallbacks: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).removeCallbacks,
-    packageLog: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).packageLog,
-    packageCustomLog: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).packageCustomLog,
-    getSelector: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).getSelector,
-    buildPath: (init_packageLogs(), 
__toCommonJS(packageLogs_exports)).buildPath
+    details: defineCustomDetails,
+    registerAuthCallback,
+    addCallbacks,
+    removeCallbacks,
+    packageLog,
+    packageCustomLog,
+    getSelector,
+    buildPath
   };
 }
 export {
diff --git a/products/userale/packages/flagon-userale/build/main.mjs.map 
b/products/userale/packages/flagon-userale/build/main.mjs.map
index 969d89b..2c72769 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":["../../../node_modules/.pnpm/tsup@5.12.9_@swc+core@1.11.22_@swc+helpers@0.5.17__postcss@8.5.3_ts-node@10.9.2_@swc+co_7dfb40117802bc289cccbf76535c67e5/node_modules/tsup/assets/esm_shims.js","../src/packageLogs.ts","../src/attachHandlers.ts","../src/utils/auth/index.ts","../src/utils/headers/index.ts","../src/utils/index.ts","../src/main.ts","../src/configure.ts","../src/getInitialSettings.ts","../src/sendLogs.ts"],"sourcesContent":["//
 Shim globals in esm bundle\ni [...]
\ No newline at end of file
+{"version":3,"sources":["../src/packageLogs.ts","../src/attachHandlers.ts","../src/utils/auth/index.ts","../src/utils/headers/index.ts","../src/getInitialSettings.ts","../src/configure.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/build/packageLogs.d.ts 
b/products/userale/packages/flagon-userale/build/packageLogs.d.ts
new file mode 100644
index 0000000..fc4dff2
--- /dev/null
+++ b/products/userale/packages/flagon-userale/build/packageLogs.d.ts
@@ -0,0 +1,106 @@
+import { Callbacks, Logging } from "@/types";
+import { Configuration } from "@/configure";
+export declare let logs: Array<Logging.Log>;
+export declare const filterHandler: CallableFunction | null;
+export declare const mapHandler: CallableFunction | null;
+export declare let cbHandlers: Callbacks.CallbackMap;
+/**
+ * Adds named callbacks to be executed when logging.
+ * @param  {Object } newCallbacks An object containing named callback 
functions.
+ */
+export 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.
+ */
+export declare function removeCallbacks(targetKeys: string[]): void;
+/**
+ * Assigns the config and log container to be used by the logging functions.
+ * @param  {Array<Logging.Log>} newLogs   Log container.
+ * @param  {Object} newConfig Configuration to use while logging.
+ */
+export declare function initPackager(newLogs: Array<Logging.Log>, newConfig: 
Configuration): 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.
+ */
+export 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.
+ */
+export declare function packageCustomLog(customLog: Logging.CustomLog, 
detailFcn: Logging.DynamicDetailFunction | Logging.StaticDetailFunction, 
userAction: boolean): boolean;
+/**
+ * Extract the millisecond and microsecond portions of a timestamp.
+ * @param  {Number} timeStamp The timestamp to split into millisecond and 
microsecond fields.
+ * @return {Object}           An object containing the millisecond
+ *                            and microsecond portions of the timestamp.
+ */
+export declare function extractTimeFields(timeStamp: number): {
+    milli: number;
+    micro: number;
+};
+/**
+ * Track intervals and gather details about it.
+ * @param {Object} e
+ * @return boolean
+ */
+export declare function packageIntervalLog(e: Event): boolean;
+/**
+ * Extracts coordinate information from the event
+ * depending on a few browser quirks.
+ * @param  {Event} e The event to extract coordinate information from.
+ * @return {Object}   An object containing nullable x and y coordinates for 
the event.
+ */
+export declare function getLocation(e: Event): {
+    x: number;
+    y: number;
+} | {
+    x: null;
+    y: null;
+} | undefined;
+/**
+ * Extracts innerWidth and innerHeight to provide estimates of screen 
resolution
+ * @return {Object} An object containing the innerWidth and InnerHeight
+ */
+export declare function getScreenRes(): {
+    width: number;
+    height: number;
+};
+/**
+ * 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.
+ */
+export 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.
+ */
+export declare function buildPath(e: Event): string[];
+/**
+ * Builds a CSS selector path from the provided list of elements.
+ * @param  {EventTarget[]} path Array of HTML Elements from which the path 
should be built.
+ * @return {string[]}      Array of string CSS selectors.
+ */
+export declare function selectorizePath(path: EventTarget[]): string[];
+/**
+ * Builds an object containing attributes of an element.
+ * Attempts to parse all attribute values as JSON text.
+ * @param  {Event} e Event from which the target element's attributes should 
be extracted.
+ * @return {Record<string, any>} Object with element attributes as key-value 
pairs.
+ */
+export declare function buildAttrs(e: Event): Record<string, any>;
+/**
+ * Builds an object containing all CSS properties of an element.
+ * @param  {Event} e Event from which the target element's properties should 
be extracted.
+ * @return {Record<string, string>} Object with all CSS properties as 
key-value pairs.
+ */
+export declare function buildCSS(e: Event): Record<string, string>;
+//# sourceMappingURL=packageLogs.d.ts.map
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/build/sendLogs.d.ts 
b/products/userale/packages/flagon-userale/build/sendLogs.d.ts
new file mode 100644
index 0000000..7aef366
--- /dev/null
+++ b/products/userale/packages/flagon-userale/build/sendLogs.d.ts
@@ -0,0 +1,26 @@
+import { Configuration } from "@/configure";
+import { Logging } from "@/types";
+/**
+ * Initializes the log queue processors.
+ * @param  {Array<Logging.Log>} logs   Array of logs to append to.
+ * @param  {Configuration} config Configuration object to use when logging.
+ */
+export declare function initSender(logs: Array<Logging.Log>, config: 
Configuration): void;
+/**
+ * Checks the provided log array on an interval, flushing the logs
+ * if the queue has reached the threshold specified by the provided config.
+ * @param  {Array<Logging.Log>} logs   Array of logs to read from.
+ * @param  {Configuration} config Configuration singleton to be read from.
+ * @return {Number}        The newly created interval id.
+ */
+export declare function sendOnInterval(logs: Array<Logging.Log>, config: 
Configuration): NodeJS.Timeout;
+export declare function sendOnClose(logs: Array<Logging.Log>, config: 
Configuration): void;
+/**
+ * Sends the provided array of logs to the specified url,
+ * retrying the request up to the specified number of retries.
+ * @param  {Array<Logging.Log>} logs    Array of logs to send.
+ * @param  {Configuration} config     configuration singleton.
+ * @param  {Number} retries Maximum number of attempts to send the logs.
+ */
+export declare function sendLogs(logs: Array<Logging.Log>, config: 
Configuration, retries: number): Promise<void>;
+//# sourceMappingURL=sendLogs.d.ts.map
\ No newline at end of file
diff --git 
a/products/userale/packages/flagon-userale/build/utils/auth/index.d.ts 
b/products/userale/packages/flagon-userale/build/utils/auth/index.d.ts
new file mode 100644
index 0000000..fee0184
--- /dev/null
+++ b/products/userale/packages/flagon-userale/build/utils/auth/index.d.ts
@@ -0,0 +1,31 @@
+import { Configuration } from "@/configure";
+import { Callbacks } from "@/types";
+export declare let authCallback: Callbacks.AuthCallback | null;
+/**
+ * Fetches the most up-to-date auth header string from the auth callback
+ * and updates the config object with the new value.
+ * @param {Configuration} config Configuration object to be updated.
+ * @param {Function} authCallback Callback used to fetch the newest header.
+ * @returns {void}
+ */
+export declare function updateAuthHeader(config: Configuration): void;
+/**
+ * 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.
+ */
+export declare function registerAuthCallback(callback: 
Callbacks.AuthCallback): boolean;
+/**
+ * Verify that the provided callback is a function which returns a string
+ * @param {Function} callback Callback used to fetch the newest header. Should 
return a string.
+ * @throws {Error} If the callback is not a function or does not return a 
string.
+ * @returns {void}
+ */
+export declare function verifyCallback(callback: Callbacks.AuthCallback): void;
+/**
+ * Resets the authCallback to null. Used for primarily for testing, but could 
be used
+ * to remove the callback in production.
+ * @returns {void}
+ */
+export declare function resetAuthCallback(): void;
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git 
a/products/userale/packages/flagon-userale/build/utils/headers/index.d.ts 
b/products/userale/packages/flagon-userale/build/utils/headers/index.d.ts
new file mode 100644
index 0000000..a8c3190
--- /dev/null
+++ b/products/userale/packages/flagon-userale/build/utils/headers/index.d.ts
@@ -0,0 +1,31 @@
+import { Configuration } from "@/configure";
+import { Callbacks } from "@/types";
+export declare let headersCallback: Callbacks.HeadersCallback | null;
+/**
+ * Fetches the most up-to-date custom headers object from the headers callback
+ * and updates the config object with the new value.
+ * @param {Configuration} config Configuration object to be updated.
+ * @param {Callbacks.HeadersCallback} headersCallback Callback used to fetch 
the newest headers.
+ * @returns {void}
+ */
+export declare function updateCustomHeaders(config: Configuration): void;
+/**
+ * Registers the provided callback to be used when updating the auth header.
+ * @param {Callbacks.HeadersCallback} callback Callback used to fetch the 
newest headers. Should return an object.
+ * @returns {boolean} Whether the operation succeeded.
+ */
+export declare function registerHeadersCallback(callback: 
Callbacks.HeadersCallback): boolean;
+/**
+ * Verify that the provided callback is a function which returns a string
+ * @param {Callbacks.HeadersCallback} callback Callback used to fetch the 
newest header. Should return an object.
+ * @throws {Error} If the callback is not a function or does not return a 
string.
+ * @returns {void}
+ */
+export declare function verifyCallback(callback: Callbacks.HeadersCallback): 
void;
+/**
+ * Resets the authCallback to null. Used for primarily for testing, but could 
be used
+ * to remove the callback in production.
+ * @returns {void}
+ */
+export declare function resetHeadersCallback(): void;
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/build/utils/index.d.ts 
b/products/userale/packages/flagon-userale/build/utils/index.d.ts
new file mode 100644
index 0000000..99a4b5a
--- /dev/null
+++ b/products/userale/packages/flagon-userale/build/utils/index.d.ts
@@ -0,0 +1,3 @@
+export { authCallback, updateAuthHeader, registerAuthCallback, 
resetAuthCallback, verifyCallback as verifyAuthCallback, } from "./auth";
+export { headersCallback, updateCustomHeaders, registerHeadersCallback, 
resetHeadersCallback, verifyCallback as verifyHeadersCallback, } from 
"./headers";
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/eslint.config.ts 
b/products/userale/packages/flagon-userale/eslint.config.ts
deleted file mode 100644
index 859a5ec..0000000
--- a/products/userale/packages/flagon-userale/eslint.config.ts
+++ /dev/null
@@ -1,29 +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.
- */
-
-import globals from "globals";
-import pluginJs from "@eslint/js";
-import tseslint from "typescript-eslint";
-
-
-export default [
-  {languageOptions: { globals: globals.browser }},
-  pluginJs.configs.recommended,
-  ...tseslint.configs.recommended,
-];
diff --git 
a/products/userale/packages/flagon-userale/example/react-app-example/src/App.js 
b/products/userale/packages/flagon-userale/example/react-app-example/src/App.js
index fb8ef69..f5979e6 100644
--- 
a/products/userale/packages/flagon-userale/example/react-app-example/src/App.js
+++ 
b/products/userale/packages/flagon-userale/example/react-app-example/src/App.js
@@ -15,35 +15,46 @@
  * limitations under the License.
  */
 
-import logo from './logo.svg';
-import './App.css';
-import * as userale from  'flagon-userale'
+import logo from "./logo.svg";
+import "./App.css";
+import * as userale from "flagon-userale";
 
 function App() {
   const handleOnClick = () => {
-    userale.start()
-  }
+    userale.start();
+  };
 
   userale.options({
     autostart: false,
-    logCountThreshold: '1',
-    transmitInterval: '1000',
-    toolName: "Apache UserALE React Example"
-  })
+    logCountThreshold: "1",
+    transmitInterval: "1000",
+    toolName: "Apache UserALE React Example",
+  });
 
   userale.filter(function (log) {
-    var type_array = ['mouseup', 'mouseover', 'mousedown', 'keydown', 
'dblclick', 'blur', 'focus', 'input', 'wheel', 'scroll'];
-    var logType_array = ['interval'];
-    return !type_array.includes(log.type) && 
!logType_array.includes(log.logType);
-  })
+    var type_array = [
+      "mouseup",
+      "mouseover",
+      "mousedown",
+      "keydown",
+      "dblclick",
+      "blur",
+      "focus",
+      "input",
+      "wheel",
+      "scroll",
+    ];
+    var logType_array = ["interval"];
+    return (
+      !type_array.includes(log.type) && !logType_array.includes(log.logType)
+    );
+  });
 
   return (
     <div className="App">
       <header className="App-header">
         <img src={logo} className="App-logo" alt="logo" />
-        <p onClick={handleOnClick}>
-          Click this text to start userale.
-        </p>
+        <p onClick={handleOnClick}>Click this text to start userale.</p>
         <a
           className="App-link"
           href="https://reactjs.org";
diff --git 
a/products/userale/packages/flagon-userale/example/react-app-example/src/index.js
 
b/products/userale/packages/flagon-userale/example/react-app-example/src/index.js
index 1485810..4b7e251 100644
--- 
a/products/userale/packages/flagon-userale/example/react-app-example/src/index.js
+++ 
b/products/userale/packages/flagon-userale/example/react-app-example/src/index.js
@@ -15,14 +15,14 @@
  * limitations under the License.
  */
 
-import React from 'react';
-import ReactDOM from 'react-dom';
-import './index.css';
-import App from './App';
+import React from "react";
+import ReactDOM from "react-dom";
+import "./index.css";
+import App from "./App";
 
 ReactDOM.render(
   <React.StrictMode>
     <App />
   </React.StrictMode>,
-  document.getElementById('root')
-);
\ No newline at end of file
+  document.getElementById("root"),
+);
diff --git 
a/products/userale/packages/flagon-userale/example/react-app-example/src/setupTests.js
 
b/products/userale/packages/flagon-userale/example/react-app-example/src/setupTests.js
index ff2e7b5..08020be 100644
--- 
a/products/userale/packages/flagon-userale/example/react-app-example/src/setupTests.js
+++ 
b/products/userale/packages/flagon-userale/example/react-app-example/src/setupTests.js
@@ -19,4 +19,4 @@
 // allows you to do things like:
 // expect(element).toHaveTextContent(/react/i)
 // learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom';
+import "@testing-library/jest-dom";
diff --git a/products/userale/packages/flagon-userale/example/test-client.js 
b/products/userale/packages/flagon-userale/example/test-client.js
new file mode 100644
index 0000000..a807a79
--- /dev/null
+++ b/products/userale/packages/flagon-userale/example/test-client.js
@@ -0,0 +1,32 @@
+"use strict";
+/*
+ * 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.
+ */
+const ws = new WebSocket("ws://localhost:8000");
+const encoder = new TextEncoder();
+ws.onopen = (event) => {
+    let logs = new Array();
+    logs.push('{"target": "#document","path": [ "Window" ], "pageUrl": 
"https://github.com/apache/flagon/tree/master/docker";, "pageTitle": 
"flagon/docker at master · apache/flagon · GitHub", "pageReferrer": 
"https://gov.teams.microsoft.us/";, "browser": { "browser": "chrome", "version": 
"116.0.0" }, "clientTime": 1719530111079, "microTime": 0,"location": { "x": 
null, "y": null }, "scrnRes": { "width": 1349, "height":954 }, "type": "load", 
"logType": "raw", "userAction": true, "details": { [...]
+    logs.push('{"target": "#document","path": [ "Window" ], "pageUrl": 
"https://github.com/apache/flagon/tree/master/docker";, "pageTitle": 
"flagon/docker at master · apache/flagon · GitHub", "pageReferrer": 
"https://gov.teams.microsoft.us/";, "browser": { "browser": "chrome", "version": 
"116.0.0" }, "clientTime": 1719530111079, "microTime": 0,"location": { "x": 
null, "y": null }, "scrnRes": { "width": 1349, "height":954 }, "type": "load", 
"logType": "raw", "userAction": true, "details": { [...]
+    let data = JSON.stringify(logs);
+    //let arr = encoder.encode(message);
+    ws.send(data);
+};
+ws.onmessage = (event) => {
+    console.log(event.data);
+};
diff --git a/products/userale/packages/flagon-userale/package.json 
b/products/userale/packages/flagon-userale/package.json
index 6d1fde2..edf1b8d 100644
--- a/products/userale/packages/flagon-userale/package.json
+++ b/products/userale/packages/flagon-userale/package.json
@@ -12,13 +12,9 @@
     }
   },
   "scripts": {
-    "format": "prettier --ignore-path .gitignore --write src/ test/",
-    "lint": "eslint ./src --fix --ext ts --ext js",
-    "check-types": "tsc --pretty --noEmit",
-    "build": "tsc && tsup",
+    "build": "tsup --onSuccess 'tsc --emitDeclarationOnly --declaration'",
     "clean": "rm -rf ./build",
-    "test": "jest -c ./test/jest.config.js",
-    "prepare": "husky",
+    "test": "jest -c ./test/jest.config.ts",
     "commit": "cz"
   },
   "repository": {
@@ -57,37 +53,29 @@
     "npm": ">= 9.x"
   },
   "devDependencies": {
-    "@eslint/js": "^9.2.0",
+    "@babel/preset-typescript": "^7.27.1",
     "@jest/globals": "^29.7.0",
-    "@playwright/test": "^1.52.0",
     "@types/jest": "^29.5.14",
     "@types/jsdom": "^21.1.6",
     "@types/node": "^20.14.2",
     "@types/ws": "^8.5.12",
-    "@typescript-eslint/eslint-plugin": "^7.8.0",
-    "@typescript-eslint/parser": "^7.8.0",
     "@typescript/lib-dom": "npm:@types/web@^0.0.144",
     "body-parser": "^1.20.2",
     "commander": "^12.1.0",
     "cypress": "^13.6.0",
     "cz-conventional-changelog": "^3.3.0",
     "dom-storage": "^2.1.0",
-    "esbuild": "^0.21.2",
-    "eslint": "^8.57.0",
     "express": "^4.18.2",
     "global-jsdom": "^24.0.0",
     "globals": "^15.2.0",
-    "husky": "^9.0.11",
     "jest": "^29.7.0",
     "jest-environment-jsdom": "^29.7.0",
     "jsdom": "^24.0.0",
     "jsonschema": "^1.4.1",
-    "prettier": "^3.2.5",
     "ts-jest": "^29.4.0",
     "ts-node": "^10.9.2",
     "tsup": "^5.10.0",
     "typescript": "^5.8.3",
-    "typescript-eslint": "^7.8.0",
     "whatwg-fetch": "^3.6.20",
     "ws": "^8.18.0"
   },
diff --git a/products/userale/packages/flagon-userale/src/getInitialSettings.ts 
b/products/userale/packages/flagon-userale/src/getInitialSettings.ts
index ed8b758..34fe95e 100644
--- a/products/userale/packages/flagon-userale/src/getInitialSettings.ts
+++ b/products/userale/packages/flagon-userale/src/getInitialSettings.ts
@@ -26,46 +26,46 @@ let httpSessionId: string | null = null;
  * @return {Object} The extracted configuration object
  */
 export function getInitialSettings(): Settings.Config {
+  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 (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 (sessionId === null) {
+    sessionId = getsessionId(
+      "userAlesessionId",
+      "session_" + String(Date.now()),
+    );
+  }
 
-    if (httpSessionId === null) {
-      httpSessionId = getsessionId(
-        "userAleHttpSessionId",
-        generatehttpSessionId(),
-      );
-    }
-    
+  if (httpSessionId === null) {
+    httpSessionId = getsessionId(
+      "userAleHttpSessionId",
+      generatehttpSessionId(),
+    );
+  }
 
   const script =
     document.currentScript ||
diff --git a/products/userale/packages/flagon-userale/src/main.ts 
b/products/userale/packages/flagon-userale/src/main.ts
index ab6c6bf..3a209e2 100644
--- a/products/userale/packages/flagon-userale/src/main.ts
+++ b/products/userale/packages/flagon-userale/src/main.ts
@@ -15,10 +15,20 @@
  * limitations under the License.
  */
 
+import { defineCustomDetails } from "@/attachHandlers";
+import { registerAuthCallback } from "@/utils";
+import {
+  addCallbacks,
+  removeCallbacks,
+  packageLog,
+  packageCustomLog,
+  getSelector,
+  buildPath,
+  initPackager,
+} from "@/packageLogs";
 import { version as userAleVersion } from "../package.json";
 import { Configuration } from "@/configure";
 import { attachHandlers } from "@/attachHandlers";
-import { initPackager, packageCustomLog } from "@/packageLogs";
 import { initSender } from "@/sendLogs";
 
 import type { Settings, Logging } from "@/types";
@@ -28,7 +38,7 @@ const logs: Array<Logging.Log> = [];
 
 const startLoadTimestamp = Date.now();
 let endLoadTimestamp: number;
-self.onload = function() {
+self.onload = function () {
   endLoadTimestamp = Date.now();
 };
 
@@ -76,7 +86,7 @@ function setup(config: Configuration) {
         attachHandlers(config);
         initSender(logs, config);
         started = config.on = true;
-        if(typeof window !== "undefined" && typeof document !== "undefined") {
+        if (typeof window !== "undefined" && typeof document !== "undefined") {
           packageCustomLog(
             {
               type: "load",
@@ -145,7 +155,6 @@ export function log(customLog: Logging.CustomLog | 
undefined) {
   }
 }
 
-
 // Only attach to window in IIFE builds
 if (typeof window !== "undefined") {
   (window as any).userale = {
@@ -154,13 +163,13 @@ if (typeof window !== "undefined") {
     options,
     log,
     version: userAleVersion,
-    details: require("@/attachHandlers").defineCustomDetails,
-    registerAuthCallback: require("@/utils").registerAuthCallback,
-    addCallbacks: require("@/packageLogs").addCallbacks,
-    removeCallbacks: require("@/packageLogs").removeCallbacks,
-    packageLog: require("@/packageLogs").packageLog,
-    packageCustomLog: require("@/packageLogs").packageCustomLog,
-    getSelector: require("@/packageLogs").getSelector,
-    buildPath: require("@/packageLogs").buildPath,
+    details: defineCustomDetails,
+    registerAuthCallback,
+    addCallbacks,
+    removeCallbacks,
+    packageLog,
+    packageCustomLog,
+    getSelector,
+    buildPath,
   };
-}
\ No newline at end of file
+}
diff --git a/products/userale/packages/flagon-userale/src/sendLogs.ts 
b/products/userale/packages/flagon-userale/src/sendLogs.ts
index 715f460..c4bc647 100644
--- a/products/userale/packages/flagon-userale/src/sendLogs.ts
+++ b/products/userale/packages/flagon-userale/src/sendLogs.ts
@@ -73,14 +73,14 @@ export function sendOnClose(
   logs: Array<Logging.Log>,
   config: Configuration,
 ): void {
-  self.addEventListener("pagehide", function() {
+  self.addEventListener("pagehide", function () {
     if (!config.on) {
       return;
     }
 
     if (logs.length > 0) {
       const url = new URL(config.url);
-    
+
       if (url.protocol === "ws:" || url.protocol === "wss:") {
         const data = JSON.stringify(logs);
         wsock.send(data);
diff --git a/products/userale/packages/flagon-userale/test/globals.d.ts 
b/products/userale/packages/flagon-userale/test/globals.d.ts
new file mode 100644
index 0000000..9debc78
--- /dev/null
+++ b/products/userale/packages/flagon-userale/test/globals.d.ts
@@ -0,0 +1,2 @@
+// Ensures jest globals are recognized in test files
+import "@types/jest";
diff --git a/products/userale/packages/flagon-userale/test/jest.config.js 
b/products/userale/packages/flagon-userale/test/jest.config.ts
similarity index 91%
rename from products/userale/packages/flagon-userale/test/jest.config.js
rename to products/userale/packages/flagon-userale/test/jest.config.ts
index e38b6cb..6202fc3 100644
--- a/products/userale/packages/flagon-userale/test/jest.config.js
+++ b/products/userale/packages/flagon-userale/test/jest.config.ts
@@ -31,6 +31,14 @@ const config = {
   },
   setupFiles: ["<rootDir>/test/jest.setup.js"],
   testMatch: ["<rootDir>/test/spec/(*.)+(spec|test).[tj]s?(x)"],
+  transform: {
+    "^.+\\.tsx?$": [
+      "ts-jest",
+      {
+        tsconfig: "./tsconfig.test.json",
+      },
+    ],
+  },
   // Optionally specify this if you want default jsdom behavior:
   // testEnvironment: "jsdom",
 };
diff --git 
a/products/userale/packages/flagon-userale/test/spec/attachHandlers.spec.ts 
b/products/userale/packages/flagon-userale/test/spec/attachHandlers.spec.ts
index 8c0b0ec..3a6a6f7 100644
--- a/products/userale/packages/flagon-userale/test/spec/attachHandlers.spec.ts
+++ b/products/userale/packages/flagon-userale/test/spec/attachHandlers.spec.ts
@@ -106,7 +106,7 @@ describe("attachHandlers", () => {
     const rate = 500;
     jest
       .spyOn(global.document, "addEventListener")
-      .mockImplementation(() => { });
+      .mockImplementation(() => {});
     // Tries to call an event 3 times. Twice in quick succession, then once 
after the set delay.
     // Number of actual calls to packageLog are recorded in callCount. Should 
amount to exactly 2 calls.
     const listenerHook = (ev: string, fn: CallableFunction) => {
@@ -135,6 +135,6 @@ describe("attachHandlers", () => {
 
   describe("defineDetails", () => {
     // TODO: clarify what constitutes "high detail events" and what is 
"correct"
-    it.skip("configures high detail events correctly", () => { });
+    it.skip("configures high detail events correctly", () => {});
   });
 });
diff --git 
a/products/userale/packages/flagon-userale/test/spec/sendLogs.spec.ts 
b/products/userale/packages/flagon-userale/test/spec/sendLogs.spec.ts
index a2c944f..f7fc602 100644
--- a/products/userale/packages/flagon-userale/test/spec/sendLogs.spec.ts
+++ b/products/userale/packages/flagon-userale/test/spec/sendLogs.spec.ts
@@ -106,7 +106,7 @@ describe("sendLogs", () => {
 
   it("sends logs on page exit with fetch", () => {
     const fetchSpy = jest.spyOn(global, "fetch");
-    
+
     config.update({ on: true, url: "http://test.com"; });
     sendOnClose([], config);
     config.update({ on: true, url: "http://test.com"; });
@@ -118,10 +118,9 @@ describe("sendLogs", () => {
     fetchSpy.mockRestore();
   });
 
-
   it("does not send logs on page exit when config is off", () => {
     const fetchSpy = jest.spyOn(global, "fetch");
-    
+
     config.update({ on: false, url: "test" });
     sendOnClose([{ foo: "bar" }], config);
     global.window.dispatchEvent(new window.CustomEvent("pagehide"));
@@ -140,30 +139,29 @@ describe("sendLogs", () => {
       logCountThreshold: 1,
     });
     jest.useFakeTimers();
-  
+
     const authCallback = jest.fn().mockReturnValue("fakeAuthToken");
     registerAuthCallback(authCallback);
-  
+
     initSender(logs, config);
     logs.push({ foo: "bar" });
-  
+
     jest.advanceTimersByTime(config.transmitInterval);
-  
+
     expect(xhrMock.send).toHaveBeenCalledTimes(1);
-  
+
     // Filter only calls to setRequestHeader with 'Authorization'
     const calls = (xhrMock.setRequestHeader as jest.Mock).mock.calls;
     const authHeaderCall = calls.find(
-      ([header]) => header.toLowerCase() === "authorization"
+      ([header]) => header.toLowerCase() === "authorization",
     );
-    
+
     expect(authHeaderCall?.[0].toLowerCase()).toBe("authorization");
     expect(authHeaderCall?.[1]).toBe("fakeAuthToken");
-  
+
     jest.useRealTimers();
     done();
   });
-  
 
   it("sends logs with proper custom headers when using 
registerHeadersCallback", (done) => {
     const logs: Array<Logging.Log> = [];
diff --git a/products/userale/packages/flagon-userale/tsconfig.json 
b/products/userale/packages/flagon-userale/tsconfig.json
index 12d6a32..e60896e 100644
--- a/products/userale/packages/flagon-userale/tsconfig.json
+++ b/products/userale/packages/flagon-userale/tsconfig.json
@@ -1,54 +1,23 @@
 {
+    "extends": "../../tsconfig.base.json",
     "compilerOptions": {
-        "allowJs": false,
-        "allowSyntheticDefaultImports": true,
-        "allowUnreachableCode": false,
-        "allowUnusedLabels": false,
-        "baseUrl": ".",
-        "checkJs": false,
-        "declaration": true,
-        "declarationDir": "./build",
-        "esModuleInterop": true,
-        "forceConsistentCasingInFileNames": false,
-        "isolatedModules": true,
-        "jsx": "preserve",
-        "lib": [
-            "ES2021",
-            "WebWorker",
-            "dom",
-            "dom.iterable",
-            "esnext"
-        ],
-        "module": "esnext",
-        "moduleResolution": "bundler",
-        "noEmit": true,
-        "noFallthroughCasesInSwitch": true,
-        "noImplicitReturns": false,
-        "noUnusedLocals": true,
-        "noUnusedParameters": false,
-        "paths": {
-            "@/*": [
-                "./src/*"
-            ]
-        },
-        "pretty": true,
-        "resolveJsonModule": true,
-        "skipLibCheck": true,
-        "sourceMap": true,
-        "strict": true,
-        "target": "ES2021",
-        "typeRoots": [
-            "node_modules/@types/"
-        ],
+      "composite": true,
+      "declaration": true,
+      "declarationMap": true,
+      "declarationDir": "./build",
+      "module": "ESNext",
+      "moduleResolution": "node",
+      "noEmit": true,
+      "rootDir": "./src",
+      "baseUrl": ".",
+      "paths": {
+        "@/*": ["./src/*"]
+      }
     },
     "include": [
-        "src",
-        "test",
-        "src/types.d.ts"
+      "src/**/*.ts",
+      "src/types.d.ts"
     ],
-    "exclude": [
-        "node_modules",
-        "build",
-        "logs"
-    ],
-}
+    "exclude": ["node_modules", "build"]
+  }
+  
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/tsconfig.test.json 
b/products/userale/packages/flagon-userale/tsconfig.test.json
new file mode 100644
index 0000000..90efa52
--- /dev/null
+++ b/products/userale/packages/flagon-userale/tsconfig.test.json
@@ -0,0 +1,9 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "noEmit": true,
+    "types": ["jest"],
+    "allowJs": true
+  },
+  "include": ["src", "test", "**/*.test.ts", "**/*.spec.ts", 
"**/__tests__/**/*.ts"]
+}
\ No newline at end of file
diff --git a/products/userale/packages/flagon-userale/tsup.config.js 
b/products/userale/packages/flagon-userale/tsup.config.js
index a198654..7989b3b 100644
--- a/products/userale/packages/flagon-userale/tsup.config.js
+++ b/products/userale/packages/flagon-userale/tsup.config.js
@@ -8,7 +8,7 @@ export default defineConfig([
     format: ['esm', 'iife'],
     name: 'userale',
     target: 'es2021',
-    dts: true,
+    dts: false,
     sourcemap: true,
     clean: true,
     minify: false,
diff --git a/products/userale/test/spec/fixtures/extension.fixture.ts 
b/products/userale/test/spec/fixtures/extension.fixture.ts
index 97030b9..e18d2ad 100644
--- a/products/userale/test/spec/fixtures/extension.fixture.ts
+++ b/products/userale/test/spec/fixtures/extension.fixture.ts
@@ -16,6 +16,7 @@ export const test = base.extend<{
     );
     const context = await chromium.launchPersistentContext(os.tmpdir(), {
       channel: 'chromium',
+      headless: false,
       args: [
         `--disable-extensions-except=${pathToExtension}`,
         `--load-extension=${pathToExtension}`,
@@ -40,7 +41,6 @@ export const test = base.extend<{
         const listener = async (req: Request) => {
           const url = req.url();
           const method = req.method();
-          // console.log(req);
 
           if (!url.startsWith('http://localhost:8000') || method !== 'POST') 
return;
 
diff --git a/products/userale/tsconfig.base.json 
b/products/userale/tsconfig.base.json
new file mode 100644
index 0000000..851d2f9
--- /dev/null
+++ b/products/userale/tsconfig.base.json
@@ -0,0 +1,18 @@
+{
+    "compilerOptions": {
+      "target": "ES2021",
+      "module": "ESNext",
+      "lib": ["DOM", "DOM.Iterable", "ESNext", "WebWorker"],
+      "strict": true,
+      "esModuleInterop": true,
+      "moduleResolution": "node",
+      "skipLibCheck": true,
+      "resolveJsonModule": true,
+      "allowSyntheticDefaultImports": true,
+      "forceConsistentCasingInFileNames": true,
+      "sourceMap": true,
+      "pretty": true,
+      "typeRoots": ["node_modules/@types"]
+    }
+  }
+  
\ No newline at end of file
diff --git a/products/userale/tsconfig.json b/products/userale/tsconfig.json
index 71bad78..94dcdcc 100644
--- a/products/userale/tsconfig.json
+++ b/products/userale/tsconfig.json
@@ -1,14 +1,18 @@
 {
-    "compilerOptions": {
-      "target": "ESNext",
-      "module": "CommonJS",
-      "lib": ["DOM", "ESNext"],
-      "strict": true,
-      "esModuleInterop": true,
-      "moduleResolution": "Node",
-      "types": ["node", "playwright"],
-      "skipLibCheck": true
-    },
-    "include": ["**/*.ts", "packages/flagon-userale/test/jest.config.js"]
-  }
-  
\ No newline at end of file
+  "references": [
+    { "path": "packages/flagon-userale" },
+    { "path": "packages/flagon-userale-ext" }
+  ],
+  "compilerOptions": {
+    "target": "ESNext",
+    "module": "ESNext",
+    "moduleResolution": "node",
+    "lib": ["DOM", "ESNext"],
+    "strict": true,
+    "esModuleInterop": true,
+    "skipLibCheck": true,
+    "types": ["node"],
+    "composite": false
+  },
+  "exclude": ["node_modules"]
+}

Reply via email to