diff --git a/README.md b/README.md index 031258e..7c2ba04 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,10 @@ gleam run -m squall generate https://rickandmortyapi.com/graphql ## Examples -See the [example/](./example/) directory for a complete working example. +See the [examples/](./examples/) directory for complete working examples: + +- **[01-basic](./examples/01-basic/)** - Basic usage with Erlang/JavaScript targets +- **[02-lustre](./examples/02-lustre/)** - Frontend app using Lustre ## Roadmap diff --git a/example/README.md b/examples/01-basic/README.md similarity index 100% rename from example/README.md rename to examples/01-basic/README.md diff --git a/example/gleam.toml b/examples/01-basic/gleam.toml similarity index 93% rename from example/gleam.toml rename to examples/01-basic/gleam.toml index 594b198..3b1836c 100644 --- a/example/gleam.toml +++ b/examples/01-basic/gleam.toml @@ -5,7 +5,7 @@ version = "1.0.0" gleam_stdlib = ">= 0.34.0 and < 2.0.0" gleam_json = ">= 3.0.0 and < 4.0.0" gleam_http = ">= 4.3.0 and < 5.0.0" -squall = { path = "../" } +squall = { path = "../../" } # For Erlang target (default) gleam_httpc = ">= 5.0.0 and < 6.0.0" diff --git a/example/manifest.toml b/examples/01-basic/manifest.toml similarity index 69% rename from example/manifest.toml rename to examples/01-basic/manifest.toml index 88b74ed..8973077 100644 --- a/example/manifest.toml +++ b/examples/01-basic/manifest.toml @@ -6,16 +6,14 @@ packages = [ { name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" }, { name = "glam", version = "2.0.3", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glam", source = "hex", outer_checksum = "237C2CE218A2A0A5D46D625F8EF5B78F964BC91018B78D692B17E1AB84295229" }, { name = "gleam_erlang", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "1124AD3AA21143E5AF0FC5CF3D9529F6DB8CA03E43A55711B60B6B7B3874375C" }, - { name = "gleam_fetch", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_javascript", "gleam_stdlib"], otp_app = "gleam_fetch", source = "hex", outer_checksum = "2CBF9F2E1C71AEBBFB13A9D5720CD8DB4263EB02FE60C5A7A1C6E17B0151C20C" }, { name = "gleam_http", version = "4.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "82EA6A717C842456188C190AFB372665EA56CE13D8559BF3B1DD9E40F619EE0C" }, { name = "gleam_httpc", version = "5.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_http", "gleam_stdlib"], otp_app = "gleam_httpc", source = "hex", outer_checksum = "C545172618D07811494E97AAA4A0FB34DA6F6D0061FDC8041C2F8E3BE2B2E48F" }, - { name = "gleam_javascript", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "EF6C77A506F026C6FB37941889477CD5E4234FCD4337FF0E9384E297CB8F97EB" }, - { name = "gleam_json", version = "3.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "874FA3C3BB6E22DD2BB111966BD40B3759E9094E05257899A7C08F5DE77EC049" }, + { name = "gleam_json", version = "3.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "44FDAA8847BE8FC48CA7A1C089706BD54BADCC4C45B237A992EDDF9F2CDB2836" }, { name = "gleam_stdlib", version = "0.65.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "7C69C71D8C493AE11A5184828A77110EB05A7786EBF8B25B36A72F879C3EE107" }, { name = "gleeunit", version = "1.9.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "DA9553CE58B67924B3C631F96FE3370C49EB6D6DC6B384EC4862CC4AAA718F3C" }, { name = "simplifile", version = "2.3.1", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "957E0E5B75927659F1D2A1B7B75D7B9BA96FAA8D0C53EA71C4AD9CD0C6B848F6" }, - { name = "squall", version = "0.1.0", build_tools = ["gleam"], requirements = ["argv", "filepath", "glam", "gleam_fetch", "gleam_http", "gleam_httpc", "gleam_javascript", "gleam_json", "gleam_stdlib", "simplifile", "swell"], source = "local", path = ".." }, - { name = "swell", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "swell", source = "hex", outer_checksum = "7CCA8C61349396C5B59B3C0627185F5B30917044E0D61CB7E0E5CC75C1B4A8E9" }, + { name = "squall", version = "1.0.0", build_tools = ["gleam"], requirements = ["argv", "filepath", "glam", "gleam_http", "gleam_httpc", "gleam_json", "gleam_stdlib", "simplifile", "swell"], source = "local", path = "../.." }, + { name = "swell", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "swell", source = "hex", outer_checksum = "CA28A95AB9A01E51D1FCFC0FC4F7102C7F47D04B9711138248D08C2A9F1FE6A3" }, ] [requirements] @@ -24,4 +22,4 @@ gleam_httpc = { version = ">= 5.0.0 and < 6.0.0" } gleam_json = { version = ">= 3.0.0 and < 4.0.0" } gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" } gleeunit = { version = ">= 1.0.0 and < 2.0.0" } -squall = { path = "../" } +squall = { path = "../../" } diff --git a/example/src/example.gleam b/examples/01-basic/src/example.gleam similarity index 100% rename from example/src/example.gleam rename to examples/01-basic/src/example.gleam diff --git a/example/src/graphql/get_character.gleam b/examples/01-basic/src/graphql/get_character.gleam similarity index 100% rename from example/src/graphql/get_character.gleam rename to examples/01-basic/src/graphql/get_character.gleam diff --git a/example/src/graphql/get_character.gql b/examples/01-basic/src/graphql/get_character.gql similarity index 100% rename from example/src/graphql/get_character.gql rename to examples/01-basic/src/graphql/get_character.gql diff --git a/example/src/graphql/get_character_with_fragment.gleam b/examples/01-basic/src/graphql/get_character_with_fragment.gleam similarity index 100% rename from example/src/graphql/get_character_with_fragment.gleam rename to examples/01-basic/src/graphql/get_character_with_fragment.gleam diff --git a/example/src/graphql/get_character_with_fragment.gql b/examples/01-basic/src/graphql/get_character_with_fragment.gql similarity index 100% rename from example/src/graphql/get_character_with_fragment.gql rename to examples/01-basic/src/graphql/get_character_with_fragment.gql diff --git a/examples/02-lustre/README.md b/examples/02-lustre/README.md new file mode 100644 index 0000000..5e8b45c --- /dev/null +++ b/examples/02-lustre/README.md @@ -0,0 +1,5 @@ +# lustre example + +```sh +gleam run -m lustre/dev start # Run the project +``` diff --git a/examples/02-lustre/gleam.toml b/examples/02-lustre/gleam.toml new file mode 100644 index 0000000..1fde76c --- /dev/null +++ b/examples/02-lustre/gleam.toml @@ -0,0 +1,28 @@ +name = "lustre_example" +version = "1.0.0" +target = "javascript" + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. +# +# description = "" +# licences = ["Apache-2.0"] +# repository = { type = "github", user = "", repo = "" } +# links = [{ title = "Website", href = "" }] +# +# For a full reference of all the available options, you can have a look at +# https://gleam.run/writing-gleam/gleam-toml/. + +[dependencies] +gleam_stdlib = ">= 0.44.0 and < 2.0.0" +lustre = ">= 5.0.0 and < 6.0.0" +lustre_http = ">= 1.0.0 and < 2.0.0" +gleam_json = ">= 3.0.0 and < 4.0.0" +gleam_http = ">= 4.3.0 and < 5.0.0" +gleam_fetch = ">= 1.0.0 and < 2.0.0" +squall = { path = "../../" } +gleam_javascript = ">= 1.0.0 and < 2.0.0" + +[dev-dependencies] +gleeunit = ">= 1.0.0 and < 2.0.0" +lustre_dev_tools = ">= 2.2.2 and < 3.0.0" diff --git a/examples/02-lustre/index.html b/examples/02-lustre/index.html new file mode 100644 index 0000000..d09dca4 --- /dev/null +++ b/examples/02-lustre/index.html @@ -0,0 +1,15 @@ + + + + + + Rick and Morty Characters - Lustre + Squall + + +
+ + + diff --git a/examples/02-lustre/manifest.toml b/examples/02-lustre/manifest.toml new file mode 100644 index 0000000..8944e41 --- /dev/null +++ b/examples/02-lustre/manifest.toml @@ -0,0 +1,61 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" }, + { name = "booklet", version = "1.1.0", build_tools = ["gleam"], requirements = [], otp_app = "booklet", source = "hex", outer_checksum = "08E0FDB78DC4D8A5D3C80295B021505C7D2A2E7B6C6D5EAB7286C36F4A53C851" }, + { name = "directories", version = "1.2.0", build_tools = ["gleam"], requirements = ["envoy", "gleam_stdlib", "platform", "simplifile"], otp_app = "directories", source = "hex", outer_checksum = "D13090CFCDF6759B87217E8DDD73A75903A700148A82C1D33799F333E249BF9E" }, + { name = "envoy", version = "1.0.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "envoy", source = "hex", outer_checksum = "95FD059345AA982E89A0B6E2A3BF1CF43E17A7048DCD85B5B65D3B9E4E39D359" }, + { name = "exception", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "exception", source = "hex", outer_checksum = "329D269D5C2A314F7364BD2711372B6F2C58FA6F39981572E5CA68624D291F8C" }, + { name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" }, + { name = "glam", version = "2.0.3", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glam", source = "hex", outer_checksum = "237C2CE218A2A0A5D46D625F8EF5B78F964BC91018B78D692B17E1AB84295229" }, + { name = "gleam_community_ansi", version = "1.4.3", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_regexp", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "8A62AE9CC6EA65BEA630D95016D6C07E4F9973565FA3D0DE68DC4200D8E0DD27" }, + { name = "gleam_community_colour", version = "2.0.2", build_tools = ["gleam"], requirements = ["gleam_json", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "E34DD2C896AC3792151EDA939DA435FF3B69922F33415ED3C4406C932FBE9634" }, + { name = "gleam_crypto", version = "1.5.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_crypto", source = "hex", outer_checksum = "50774BAFFF1144E7872814C566C5D653D83A3EBF23ACC3156B757A1B6819086E" }, + { name = "gleam_erlang", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "1124AD3AA21143E5AF0FC5CF3D9529F6DB8CA03E43A55711B60B6B7B3874375C" }, + { name = "gleam_fetch", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_http", "gleam_javascript", "gleam_stdlib"], otp_app = "gleam_fetch", source = "hex", outer_checksum = "2CBF9F2E1C71AEBBFB13A9D5720CD8DB4263EB02FE60C5A7A1C6E17B0151C20C" }, + { name = "gleam_http", version = "4.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_http", source = "hex", outer_checksum = "82EA6A717C842456188C190AFB372665EA56CE13D8559BF3B1DD9E40F619EE0C" }, + { name = "gleam_httpc", version = "5.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_http", "gleam_stdlib"], otp_app = "gleam_httpc", source = "hex", outer_checksum = "C545172618D07811494E97AAA4A0FB34DA6F6D0061FDC8041C2F8E3BE2B2E48F" }, + { name = "gleam_javascript", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "EF6C77A506F026C6FB37941889477CD5E4234FCD4337FF0E9384E297CB8F97EB" }, + { name = "gleam_json", version = "3.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "44FDAA8847BE8FC48CA7A1C089706BD54BADCC4C45B237A992EDDF9F2CDB2836" }, + { name = "gleam_otp", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "BA6A294E295E428EC1562DC1C11EA7530DCB981E8359134BEABC8493B7B2258E" }, + { name = "gleam_regexp", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "9C215C6CA84A5B35BB934A9B61A9A306EC743153BE2B0425A0D032E477B062A9" }, + { name = "gleam_stdlib", version = "0.65.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "7C69C71D8C493AE11A5184828A77110EB05A7786EBF8B25B36A72F879C3EE107" }, + { name = "gleam_time", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_time", source = "hex", outer_checksum = "D560E672C7279C89908981E068DF07FD16D0C859DCA266F908B18F04DF0EB8E6" }, + { name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" }, + { name = "gleeunit", version = "1.9.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "DA9553CE58B67924B3C631F96FE3370C49EB6D6DC6B384EC4862CC4AAA718F3C" }, + { name = "glint", version = "1.2.1", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], otp_app = "glint", source = "hex", outer_checksum = "2214C7CEFDE457CEE62140C3D4899B964E05236DA74E4243DFADF4AF29C382BB" }, + { name = "glisten", version = "8.0.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib", "logging", "telemetry"], otp_app = "glisten", source = "hex", outer_checksum = "534BB27C71FB9E506345A767C0D76B17A9E9199934340C975DC003C710E3692D" }, + { name = "gramps", version = "6.0.0", build_tools = ["gleam"], requirements = ["gleam_crypto", "gleam_erlang", "gleam_http", "gleam_stdlib"], otp_app = "gramps", source = "hex", outer_checksum = "8B7195978FBFD30B43DF791A8A272041B81E45D245314D7A41FC57237AA882A0" }, + { name = "group_registry", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "group_registry", source = "hex", outer_checksum = "BC798A53D6F2406DB94E27CB45C57052CB56B32ACF7CC16EA20F6BAEC7E36B90" }, + { name = "houdini", version = "1.2.0", build_tools = ["gleam"], requirements = [], otp_app = "houdini", source = "hex", outer_checksum = "5DB1053F1AF828049C2B206D4403C18970ABEF5C18671CA3C2D2ED0DD64F6385" }, + { name = "hpack_erl", version = "0.3.0", build_tools = ["rebar3"], requirements = [], otp_app = "hpack", source = "hex", outer_checksum = "D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0" }, + { name = "justin", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "justin", source = "hex", outer_checksum = "7FA0C6DB78640C6DC5FBFD59BF3456009F3F8B485BF6825E97E1EB44E9A1E2CD" }, + { name = "logging", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "logging", source = "hex", outer_checksum = "1098FBF10B54B44C2C7FDF0B01C1253CAFACDACABEFB4B0D027803246753E06D" }, + { name = "lustre", version = "5.4.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_json", "gleam_otp", "gleam_stdlib", "houdini"], otp_app = "lustre", source = "hex", outer_checksum = "40E097BABCE65FB7C460C073078611F7F5802EB07E1A9BFB5C229F71B60F8E50" }, + { name = "lustre_dev_tools", version = "2.2.2", build_tools = ["gleam"], requirements = ["argv", "booklet", "filepath", "gleam_community_ansi", "gleam_crypto", "gleam_erlang", "gleam_http", "gleam_httpc", "gleam_json", "gleam_otp", "gleam_regexp", "gleam_stdlib", "glint", "group_registry", "justin", "lustre", "mist", "polly", "simplifile", "tom", "wisp"], otp_app = "lustre_dev_tools", source = "hex", outer_checksum = "C66A09B0B268B596F021971E4E4111E4B2B4A1DF5BDFE6C28A1E1FE4CA371F1A" }, + { name = "lustre_http", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_fetch", "gleam_http", "gleam_javascript", "gleam_json", "gleam_stdlib", "lustre"], otp_app = "lustre_http", source = "hex", outer_checksum = "FA293FECBC779074C18E3F74D6668D1F13841899283C87B8C358BB6572D25498" }, + { name = "marceau", version = "1.3.0", build_tools = ["gleam"], requirements = [], otp_app = "marceau", source = "hex", outer_checksum = "2D1C27504BEF45005F5DFB18591F8610FB4BFA91744878210BDC464412EC44E9" }, + { name = "mist", version = "5.0.3", build_tools = ["gleam"], requirements = ["exception", "gleam_erlang", "gleam_http", "gleam_otp", "gleam_stdlib", "gleam_yielder", "glisten", "gramps", "hpack_erl", "logging"], otp_app = "mist", source = "hex", outer_checksum = "7C4BE717A81305323C47C8A591E6B9BA4AC7F56354BF70B4D3DF08CC01192668" }, + { name = "platform", version = "1.0.0", build_tools = ["gleam"], requirements = [], otp_app = "platform", source = "hex", outer_checksum = "8339420A95AD89AAC0F82F4C3DB8DD401041742D6C3F46132A8739F6AEB75391" }, + { name = "polly", version = "2.1.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib", "simplifile"], otp_app = "polly", source = "hex", outer_checksum = "1BA4D0ACE9BCF52AEA6AD9DE020FD8220CCA399A379E50A1775FC5C1204FCF56" }, + { name = "simplifile", version = "2.3.1", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "957E0E5B75927659F1D2A1B7B75D7B9BA96FAA8D0C53EA71C4AD9CD0C6B848F6" }, + { name = "snag", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "snag", source = "hex", outer_checksum = "274F41D6C3ECF99F7686FDCE54183333E41D2C1CA5A3A673F9A8B2C7A4401077" }, + { name = "squall", version = "1.0.0", build_tools = ["gleam"], requirements = ["argv", "filepath", "glam", "gleam_http", "gleam_httpc", "gleam_json", "gleam_stdlib", "simplifile", "swell"], source = "local", path = "../.." }, + { name = "swell", version = "1.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "swell", source = "hex", outer_checksum = "CA28A95AB9A01E51D1FCFC0FC4F7102C7F47D04B9711138248D08C2A9F1FE6A3" }, + { name = "telemetry", version = "1.3.0", build_tools = ["rebar3"], requirements = [], otp_app = "telemetry", source = "hex", outer_checksum = "7015FC8919DBE63764F4B4B87A95B7C0996BD539E0D499BE6EC9D7F3875B79E6" }, + { name = "tom", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_time"], otp_app = "tom", source = "hex", outer_checksum = "74D0C5A3761F7A7D06994755D4D5AD854122EF8E9F9F76A3E7547606D8C77091" }, + { name = "wisp", version = "2.1.0", build_tools = ["gleam"], requirements = ["directories", "exception", "filepath", "gleam_crypto", "gleam_erlang", "gleam_http", "gleam_json", "gleam_stdlib", "houdini", "logging", "marceau", "mist", "simplifile"], otp_app = "wisp", source = "hex", outer_checksum = "362BDDD11BF48EB38CDE51A73BC7D1B89581B395CA998E3F23F11EC026151C54" }, +] + +[requirements] +gleam_fetch = { version = ">= 1.0.0 and < 2.0.0" } +gleam_http = { version = ">= 4.3.0 and < 5.0.0" } +gleam_javascript = { version = ">= 1.0.0 and < 2.0.0" } +gleam_json = { version = ">= 3.0.0 and < 4.0.0" } +gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" } +gleeunit = { version = ">= 1.0.0 and < 2.0.0" } +lustre = { version = ">= 5.0.0 and < 6.0.0" } +lustre_dev_tools = { version = ">= 2.2.2 and < 3.0.0" } +lustre_http = { version = ">= 1.0.0 and < 2.0.0" } +squall = { path = "../../" } diff --git a/examples/02-lustre/src/graphql/get_characters.gleam b/examples/02-lustre/src/graphql/get_characters.gleam new file mode 100644 index 0000000..eb53bef --- /dev/null +++ b/examples/02-lustre/src/graphql/get_characters.gleam @@ -0,0 +1,90 @@ +import gleam/dynamic/decode +import gleam/http/request.{type Request} +import gleam/json +import gleam/option.{type Option} +import squall + +pub type Characters { + Characters(results: Option(List(Character))) +} + +pub fn characters_decoder() -> decode.Decoder(Characters) { + use results <- decode.field( + "results", + decode.optional(decode.list(character_decoder())), + ) + decode.success(Characters(results: results)) +} + +pub type Character { + Character( + id: Option(String), + name: Option(String), + status: Option(String), + species: Option(String), + ) +} + +pub fn character_decoder() -> decode.Decoder(Character) { + use id <- decode.field("id", decode.optional(decode.string)) + use name <- decode.field("name", decode.optional(decode.string)) + use status <- decode.field("status", decode.optional(decode.string)) + use species <- decode.field("species", decode.optional(decode.string)) + decode.success(Character(id: id, name: name, status: status, species: species)) +} + +pub fn characters_to_json(input: Characters) -> json.Json { + json.object([ + #( + "results", + json.nullable(input.results, fn(list) { + json.array(from: list, of: character_to_json) + }), + ), + ]) +} + +pub fn character_to_json(input: Character) -> json.Json { + json.object([ + #("id", json.nullable(input.id, json.string)), + #("name", json.nullable(input.name, json.string)), + #("status", json.nullable(input.status, json.string)), + #("species", json.nullable(input.species, json.string)), + ]) +} + +pub type GetCharactersResponse { + GetCharactersResponse(characters: Option(Characters)) +} + +pub fn get_characters_response_decoder() -> decode.Decoder( + GetCharactersResponse, +) { + use characters <- decode.field( + "characters", + decode.optional(characters_decoder()), + ) + decode.success(GetCharactersResponse(characters: characters)) +} + +pub fn get_characters_response_to_json( + input: GetCharactersResponse, +) -> json.Json { + json.object([ + #("characters", json.nullable(input.characters, characters_to_json)), + ]) +} + +pub fn get_characters(client: squall.Client) -> Result(Request(String), String) { + squall.prepare_request( + client, + "query GetCharacters {\n characters {\n results {\n id\n name\n status\n species\n }\n }\n}\n", + json.object([]), + ) +} + +pub fn parse_get_characters_response( + body: String, +) -> Result(GetCharactersResponse, String) { + squall.parse_response(body, get_characters_response_decoder()) +} diff --git a/examples/02-lustre/src/graphql/get_characters.gql b/examples/02-lustre/src/graphql/get_characters.gql new file mode 100644 index 0000000..bf4dc26 --- /dev/null +++ b/examples/02-lustre/src/graphql/get_characters.gql @@ -0,0 +1,10 @@ +query GetCharacters { + characters { + results { + id + name + status + species + } + } +} diff --git a/examples/02-lustre/src/lustre_example.gleam b/examples/02-lustre/src/lustre_example.gleam new file mode 100644 index 0000000..764903a --- /dev/null +++ b/examples/02-lustre/src/lustre_example.gleam @@ -0,0 +1,139 @@ +import gleam/fetch +import gleam/javascript/promise +import gleam/list +import gleam/option.{None, Some} +import graphql/get_characters +import lustre +import lustre/attribute +import lustre/effect.{type Effect} +import lustre/element.{type Element} +import lustre/element/html +import squall + +pub fn main() { + let app = lustre.application(init, update, view) + let assert Ok(_) = lustre.start(app, "#app", Nil) +} + +// MODEL + +pub type Model { + Model(state: State) +} + +pub type State { + Loading + Loaded(characters: List(get_characters.Character)) + Failed(message: String) +} + +fn init(_flags) -> #(Model, Effect(Msg)) { + #(Model(Loading), fetch_characters()) +} + +// UPDATE + +pub type Msg { + HandleCharacters(Result(get_characters.GetCharactersResponse, String)) +} + +fn update(_model: Model, msg: Msg) -> #(Model, Effect(Msg)) { + case msg { + HandleCharacters(Ok(response)) -> { + let characters = case response.characters { + Some(chars) -> + case chars.results { + Some(results) -> results + None -> [] + } + None -> [] + } + #(Model(Loaded(characters)), effect.none()) + } + HandleCharacters(Error(err)) -> #(Model(Failed(err)), effect.none()) + } +} + +// VIEW + +fn view(model: Model) -> Element(Msg) { + html.div([], [ + html.h1([], [html.text("Rick and Morty Characters")]), + case model.state { + Loading -> html.p([], [html.text("Loading characters...")]) + Failed(message) -> + html.div([], [ + html.p([attribute.style("color", "red")], [ + html.text("Error: " <> message), + ]), + ]) + Loaded(characters) -> render_characters(characters) + }, + ]) +} + +fn render_characters(characters: List(get_characters.Character)) -> Element(Msg) { + html.div([], [ + html.ul( + [], + characters + |> list.map(fn(character) { + html.li([], [ + html.div([], [ + html.strong([], [ + html.text(option.unwrap(character.name, "Unknown")), + ]), + html.text(" - "), + html.text( + "Status: " <> option.unwrap(character.status, "Unknown"), + ), + html.text(", "), + html.text( + "Species: " <> option.unwrap(character.species, "Unknown"), + ), + ]), + ]) + }), + ), + ]) +} + +// EFFECTS + +fn fetch_characters() -> Effect(Msg) { + effect.from(fn(dispatch) { + let client = squall.new("https://rickandmortyapi.com/graphql", []) + let assert Ok(req) = get_characters.get_characters(client) + + fetch.send(req) + |> promise.map(fn(fetch_result) { + case fetch_result { + Ok(resp) -> { + fetch.read_text_body(resp) + |> promise.await(fn(text_result) { + case text_result { + Ok(text) -> { + let result = + get_characters.parse_get_characters_response(text.body) + dispatch(HandleCharacters(result)) + promise.resolve(Nil) + } + Error(_) -> { + dispatch( + HandleCharacters(Error("Failed to read response body")), + ) + promise.resolve(Nil) + } + } + }) + } + Error(_) -> { + dispatch(HandleCharacters(Error("Failed to fetch characters"))) + promise.resolve(Nil) + } + } + }) + + Nil + }) +} diff --git a/examples/02-lustre/test/lustre_example_test.gleam b/examples/02-lustre/test/lustre_example_test.gleam new file mode 100644 index 0000000..fba3c88 --- /dev/null +++ b/examples/02-lustre/test/lustre_example_test.gleam @@ -0,0 +1,13 @@ +import gleeunit + +pub fn main() -> Nil { + gleeunit.main() +} + +// gleeunit test functions end in `_test` +pub fn hello_world_test() { + let name = "Joe" + let greeting = "Hello, " <> name <> "!" + + assert greeting == "Hello, Joe!" +} diff --git a/gleam.toml b/gleam.toml index 85c6fab..89dbdb6 100644 --- a/gleam.toml +++ b/gleam.toml @@ -1,5 +1,5 @@ name = "squall" -version = "1.0.0" +version = "1.0.1" description = "☁️ Type-safe GraphQL client generator for Gleam" licences = ["Apache-2.0"] repository = { type = "github", user = "bigmoves", repo = "squall" }