Where this code is running: a plain browser tab, FiveM's CEF, or nowhere with a DOM.
Three answers, not two, and headless is the one that earns this its own function
(MICA-177). isBrowser() below used to be !window.invokeNative with no guard, so
where there is no window at all it threw ReferenceError instead of answering. Both
cheap guards are wrong, and that is why the third state exists rather than a default:
Answer true with no window, and every module-scope if (isBrowser()) that then
writes a dev helper onto window (shell/state/charge.ts) throws one line later.
Answer false with no window and say nothing, and every !isBrowser() branch takes
the CEF path under a node test, silently. A test that meant to exercise the browser
path exercises the CEF path instead and stays green, which is worse than the crash.
So the predicate keeps its published boolean and its published answer for the two real
runtimes, and a caller that needs to know the third can ask for it by name. The same
shape as detectFramework's unknown in server/lib/FrameworkBridge.ts: a state
nothing can act on safely without knowing is a first-class answer, never folded into
whichever default happens to be nearest.
What headless actually is: a Vitest file in the node environment, or any module graph
loaded outside a page. Never a phone. CEF and a browser tab both have a window.
Where this code is running: a plain browser tab, FiveM's CEF, or nowhere with a DOM.
Three answers, not two, and
headlessis the one that earns this its own function (MICA-177).isBrowser()below used to be!window.invokeNativewith no guard, so where there is nowindowat all it threwReferenceErrorinstead of answering. Both cheap guards are wrong, and that is why the third state exists rather than a default:truewith nowindow, and every module-scopeif (isBrowser())that then writes a dev helper ontowindow(shell/state/charge.ts) throws one line later.falsewith nowindowand say nothing, and every!isBrowser()branch takes the CEF path under a node test, silently. A test that meant to exercise the browser path exercises the CEF path instead and stays green, which is worse than the crash.So the predicate keeps its published boolean and its published answer for the two real runtimes, and a caller that needs to know the third can ask for it by name. The same shape as
detectFramework'sunknowninserver/lib/FrameworkBridge.ts: a state nothing can act on safely without knowing is a first-class answer, never folded into whichever default happens to be nearest.What
headlessactually is: a Vitest file in the node environment, or any module graph loaded outside a page. Never a phone. CEF and a browser tab both have awindow.