# `MobNew.LiveViewPatcher`
[🔗](https://github.com/genericjam/mob_new/blob/master/lib/mob_new/live_view_patcher.ex#L1)

Pure helpers for applying the Mob LiveView bridge patches to a freshly
generated Phoenix project.

These are duplicated from `MobDev.Enable` (which lives in mob_dev, a separate
package) to keep mob_new self-contained as a Mix archive with no runtime deps
on mob_dev.

## What gets patched

1. `assets/js/app.js` — `MobHook` definition inserted after the last import,
   and `MobHook` registered in the `LiveSocket` `hooks:` option.
2. `lib/<app>_web/components/layouts/root.html.heex` — hidden
   `<div id="mob-bridge" phx-hook="MobHook">` inserted after `<body>`.
3. `lib/<app>/mob_screen.ex` — generated (the `Mob.Screen` that opens the WebView).
4. `mob.exs` — placeholder `# config :mob, liveview_port: 4200` added (runtime
   default hashes per app to avoid collisions across multiple installed apps).
5. `mix.exs` — mob / mob_dev deps injected into the `deps/0` function.
6. `lib/<app>/application.ex` — `Mob.App` child started in the supervision tree.

# `about_live_content`

Generates `lib/<app>_web/live/about_live.ex`.

# `erlang_entry_content`

Generates the Erlang bootstrap for a LiveView project.

Calls `ModuleName.MobApp.start()` instead of `ModuleName.App.start()`.

# `inject_deps`

Injects mob / mob_dev dependencies into the `deps/0` function in `mix.exs` content.

`mob_dep` and `mob_dev_dep` are dependency tuple strings (already formatted —
e.g. `~s({:mob, "~> 0.5"})` or `~s({:mob, path: "/path"})`). They are parsed
back to AST and inserted at the end of the user's deps list.

Idempotent: no-op if `:mob` is already declared in the user's deps list,
regardless of indentation or trailing-comma shape.

## Implementation note

Phase 5 iter 1 replaced the regex-on-Elixir-source approach with Sourceror
AST manipulation. The old version matched `defp deps do\s*\[` and inserted
the dep tuples right after the opening bracket — fragile when phx.new's
generated mix.exs varied (different Phoenix versions, different formatter
configs). The AST walk is robust against all of these.

# `inject_mob_bridge_element`

Injects the hidden bridge `<div>` immediately after the opening `<body>` tag.

Idempotent: returns unchanged content if mob-bridge is already present.

# `inject_mob_hook`

Injects the MobHook definition and registration into the given `app.js` content.

Idempotent: returns unchanged content if MobHook is already present.

# `migration_content`

Generates the create_notes Ecto migration.

# `mob_bridge_element`

Returns the hidden bridge element string (for test assertions).

# `mob_exs_content`

Generates mob.exs config content for a LiveView project.

# `mob_live_app_content`

Generates the `mob_app.ex` entry point for a LiveView project.

This module is called from the Erlang bootstrap (`src/app_name.erl`) instead
of a native `Mob.App` module. It starts the Phoenix OTP application (which
boots the endpoint) and then starts `MobScreen` to open the WebView.

Unlike native Mob apps, this does NOT `use Mob.App` — Phoenix owns the
supervision tree. Mob is wired in at the BEAM entry level only.

`secret_key_base` and `signing_salt` are embedded directly because Mix config
files (`config/*.exs`) are not loaded on-device — `Application.put_env/3` is
the only way to configure the endpoint before `ensure_all_started/1` runs.
The on-device port defaults to a per-app hash (4200..4999) — see
`default_liveview_port/0` and issues.md #4 for the collision rationale.

# `mob_screen_content`

Generates the MobScreen source file content for the given module name.

# `note_content`

Generates `lib/<app>/note.ex` — the Note Ecto schema.

# `note_editor_live_content`

Generates `lib/<app>_web/live/note_editor_live.ex`.

# `notes_content`

Generates `lib/<app>/notes.ex` — the Notes context with seed data.

# `notes_list_live_content`

Generates `lib/<app>_web/live/notes_list_live.ex`.

# `page_live_content`

Generates `lib/<app>_web/live/page_live.ex` — a minimal starter LiveView
that replaces the default PageController route.

# `repo_content`

Generates `lib/<app>/repo.ex` — Ecto.Repo backed by SQLite3.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
