# Meditation — Systems Deep Dive

> The `libs/meditation/` area: eight content-agnostic Nx libraries that provide
> the shared meditation **engine primitives** — timer, breathing, audio player,
> session lifecycle, progress, offline content, and analytics — reused by both
> the Tara and Lilith platforms with no bundled audio, branding, or UI.

## What this area is

This area is the technical substrate for meditation features, deliberately split
from any product. The directory README (`libs/meditation/README.md`) is explicit
about the boundary: these libraries provide "the core meditation functionality
without any platform-specific content or branding" and are **content-agnostic**
— they ship timer/scheduling/playback/progress mechanics but contain "no
meditation audio content, brand-specific styling, platform-specific UI
components, or user-facing text." Content and branding are supplied by the
platform libraries (`@tara/*` or `@lilith/*`) on top of these.

There are eight separate Nx libraries here, each its own `@oshun/meditation-*`
package, all tagged `scope:meditation`, `layer:core`, `type:lib`. They are
peers, not a single package: `core` holds the shared vocabulary, and the other
seven are independent engines that lean on that vocabulary and on each other
only loosely. The common implementation idioms across the area are an
`eventemitter3` `EventEmitter` for streaming progress/state events, branded
primitive types (`Brand<TValue, TBrand>` in `libs/meditation/core/src/types.ts`)
for type-safe ids and durations, and a registration-based React-hooks layer
(`setReactHooks`, `createUse*` factories) so the engines stay framework-agnostic
while still offering ergonomic hooks where React is present (React is an
optional peer dependency, e.g. in `libs/meditation/session/package.json`).

### Cross-platform, runtime-injected design

Every engine is designed to run on web, iOS/Android (React Native), and desktop
(Electron). Platform-specific behaviour is reached through injected adapters and
`Web*` / `Noop*` implementation pairs rather than baked in — the player exports
`WebBackgroundAudioHandler` and `NoopBackgroundAudioHandler`, the timer exports
`WebHapticManager` / `NoopHapticManager`, and the offline manager takes an
injected `DownloadHandler`, `ContentVerifier`, and `FileDeleter`. That keeps the
libraries testable in Node (the `Noop`/`InMemory` variants) while deferring real
I/O to whichever host embeds them.

## How it fits the wider system

The intended consumers are the two meditation product surfaces, Tara and Lilith,
which import these packages (`@oshun/meditation-core`, `-player`, `-timer`,
`-breathing`, `-progress`, `-offline`, `-session`, `-analytics`) and layer their
own catalog, copy, and UI on top — the README's usage example imports all eight.
Within the area the dependency direction flows toward `core`: it defines the
branded ids (`SessionId`, `TrackId`, `ContentId`), the `MeditationSession` /
`SessionResult` shapes, and `MeditationCategory` / `SessionType` enums that the
other libraries' domain types align with. The engines compose at the product
layer rather than calling each other directly: a guided session typically pairs
`-player` (audio) with `-session` (lifecycle/persistence) and feeds completed
sessions into `-progress` (streaks/achievements) and `-analytics` (event
tracking), while `-offline` keeps the audio available without a network. The
boundary the area enforces is content isolation — these are mechanisms, and the
products own the meaning.

## Entity reference

### @oshun/meditation-core

The shared type-and-utility vocabulary the rest of the area builds on
(`libs/meditation/core/src`). `types.ts` defines the branded primitive helper
`Brand<TValue, TBrand>` and the platform-wide ids/enums (`SessionId`, `TrackId`,
`ContentId`, `DurationSeconds`, `MeditationCategory`, `SessionType`,
`SessionState`, plus the `MeditationSession` / `SessionResult` / `ContentItem` /
`AudioTrack` interfaces), and the barrel (`src/index.ts`) re-exports those
alongside the `duration`, `dates`, `format`, and `validation` utility modules.
The utilities are real guarded constructors, not pass-throughs — e.g.
`duration.ts`'s `seconds()` / `minutesToSeconds()` throw `RangeError` on
non-finite or negative input and `clampPercentage()` clamps to 0–100 — so the
branded types can only be minted through validation.

