Read and follow reddiquette; no excessive self-promotion. Please refer to the Reddit 9:1 rule when considering posting self promoting materials.
i work on zenovay, and i've been cleaning up our browser tracker install.
the script itself loads async. the annoying edge case was app code calling track() before that script had replaced the global. i didn't want every integration to wait for a ready promise just to record an event.
the npm wrapper now puts a callable stub on window immediately:
const q = []
function stub(...args) {
q.push(args)
}
stub.q = q
window.zenovay = stub
then init() injects the real script with async and defer. the tracker copies the queued calls, installs the real dispatcher, and drains them in order during initialization.
i also made init() idempotent. if the script tag is already there, the wrapper doesn't inject another one. calls made during ssr are just no-ops.
the bit i'm still unsure about is reads. a command like track() can be queued, but getVisitorId() can't return a real value before the tracker exists. right now it returns null until the live function is ready.
would you keep commands queue-based and synchronous getters nullable, or expose a ready() promise and make reads explicitly async?
affiliation: i work on zenovay. no product link here, i'm mainly looking for feedback on the api shape.
Read and follow reddiquette; no excessive self-promotion. Please refer to the Reddit 9:1 rule when considering posting self promoting materials.