Tutorial — your first session
Install, start a session, subscribe to events, read snapshot state, dispose.
Previous: Core concepts · Next: Visibility
Playground
Visibility explorer — switch tabs and observe event order.
Prerequisites: Node 20+, browser or SSR-aware bootstrap.
Step 1 — Install
bash
npm install @jayoncode/browser-lifecycleOutcome: Package available for import.
Step 2 — Create a session
ts
import { createBrowserLifecycle } from "@jayoncode/browser-lifecycle";
const lifecycle = createBrowserLifecycle({ autoStart: true });Outcome: Session in running phase with modules attached per configuration.
Step 3 — Subscribe to events
ts
lifecycle.on("page:visible", () => {
resumePolling();
});
lifecycle.on("page:hidden", () => {
pausePolling();
});Outcome: Handlers run on normalized visibility transitions. Unsubscribe via returned function.
Step 4 — Read snapshot
ts
const snapshot = lifecycle.getSnapshot();
console.log(snapshot.page.visibility); // "visible" | "hidden"Outcome: Readonly view of current session state without manual listener bookkeeping.
UI structure (framework shell)
Browser Lifecycle has no form markup — mount one shared session and dispose on unmount.
React JSX
tsx
import { useEffect, useMemo } from "react";
import { createBrowserLifecycle } from "@jayoncode/browser-lifecycle";
export function AppShell({ children }: { children: React.ReactNode }) {
const lifecycle = useMemo(() => createBrowserLifecycle({ autoStart: true }), []);
useEffect(() => {
const offVisible = lifecycle.on("page:visible", () => resumeWork());
const offHidden = lifecycle.on("page:hidden", () => pauseWork());
return () => {
offVisible();
offHidden();
void lifecycle.dispose();
};
}, [lifecycle]);
return <>{children}</>;
}Vanilla HTML + module script
html
<body>
<main id="app"><!-- your UI --></main>
<script type="module">
import { createBrowserLifecycle } from "@jayoncode/browser-lifecycle";
const lifecycle = createBrowserLifecycle({ autoStart: true });
lifecycle.on("page:hidden", () => console.log("tab hidden"));
window.addEventListener("pagehide", () => {
void lifecycle.dispose();
});
</script>
</body>Step 5 — Dispose
ts
await lifecycle.dispose();Outcome: Listeners removed; instance must not be reused.
Recap
| Step | API | Result |
|---|---|---|
| 1 | npm install | Dependency installed |
| 2 | createBrowserLifecycle() | Active session |
| 3 | on(event, handler) | Typed subscriptions |
| 4 | getSnapshot() | Current state |
| 5 | dispose() | Clean teardown |
Pitfalls
| Issue | Mitigation |
|---|---|
| Multiple sessions per tab | Single shared instance |
| Missing teardown | Call dispose() on unmount |
| SSR access | Guard typeof window !== "undefined" |
Continue
| Topic | Guide | Playground |
|---|---|---|
| Visibility module | Visibility | Visibility |
| Event patterns | Events | Events |
| Config & SSR | Core infrastructure | Configuration |