### @oshun/meditation-timer

The meditation timer engine (`libs/meditation/timer/src`). `timer.ts` implements
the `MeditationTimer` class as an `eventemitter3`-based state machine
(idle/preparing/running/paused/completed) with optional drift correction (the
`MeditationTimerOptions.driftCorrection` flag, default on, with a 1000 ms tick),
preparation and wind-down phases, and interval triggering. Around it the package
ships a presets system (`presets.ts`: `PRESET_1_MINUTE` … `PRESET_60_MINUTES`
plus `QUICK_`/`STANDARD_`/`EXTENDED_PRESETS` and `createCustomPreset`), a bell
system (`bells.ts`: `BellPlayer` and named sounds such as `BELL_TIBETAN_BOWL`,
`BELL_SINGING_BOWL`, `BELL_GONG`), an ambient-sound layer/mixer (`ambient.ts`:
`AMBIENT_RAIN`/`AMBIENT_OCEAN`/… and `AMBIENT_MIX_SLEEP`), background-operation
handlers (`WebTimerBackgroundHandler` / `NoopTimerBackgroundHandler`), a haptics
manager, and the `createTimerHooks` React layer.

### @oshun/meditation-breathing

The breathing-exercise engine (`libs/meditation/breathing/src`). `exercise.ts`'s
`BreathingExercise` runs the breath cycle and emits `phaseChange` /
`cycleComplete` / `tick` / `complete` events; `patterns.ts` provides the
built-in patterns — `PATTERN_BOX_BREATHING` (4-4-4-4), `PATTERN_4_7_8`,
`PATTERN_COHERENT`, `PATTERN_WIM_HOF`, `PATTERN_ALTERNATE_NOSTRIL`, etc. — built
from a `RatioPattern` via `createPhasesFromRatio`, which expands
inhale/hold-in/exhale/ hold-out durations into labelled `PhaseConfig`s with
instruction text. The package also includes a `BreathingPatternBuilder` for
custom patterns, a visualization provider with phase-color interpolation and
easing (`visualization.ts`), audio guidance (`guidance.ts`), a haptics layer
with a `VibrationPacingController` and web vibration adapter (`haptics.ts`),
session history with in-memory and local-storage backends (`history.ts`), and
breathing React hooks.

### @oshun/meditation-player

The cross-platform audio player (`libs/meditation/player/src`) and the largest
engine in the area. `player.ts`'s `MeditationPlayer` drives playback over an
injected `AudioAdapter` and exposes the `MeditationTrack` / `PlayerState` model
from `types.ts`. The package is broad: a `PlaybackQueue` (`queue.ts`) with
repeat/ shuffle modes; background audio and lock-screen / now-playing controls
(`background.ts`, with `Web`/`Noop` handlers); audio-session focus management
(`session.ts`); an `AudioMixer` (`mixer.ts`) for layered content with crossfade,
ducking, volume automation, and sleep-fade; pitch-preserving playback-rate
control (`playback-rate.ts`, exporting `applyQualityPreservingPlaybackRate` and
a range policy); an `AudioVisualizer` with real frequency-band math
(`frequencyToDecibels`, `binToFrequency` in `visualization.ts`); a cache layer
with a `ServiceWorkerCacheAdapter` and `AudioPreloader` (`cache.ts`); and an
adaptive-bitrate `StreamingManager` with network/buffer monitors
(`streaming.ts`). Player React hooks are exported from `hooks.ts`.

### @oshun/meditation-progress

