MobNew.LiveViewPatcher (mob_new v0.3.5)

Copy Markdown View Source

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.jsMobHook 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.exMob.App child started in the supervision tree.

Summary

Functions

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

Generates the Erlang bootstrap for a LiveView project.

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

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

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

Generates the create_notes Ecto migration.

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

Generates mob.exs config content for a LiveView project.

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

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

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

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

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

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

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

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

Functions

about_live_content(module_name, app_name)

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

erlang_entry_content(module_name, app_name)

Generates the Erlang bootstrap for a LiveView project.

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

inject_deps(content, mob_dep, mob_dev_dep)

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(content)

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

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

inject_mob_hook(content)

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

Idempotent: returns unchanged content if MobHook is already present.

migration_content(app_name)

Generates the create_notes Ecto migration.

mob_bridge_element()

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

mob_exs_content(mob_exs_mob_dir, mob_exs_elixir_lib)

Generates mob.exs config content for a LiveView project.

mob_live_app_content(module_name, app_name, secret_key_base, signing_salt)

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(module_name)

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

note_content(module_name)

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

note_editor_live_content(module_name, app_name)

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

notes_content(module_name, app_name)

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

notes_list_live_content(module_name, app_name)

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

page_live_content(module_name, app_name)

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

repo_content(module_name, app_name)

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