fullstory-browser-sdk
fullstory-browser-sdk copied to clipboard
Provide a way to defer execution of certain API functions until FullStory is bootstrapped
Use a promise-based contract to let integrators know when FullStory is fully bootstrapped:
FullStory.isReady().then(() => {});
or
await FullStory.isReady();
// do more things
OR
use a callback interface for functions that need to wait until FullStory is bootstrapped to become operational: asyncGetCurrentSessionURL(callback, now?)
Thoughts on implementation:
isReady() with a promise
let alreadyReady = () => {};
// test to see if window['_fs_ready'] has already been set in the <head> of the document
if (typeof window._fs_ready === 'function') {
alreadyReady = window._fs_ready;
}
let readyCalled = false;
window._fs_ready = () => {
readyCalled = true;
alreadyReady();
};
export const isReady = new Promise((resolve, reject) => {
if (readyCalled) return resolve();
let iteration = 0;
const id = setInterval(() => {
if (readyCalled) {
clearInterval(id);
return resolve();
}
iteration++;
if (iteration > 10) {
clearInterval(id);
return reject('timeout');
}
}, 500);
});
- Using the Promise API will likely require a polyfill (which can be inserted via
@babel/preset-env
configuration).
async functions with a callback
There's no general isReady()
function, rather individual functions that need to wait for FullStory to bootstrap before they become operational have an async{function name}
version.
let alreadyReady = () => {};
// test to see if window['_fs_ready'] has already been set in the <head> of the document
if (typeof window._fs_ready === 'function') {
alreadyReady = window._fs_ready;
}
let readyCalled = false;
window._fs_ready = () => {
readyCalled = true;
alreadyReady();
};
const waitReady = (cb) => {
if (readyCalled) return cb();
let iteration = 0;
const id = setInterval(() => {
if (readyCalled) {
clearInterval(id);
return cb();
}
iteration++;
if (iteration > 10) {
clearInterval(id);
throw new Error('timeout');
}, 500);
}
const export asyncGetCurrentSessionURL(callback, now) {
const cb = () => {callback(getCurrentSessionURL(now))};
waitReady(cb);
}
- Both
isReady
andasync{function name}
assume that FullStory is initialized with theinit
function found in this package and not via placing the snippet tag in the<head>
of the document - 500 milliseconds could likely be too long of an interval; some analysis is required to find an interval value that doesn't introduce undue latency when retrieving session replay urls while waiting for FullStory to bootstrap
Question: is there a use case where a client of the FullStory browser API cares whether FS is ready other than waiting to get a session replay url (or session replay id)?
@bddean would love to know your thoughts.
@patrick-fs Sorry, I kept forgetting to reply to this message. No, those are the only two cases, though I can imagine we might want to add more in the future.
Relatedly, here's a PR that adds a callback-based variant to the snippet itself (can't use promises because browser support): https://github.com/cowpaths/mn/pull/19589