-module(agnostic@platform). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/agnostic/platform.gleam"). -export([headless/0, new/22, mount/1, is_headless/1, is_browser/0]). -export_type([platform_error/0, phase/0, platform/6]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " This module contains the platform abstraction used by Lustre's reconciler.\n" " A platform configuration provides the low-level mutation methods needed to\n" " create, modify, and remove nodes in a render target.\n" "\n" ). -type platform_error() :: not_a_browser | {element_not_found, binary()} | not_mountable. -type phase() :: {phase, binary(), fun((fun(() -> nil)) -> nil)}. -opaque platform(ILA, ILB, ILC, ILD, ILE, ILF) :: headless | {platform, ILB, fun((ILB) -> {ILA, agnostic@vdom@vnode:element(ILE)}), fun((binary(), binary()) -> ILA), fun((binary()) -> ILA), fun(() -> ILA), fun((binary()) -> ILA), fun((ILA, ILA, {ok, ILA} | {error, nil}) -> nil), fun((ILA, ILA, {ok, ILA} | {error, nil}) -> nil), fun((ILA, ILA) -> nil), fun((ILA) -> {ok, ILA} | {error, nil}), fun((ILA, binary()) -> {ok, binary()} | {error, nil}), fun((ILA, binary(), binary()) -> nil), fun((ILA, binary()) -> nil), fun((ILA, binary(), ILC) -> nil), fun((ILA, binary()) -> nil), fun((ILA, ILF) -> nil), fun((ILF) -> ILA), fun((ILA, binary(), fun((ILD) -> nil), boolean()) -> nil), fun((ILA, binary(), fun((ILD) -> nil)) -> nil), fun((fun(() -> nil)) -> fun(() -> nil)), fun(() -> nil), list(phase())}. -file("src/agnostic/platform.gleam", 96). ?DOC( " Returns a headless [`Platform`](#Platform) for server components. Server\n" " components don't render to a DOM target — they send patches over the network\n" " to connected clients instead.\n" "\n" " Headless platforms declare no deferred phases: effects deferred to a\n" " platform phase (such as `dom.before_paint` or `dom.after_paint`) are\n" " dropped and never run.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " import agnostic/platform\n" " import agnostic/platform/dom\n" "\n" " let p = platform.headless()\n" " ```\n" ). -spec headless() -> platform(any(), any(), any(), any(), any(), any()). headless() -> headless. -file("src/agnostic/platform.gleam", 118). ?DOC( " Construct a custom [`Platform`](#Platform) with user-provided mutation\n" " methods. This is useful for rendering to non-DOM targets.\n" "\n" " Non-DOM targets can no-op `create_comment`, `create_fragment`,\n" " `set_raw_content`, `create_raw_node`, `add_event_listener`, and\n" " `remove_event_listener` and provide minimal implementations for the rest.\n" "\n" " `phases` declares the platform's deferred effect [`Phase`](#Phase)s in\n" " drain order. Pass an empty list for no deferred phases — deferred effects\n" " are then dropped. To run effects constructed by another platform module's\n" " typed constructors, declare a phase whose name matches that platform's\n" " public phase-name constant (for example\n" " [`dom.before_paint_phase`](./platform/dom.html#before_paint_phase)).\n" "\n" " > **Note**: `schedule_render` and every `Phase`'s `schedule` function must\n" " > defer — they must never invoke their callback synchronously. The\n" " > runtime's render bookkeeping assumes control returns to it first.\n" ). -spec new( ILS, fun((ILS) -> {ILT, agnostic@vdom@vnode:element(ILU)}), fun((binary(), binary()) -> ILT), fun((binary()) -> ILT), fun(() -> ILT), fun((binary()) -> ILT), fun((ILT, ILT, {ok, ILT} | {error, nil}) -> nil), fun((ILT, ILT, {ok, ILT} | {error, nil}) -> nil), fun((ILT, ILT) -> nil), fun((ILT) -> {ok, ILT} | {error, nil}), fun((ILT, binary()) -> {ok, binary()} | {error, nil}), fun((ILT, binary(), binary()) -> nil), fun((ILT, binary()) -> nil), fun((ILT, binary(), IME) -> nil), fun((ILT, binary()) -> nil), fun((ILT, IMF) -> nil), fun((IMF) -> ILT), fun((ILT, binary(), fun((IMG) -> nil), boolean()) -> nil), fun((ILT, binary(), fun((IMG) -> nil)) -> nil), fun((fun(() -> nil)) -> fun(() -> nil)), fun(() -> nil), list(phase()) ) -> platform(ILT, ILS, IME, IMG, ILU, IMF). new( Target, Mount, Create_element, Create_text_node, Create_fragment, Create_comment, Insert_before, Move_before, Remove_child, Next_sibling, Get_attribute, Set_attribute, Remove_attribute, Set_property, Set_text, Set_raw_content, Create_raw_node, Add_event_listener, Remove_event_listener, Schedule_render, After_render, Phases ) -> {platform, Target, Mount, Create_element, Create_text_node, Create_fragment, Create_comment, Insert_before, Move_before, Remove_child, Next_sibling, Get_attribute, Set_attribute, Remove_attribute, Set_property, Set_text, Set_raw_content, Create_raw_node, Add_event_listener, Remove_event_listener, Schedule_render, After_render, Phases}. -file("src/agnostic/platform.gleam", 182). ?DOC(false). -spec mount(platform(IMO, any(), any(), any(), IMS, any())) -> {ok, {IMO, agnostic@vdom@vnode:element(IMS)}} | {error, platform_error()}. mount(Platform) -> case Platform of headless -> {error, not_mountable}; {platform, T, M, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} -> {ok, M(T)} end. -file("src/agnostic/platform.gleam", 194). ?DOC(false). -spec is_headless(platform(any(), any(), any(), any(), any(), any())) -> boolean(). is_headless(Platform) -> case Platform of headless -> true; {platform, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} -> false end. -file("src/agnostic/platform.gleam", 212). ?DOC( " Gleam's conditional compilation makes it possible to have different implementations\n" " of a function for different targets, but it's not possible to know what runtime\n" " you're targeting at compile-time.\n" "\n" " This is problematic if you're using server components with a JavaScript\n" " backend because you'll want to know whether you're currently running on your\n" " server or in the browser: this function tells you that!\n" ). -spec is_browser() -> boolean(). is_browser() -> false.