-module(lustre@server_component). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -define(FILEPATH, "src/lustre/server_component.gleam"). -export([element/2, script/0, route/1, method/1, include/2, subject/1, pid/1, register_subject/1, deregister_subject/1, register_callback/1, deregister_callback/1, emit/2, select/1, runtime_message_decoder/0, client_message_to_json/1]). -export_type([transport_method/0]). -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( " Server components are an advanced feature that allows you to run components\n" " or full Lustre applications on the server. Updates are broadcast to a small\n" " (10kb!) client runtime that patches the DOM and events are sent back to the\n" " server component in real-time.\n" "\n" " ```text\n" " -- SERVER -----------------------------------------------------------------\n" "\n" " Msg Element(Msg)\n" " +--------+ v +----------------+ v +------+\n" " | | <-------------- | | <-------------- | |\n" " | update | | Lustre runtime | | view |\n" " | | --------------> | | --------------> | |\n" " +--------+ ^ +----------------+ ^ +------+\n" " #(model, Effect(msg)) | ^ Model\n" " | |\n" " | |\n" " DOM patches | | DOM events\n" " | |\n" " v |\n" " +-----------------------+\n" " | |\n" " | Your WebSocket server |\n" " | |\n" " +-----------------------+\n" " | ^\n" " | |\n" " DOM patches | | DOM events\n" " | |\n" " v |\n" " -- BROWSER ----------------------------------------------------------------\n" " | ^\n" " | |\n" " DOM patches | | DOM events\n" " | |\n" " v |\n" " +----------------+\n" " | |\n" " | Client runtime |\n" " | |\n" " +----------------+\n" " ```\n" "\n" " > **Note**: Lustre's server component runtime is separate from your application's\n" " > WebSocket server. You're free to bring your own stack, connect multiple\n" " > clients to the same Lustre instance, or keep the application alive even when\n" " > no clients are connected.\n" "\n" " Lustre server components run next to the rest of your backend code, your\n" " services, your database, etc. Real-time applications like chat services, games,\n" " or components that can benefit from direct access to your backend services\n" " like an admin dashboard or data table are excellent candidates for server\n" " components.\n" "\n" " ## Examples\n" "\n" " Server components are a new feature in Lustre and we're still working on the\n" " best ways to use them and show them off. Here are a few examples we've\n" " developed so far:\n" "\n" " - [Basic setup](https://github.com/lustre-labs/lustre/tree/main/examples/06-server-components/01-basic-setup)\n" "\n" " - [Custom attributes and events](https://github.com/lustre-labs/lustre/tree/main/examples/06-server-components/02-attributes-and-events)\n" "\n" " - [Decoding DOM events](https://github.com/lustre-labs/lustre/tree/main/examples/06-server-components/03-event-include)\n" "\n" " - [Connecting more than one client](https://github.com/lustre-labs/lustre/tree/main/examples/06-server-components/04-multiple-clients)\n" "\n" " ## Getting help\n" "\n" " If you're having trouble with Lustre or not sure what the right way to do\n" " something is, the best place to get help is the [Gleam Discord server](https://discord.gg/Fm8Pwmy).\n" " You could also open an issue on the [Lustre GitHub repository](https://github.com/lustre-labs/lustre/issues).\n" "\n" ). -type transport_method() :: web_socket | server_sent_events | polling. -file("src/lustre/server_component.gleam", 141). ?DOC( " Render the server component custom element. This element acts as the thin\n" " client runtime for a server component running remotely. There are a handful\n" " of attributes you should provide to configure the client runtime:\n" "\n" " - [`route`](#route) is the URL your server component should connect to. This\n" " **must** be provided before the client runtime will do anything. The route\n" " can be a relative URL, in which case it will be resolved against the current\n" " page URL.\n" "\n" " - [`method`](#method) is the transport method the client runtime should use.\n" " This defaults to `WebSocket` enabling duplex communication between the client\n" " and server runtime. Other options include `ServerSentEvents` and `Polling`\n" " which are unidirectional transports.\n" "\n" " > **Note**: the server component runtime bundle must be included and sent to\n" " > the client for this to work correctly. You can do this by including the\n" " > JavaScript bundle found in Lustre's `priv/static` directory or by inlining\n" " > the script source directly with the [`script`](#script) element below.\n" ). -spec element( list(lustre@vdom@vattr:attribute(UMR)), list(lustre@vdom@vnode:element(UMR)) ) -> lustre@vdom@vnode:element(UMR). element(Attributes, Children) -> lustre@element:element( <<"lustre-server-component"/utf8>>, Attributes, Children ). -file("src/lustre/server_component.gleam", 153). ?DOC( " Inline the server component client runtime as a `