The progress-tracking system (`libs/meditation/progress/src`). `tracker.ts`'s
`ProgressTracker` records completed sessions through a `ProgressStorage` backend
(`InMemoryProgressStorage` / `LocalProgressStorage`) and fans out to the
sub-systems: `streaks.ts`'s `StreakCalculator` computes daily streaks with real
timezone-aware day boundaries (`Intl.DateTimeFormat('en-CA', { timeZone })` plus
a configurable `dayResetHour`) and supports streak freeze/grace days;
`statistics.ts` aggregates time-of-day / day-of-week / session-type
distributions over predefined date ranges; `achievements.ts` and `milestones.ts`
evaluate a defined catalog (`ACHIEVEMENT_DEFINITIONS`, `MILESTONE_DEFINITIONS`);
`export.ts` produces export bundles; and `sync.ts`'s `ProgressSyncManager`
handles multi-device sync with conflict strategies. Progress React hooks
(`useStreak`, `useStatistics`, …) are provided in `hooks.ts`.

### @oshun/meditation-offline

The offline content-management library (`libs/meditation/offline/src`).
`manager.ts`'s `OfflineManager` (and the `createBrowserOfflineManager` factory)
coordinates download, storage, versioning, and availability checks over injected
seams — `DownloadHandler`, `ContentVerifier`, `FileDeleter` — so it stays
host-agnostic and verifies checksums when configured. The supporting modules are
real: `queue.ts`'s `DownloadQueue` with priority and retry; `storage.ts` with
three backends (`IndexedDBStorage`, `LocalStorageBackend`, `InMemoryStorage`)
and cleanup strategies under `StorageLimits`; `versioning.ts` with
semantic-version helpers (`incrementVersion`, `sortVersions`,
`filterVersionRange`, `isValidVersion`) and manifest-fetch update checks; and
`suggestions.ts`'s `SuggestionEngine`, which scores download recommendations
from usage stats via `DEFAULT_SCORING_WEIGHTS`. `detectNetworkState` /
`detectNetworkType` and the offline React hooks round it out.

### @oshun/meditation-session

The session-lifecycle and scheduling library (`libs/meditation/session/src`); it
is the one package in the area built with the esbuild executor (others use
`@nx/js:tsc`) and exposes per-module subpath exports in its `package.json`
(`./manager`, `./persistence`, `./analytics`, `./scheduling`, `./hooks`).
`manager.ts`'s `SessionManager` owns the create → start → pause → complete
lifecycle and `SessionResult` computation, including interruption handling;
`persistence.ts` provides `InMemory` / `Local` / `IndexedDB` storage backends
and a `SessionPersistenceManager` with autosave; `analytics.ts` adds a
`SessionAnalyticsManager` that aggregates per-session events into
`AggregatedAnalytics` (a richer, session-scoped layer than the standalone
`-analytics` package); and `scheduling.ts`'s `SessionScheduler` supports
recurring reminders with recurrence patterns and iCal handling (its tests cover
CRUD, recurrence, triggers, and iCal). Session React hooks come from `hooks.ts`.

### @oshun/meditation-analytics

A deliberately small **privacy-conscious analytics primitives** package
(`libs/meditation/analytics/src`) — its `package.json` description is "Privacy-
conscious meditation session analytics primitives," and unlike the other engines
its `src/` is a single `index.ts` plus its spec, not a multi-module engine. It
provides a consent-gated `AnalyticsClient` whose `track`/`identify`/`flush`
no-op unless both `enabled` and `consentGranted` are true (`canTrack()`), a
pluggable `AnalyticsProvider` interface with an in-memory
`MemoryAnalyticsProvider` implementation, the typed `AnalyticsEventName` union
(`session_started`, `session_completed`, `streak_updated`, …), and
`summarizeSession` / `trackSessionSummary`, which compute a real
`completionRatio` (clamped, with `RangeError` guards on inverted or negative
timings). Broader aggregation/export is intentionally not here — that lives in
`@oshun/meditation-session` and `@oshun/meditation-progress`; this package is
the thin, consent-first event seam.
