Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.0+2026.02.03T15.21.57.253Z.1310c89e.berickson.20260130.execution.dag.single.value
0.1.0+2026.02.05T21.57.29.413Z.5f75e49b.berickson.20260205.add.url.to.lockfields
10 changes: 5 additions & 5 deletions modules/lo_event/lo_event/lo_event.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as Queue from './queue.js';
import * as disabler from './disabler.js';
import * as debug from './debugLog.js';
import * as util from './util.js';
import { initializeUrlLockFields } from './urlLockFields.js';

export const QueueType = Queue.QueueType;

Expand All @@ -23,7 +24,6 @@ const INIT_STATES = {
let initialized = INIT_STATES.NOT_STARTED; // Current FSM state
let currentState = new Promise((resolve, reject) => { resolve(); }); // promise pipeline to ensure we handle all initialization


let loggersEnabled = []; // A list of all loggers which should receive events.
let queue;

Expand Down Expand Up @@ -59,7 +59,7 @@ async function initializeLoggers () {
* When initializing `lo_event`, clients can set which metadata items
* they wish to include.
*/
export async function compileMetadata(metadataTasks) {
export async function compileMetadata (metadataTasks) {
const taskPromises = metadataTasks.map(async task => {
try {
const result = await Promise.resolve(task.func());
Expand All @@ -75,7 +75,6 @@ export async function compileMetadata(metadataTasks) {
return results.filter(Boolean);
}


/**
* Set specific key/value pairs using the `lock_fields`
* event. We use this to set specific fields that we want
Expand Down Expand Up @@ -145,10 +144,11 @@ export function init (
.then(initializeLoggers)
.then(() => setFieldSet([{ source, version }]))
.then(() => compileMetadata(metadata));
if(sendBrowserInfo) {
initializeUrlLockFields(setFieldSet);
if (sendBrowserInfo) {
// In the future, some or all of this might be sent on every
// reconnect
logEvent("BROWSER_INFO", getBrowserInfo());
logEvent('BROWSER_INFO', getBrowserInfo());
}
}

Expand Down
115 changes: 115 additions & 0 deletions modules/lo_event/lo_event/urlLockFields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
let urlListenerInitialized = false;
let lastUrl = null;

function parseUrlFields (url, baseUrl) {
if (!url) {
return null;
}

try {
const parsed = new URL(url, baseUrl);
return {
url: parsed.href,
url_path: parsed.pathname
};
} catch (error) {
return null;
}
}

function updateUrlLockFields (setFieldSet, url) {
const baseUrl = (typeof window !== 'undefined' && window.location) ? window.location.href : undefined;
const fields = parseUrlFields(url, baseUrl);
if (!fields) {
return;
}

if (fields.url === lastUrl) {
return;
}

lastUrl = fields.url;
setFieldSet([fields]);
}

function initializeWindowListeners (setFieldSet) {
if (typeof window === 'undefined' || !window.location) {
return;
}

updateUrlLockFields(setFieldSet, window.location.href);

if (!window.addEventListener) {
return;
}

const handleLocationChange = () => updateUrlLockFields(setFieldSet, window.location.href);
window.addEventListener('popstate', handleLocationChange);
window.addEventListener('hashchange', handleLocationChange);

if (window.history) {
const originalPushState = window.history.pushState;
const originalReplaceState = window.history.replaceState;

window.history.pushState = function (...args) {
const result = originalPushState.apply(this, args);
handleLocationChange();
return result;
};

window.history.replaceState = function (...args) {
const result = originalReplaceState.apply(this, args);
handleLocationChange();
return result;
};
}
}

function initializeChromeListeners (setFieldSet) {
if (typeof chrome === 'undefined' || !chrome.tabs) {
return;
}

const handleTab = (tab) => {
if (tab && tab.url) {
updateUrlLockFields(setFieldSet, tab.url);
}
};

if (chrome.tabs.onUpdated && chrome.tabs.onUpdated.addListener) {
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo && changeInfo.url) {
updateUrlLockFields(setFieldSet, changeInfo.url);
return;
}
handleTab(tab);
});
}

if (chrome.tabs.onActivated && chrome.tabs.onActivated.addListener) {
chrome.tabs.onActivated.addListener((activeInfo) => {
if (!chrome.tabs.query) {
return;
}
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
handleTab(tabs && tabs[0]);
});
});
}

if (chrome.tabs.query) {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
handleTab(tabs && tabs[0]);
});
}
}

export function initializeUrlLockFields (setFieldSet) {
if (urlListenerInitialized) {
return;
}
urlListenerInitialized = true;

initializeWindowListeners(setFieldSet);
initializeChromeListeners(setFieldSet);
}