Giter VIP home page Giter VIP logo

purescript-halogen-realworld's Introduction

Real World Halogen

RealWorld Frontend CI Maintainer: thomashoneyman

PureScript is a delightful pure functional language that offers pragmatic and powerful tools to help you design, build, and refactor reliable apps of any size. This repository demonstrates the principles I apply at work every day in more than 2,000 lines of thoroughly commented code.

I’m a developer at Awake Security (and previously at CitizenNet). Both companies have large production PureScript applications that have remained reliable, understandable, and maintainable as they scale.

This repository follows the RealWorld spec to implement a Medium clone called Conduit using Halogen. It’s large enough to demonstrate real world examples (CRUD, state management, scalable architecture, type classes, components, etc.) but not so large as to be overwhelming. There is also a Real World PureScript React project that demonstrates the same project using React bindings from PureScript.

The source code currently covers Halogen 7 with PureScript 0.15, but there are versions for versions going back to Halogen 4:

If you have found this repository and the guide useful, please consider becoming a sponsor!

Installation

First, clone the repository:

$ git clone https://github.com/thomashoneyman/purescript-halogen-realworld
Cloning into 'purescript-halogen-realworld'...
...
Resolving deltas: 100% (...), done.
$ cd purescript-halogen-realworld

You can enter a development shell with all non-JavaScript dependencies via Nix:

$ nix develop

Alternately, you can install purescript, spago, purs-tidy, purescript-psa, and the PureScript language server from NPM.

Next, install JavaScript dependencies:

$ npm install

Building and running

Next, build the project (this command will run spago build; see the package.json file to see all helper scripts for the project):

$ npm run build

You can bundle the JS for production:

$ npm run bundle

You can run a dev server to use Conduit:

$ npm run serve
...
 > Local:   http://127.0.0.1:8000/
 > Network: http://192.168.1.67:8000/

When you reload the application in the browser, esbuild will re-bundle the application using the latest compiled PureScript in the output directory. If you're using the PureScript language server, then this directory will be updated when you save files via incremental compilation.

Learning PureScript

This project is intended to give non-PureScript developers a taste of what a small application in the language looks like, and to give advanced beginners in PureScript a resource to feel comfortable building reliable applications of their own.

PureScript is a delightful language that becomes only more interesting and rewarding the more you use it and the larger your application becomes; if you haven’t yet tried it out, I encourage you to do so. Not convinced? Kris Jenkins has a lovely talk about PureScript which might change your mind.

Resources

The PureScript community is warm and helpful. If you would like some help getting started, please consider joining the official Discourse and official chat. You may also want to check out:

  1. The (warning: currently in rough draft form) handbook which explains the theory & principles at work in this application in-depth, which will be useful to help take you from advanced beginner to advanced intermediate in the language.
  2. The official Halogen guide, which will teach you how to use the Halogen framework to write components.
  3. PureScript by Example, which will teach you PureScript from scratch and was written by the language’s creator, Phil Freeman. While the official book has not been updated for the latest version of the compiler, this link is to an up-to-date fork of the book.
  4. Functional Programming Made Easier, a book by Charles Scalfani that teaches functional programming using PureScript.
  5. Jordan Martinez’s PureScript reference, which has a broad overview of dozens of topics in PureScript and functional programming.

Contributing

PRs are welcome! Any functional changes will need to remain compliant with the RealWorld spec, and I may re-word documentation changes to fit with the voice used throughout the repository.

purescript-halogen-realworld's People

Contributors

alex-ketch avatar and-pete avatar baig avatar chris81 avatar commandodev avatar damien-biasotto avatar davezuch avatar dependabot[bot] avatar flip111 avatar geromegrignon avatar jfraudeau avatar kurtmilam avatar lambdina avatar maridonkers avatar matthew-hilty avatar mjepronk avatar pete-murphy avatar pmiddend avatar safareli avatar sjpgarcia avatar sumew avatar th-awake avatar thomashoneyman avatar toastal avatar wryk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

purescript-halogen-realworld's Issues

Unexpected behaviour for logged-in user

Hi Thomas,

I've identified what I think are two bugs, that have a chance of being related and so I'll keep them in the same issue.

See this Recordit GIF here for both behaviours demonstrated. For reference, this was recorded with me running the current commit in main right now.

Issue No. 1: Refreshing a logged-in user

When a logged-in user refreshes the page (for example, at Home), they present as though they are not logged in.

If while appearing logged-out they then:

  • Navigate away from the Home page to one of the navbar links available to logged-out users (Log in / Sign up) they can do so. But when they navigate back to Home from there they will now present as logged in.
  • Navigate away from the Home page directly to a route that has a version for logged-in users (e.g. Read more...), they will display as being logged in at that new route.

Experimenting, I've found a change that seems to partially fix this behaviour (i.e. it will display a refreshed user as being logged-in). In Main.purs, you currently write the the user profile to the currentUser Ref if there was a successful response from the server. If you add a second line where you also write it to the userBus Bus, upon page refresh you'll now initially see the the page display as logged out, but only for however many milliseconds it takes for the User request to come back and be decoded. And then you are displayed as logged in.

Adding the Bus.write changes another behaviour too. Toward the end of the GIF, I click the Settings link while displaying as logged in again (after a refresh & navigation changes), but it asks me to Sign In again. Writing to the Bus in main makes it so that the Settings page loads without being shown the Sign In page first.

Issue No. 2: Initialize-ation of the Home route

This is also related to users that are logged in. Specifically, I can't seem to be able to find a way to trigger this Just branch here in Home.purs in the component's Initialize action.

handleAction = case _ of
  Initialize -> do
    void $ H.fork $ handleAction LoadTags
    state <- H.get
    case state.currentUser of
      Nothing ->
        void $ H.fork $ handleAction $ LoadArticles noArticleParams

     -- This branch never triggers
      profile -> do
        void $ H.fork $ handleAction $ LoadFeed { limit: Just 20, offset: Nothing }
        H.modify_ _ { tab = Feed }

It doesn't matter whether I'm logged in + refreshing or whether I'm logged in + navigating back to the Home route from another route like an article.

You can see this at the end of the same GIF I linked above. I try to show that the page always shows the "Global Feed" (...that corresponds to the Nothing branch in the Initialize action) and never loads the "Your Feed" tab (...that should load if you had a Just profile in the component's state). I've checked by adding logging statements into the different branches and yeah there's always a Nothing value in state.currentUser when that initializing action runs.

After getting some help clearing up some confusion in Slack about the evaluation order of Halogen components a week or two back, I think this implies that the initialState input being received by the Home page's component on initialization must also be { currentUser: Nothing } (...as there's nothing else other than initialState that can modify the component's state before this Initialize action we're in). BUT... I'm trying to stick to observed behaviours here and not my interpretation of what's going on 😅

I'll take a look at some of the other components to see if I can find any equivalent behaviour. e.g. in the Editor component, it is similar to Home in that it is also built using the Connect.component HOC and its Initialize action starts with H.get-ing the current state.

My impression is that while components like Profile & ViewArticles (that aren't constructed using the HOC) need to read from the userEnv.currentUser/etc. Ref in order to get the state of the logged-in user, other components like Home above & Editor should be able to H.get a Just initial value form their component state when initializing as they'll have been provided some initial state as their input from the Connect.component HOC before the Initialize action runs. So if there's an issue where the HOC is not providing that initial state to Home, it might be observable in Editor too. I shall dig!

Sorry for the length!

The reason I've kept this as one GH issue is that I'm not sure that just adding Bus.write for the userBus in Main is the right fix for that refresh issue. And that there might be some single issue going on with HOC that's causing both.

Would you be interested in a PR to update various dependencies?

The application builds and runs locally after I:

  1. Update the dependencies and devDependencies in package.json
  2. Update the spago package set
  3. Update the halogen override to v5.0.0-rc.7
  4. Make a few changes to adapt to the new request API introduced with AffJax 10.0

I checked the additions defined in packages.dhall, and each seems to be on the latest version, so I think the above changes are all that's necessary to bring the project up to the latest state.

Thanks for sharing this project (and for the other writing and OSS work you do). I've found your writing and repos very helpful as I've been learning PureScript.

virtual module prefix Conduit

I noticed that some modules has virtual prefix "Conduit." though folder path in src starts with second segment.

I thought the import was from library and spent significant amount of time on purs trying to find source code.

yarn/npm install fails due to missing halogen-5 tag on halogen-formless

Error message:

spago: Installation failed.

Error:


Failed to install dependency "halogen-formless"
Git output:

From https://github.com/thomashoneyman/purescript-halogen-formless
 * [new branch]      gh-pages   -> origin/gh-pages
 * [new branch]      master     -> origin/master
 * [new tag]         v0.1.0     -> v0.1.0
 * [new tag]         v0.1.1     -> v0.1.1
 * [new tag]         v0.2.0     -> v0.2.0
 * [new tag]         v0.3.0     -> v0.3.0
 * [new tag]         v0.3.1     -> v0.3.1
 * [new tag]         v0.4.0     -> v0.4.0
 * [new tag]         v0.4.1     -> v0.4.1
 * [new tag]         v0.5.0     -> v0.5.0
 * [new tag]         v0.5.1     -> v0.5.1
 * [new tag]         v0.5.2     -> v0.5.2
error: pathspec 'halogen-5' did not match any file(s) known to git.

Another installation warning - yarn bundle

Sorry for the noob questions, but at this point I don't know what can be safely ignored and what will cause problems down the road.

Is there something wrong with my tool setup or is this save to ignore?

I'm running the following:
yarn 1.22.4
npm 6.14.5
WSL Ubunto 18.04.4

$ yarn bundle
yarn run v1.22.4
$ npm run bundle:build && npm run bundle:dce && npm run bundle:parcel
npm WARN lifecycle The node binary used for scripts is /tmp/yarn--1589592225223-0.10801633644455455/node but npm is using /home/steve/.local/lib/node-v12.16.3-linux-x64/bin/node itself. Use the --scripts-prepend-node-path option to include the path for the node binary npm was executed with.

Why Halogen?

In the “why Halogen?” Section in the introduction, you briefly state some other frameworks but you don’t specifically address the question of why Halogen. What has halogen got to offer that these other frameworks do not? I’m coming from Elm so I’m wondering whether I should put in the effort to learn halogen or stick with Spork, Hedwig, or another TEA done in purescript.

Thank you for a great book so far.

Migrate project to use Halogen Hooks

This would be a larger undertaking and we would still need to get Formless and Select migrated over first.

However, this would likely be the best way to benchmark how much these hooks affect the following factors:

  • readability
  • scalability
  • performance

Update for Halogen 5

Halogen is on its fourth release candidate for v5, which appears imminent once docs are updated. Formless, the only Halogen dependency of this project, is updated for Halogen 5. As far as I'm aware the only other missing dependency is RemoteData, which has conflicting versions for Lens.

This project should be updated for Halogen 5 as soon as possible, where it can serve as a migration guide for others upgrading to Halogen 5 in the near future.

zephyr doesn't build with purescript 0.13.8 because extern files now have extension cbor

yarn bundle                                                                 yarn run v1.22.4
$ npm run bundle:build && npm run bundle:dce && npm run bundle:parcel
npm WARN lifecycle The node binary used for scripts is /tmp/yarn--1591623780504-0.9926300850329874/node but npm is using /nix/store/iciihahi16fv7i3ynmhkpvav08min08h-nodejs-13.14.0/bin/node itself. Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed with.

> [email protected] bundle:build /home/srghma/projects/purescript-halogen-realworld
> spago build --purs-args '--codegen corefn'

[info] Installation complete.
[info] Build succeeded.
npm WARN lifecycle The node binary used for scripts is /tmp/yarn--1591623780504-0.9926300850329874/node but npm is using /nix/store/iciihahi16fv7i3ynmhkpvav08min08h-nodejs-13.14.0/bin/node itself. Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed with.

> [email protected] bundle:dce /home/srghma/projects/purescript-halogen-realworld
> zephyr -f Main.main

zephyr: output/Affjax/externs.json: openBinaryFile: does not exist (No such file or directory)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] bundle:dce: `zephyr -f Main.main`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] bundle:dce script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/srghma/.npm/_logs/2020-06-08T13_43_08_958Z-debug.log
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ls -al output/Affjax/
total 196
drwxr-xr-x   2 srghma users   4096 Jun  8 16:23 .
drwxr-xr-x 837 srghma users  36864 Jun  8 16:18 ..
-rw-r--r--   1 srghma users 101214 Jun  8 16:18 corefn.json
-rw-r--r--   1 srghma users  31848 Jun  8 16:23 externs.cbor
-rw-r--r--   1 srghma users   2833 Jun  8 16:23 foreign.js
-rw-r--r--   1 srghma users  14637 Jun  8 16:23 index.js
purs --version
0.13.8
{
  pkgs ? import ./nix/pkgs.nix
}:

pkgs.mkShell rec {
  buildInputs = with pkgs; [
    pkgs.path # nixpkgs path, not dependency, add nixpkgs source to gc-root and prevent it to be gc collected
    # rootYarnModules

    gnumake
    git
    nix

    nodejs
    yarn

    # for building c++ extensions (from https://matrix.ai/2018/03/24/developing-with-nix/)
    # nodePackages.node-gyp
    # nodePackages.node-gyp-build
    # nodePackages.node-pre-gyp

    easy-purescript-nix-automatic.spago
    easy-purescript-nix-automatic.purs
    easy-purescript-nix-automatic.purty # find ./packages/client/src -name "*.purs" -exec purty --write {} \;
    easy-purescript-nix-automatic.zephyr # find ./packages/client/src -name "*.purs" -exec purty --write {} \;
    # easy-purescript-nix-automatic.spago2nix
  ];

  # for https://www.npmjs.com/package/debug that is used at https://github.com/ethul/purs-loader
  # DEBUG = "purs-loader*";
  # DEBUG_DEPTH = "100";

  shellHook = ''
    export PATH="${pkgs.rootProjectDir}/node_modules/.bin/:$PATH"
  '';
}

Add Travis CI build?

It might be a good idea to add a Travis CI build. I just did npm install and it failed at

> install-purescript --purs-ver=0.12.5

so something's wrong.

@parcel/transformer-js: Browser scripts cannot have imports or exports.

Following the instructions in the README (in the nix-shell) I get this:

$ npm install
...
$ npm run build
$ npm run bundle
$ npm run serve-dev

> purescript-halogen-realworld@ serve-dev /home/ben/docs/1.Projects/RestaurantOptimisation/purescript-halogen-realworld
> parcel dev/index.html --open

Server running at http://localhost:1234
🚨 Build failed.

@parcel/transformer-js: Browser scripts cannot have imports or exports.

  /home/ben/docs/1.Projects/RestaurantOptimisation/purescript-halogen-realworld/index-dev.js:1:12
  > 1 | var Main = require("./output/Main");
  >   |            ^^^^^^^^^^^^^^^^^^^^^^^^
    2 | Main.main();
    3 | 
  
  /home/ben/docs/1.Projects/RestaurantOptimisation/purescript-halogen-realworld/dev/index.html:20:5
    19 |   <body>
  > 20 |     <script src="../index-dev.js"></script>
  >    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The environment was originally created here
    21 |   </body>
    22 | </html>

  💡 Add the type="module" attribute to the <script> tag

Conduit.Component.RawHTML will fail with "require is not defined" (var marked =require("marked");)

in dist/app.js I have

})(PS["Conduit.Component.RawHTML"] = PS["Conduit.Component.RawHTML"] || {});
(function(exports) {

  var marked =require("marked");

  // Next, we'll perform any setup necessary before exporting functions. In our case, we'll turn off
  // the 'pedantic' option to be more lenient with parsing, and we'll enable GitHub-flavored
  // markdown.
  marked.setOptions({
    pedantic: false,
    gfm: true
  });

I didnt check, but var marked =require("marked"); should fail

to resolve we could use rollup-plugin-purs and rollup-plugin-node-resolve (source purescript/purescript#2621 (comment))

P.S. would be also cool to add https://www.npmjs.com/package/rollup-plugin-prepack

Real World Demo

Hi there,

I'm putting togeterh a refresh of Real World Comparision of Front-End Frameworks and was wondering if you could put a link to a demo application (on Netlify or something) into the repo? This is needed for the first metric--Performance.

if this is not imporatnt to you -- that is also fine and feel free to close this issue.

Thanks, Jacek

Use `FormError t` instead of FormError

Thank you very much for this awesome project!

Perhaps my suggestion is a bit over-engineering, but I feel like that it is better to define FormError with

import Type.Proxy (Proxy)
data FormError t
  = Required
  | TooShort
  | TooLong
  | Invalid (Proxy t)

, where data Proxy t = Proxy from purescript-proxy package. Then FormError is typed with the kind of input.

Thank you again for this awesome project. I learn a lot about purs from it.

Cheers,

Thank you again!

This is extremely useful and I cannot express my gratitude enough for your efforts. I'm sure so many others feel the same.

Thank you for sharing this with the world.

This issue was not created to complain or report anything, so you can close this any time.

`npm run serve` gives an empty page

Cloning this repository and running npm run serve from inside of the nix shell results in an empty page.

The problem is that index.html refers to main.js instead of index.js. However, npm run bundle is configured to produce a main.js file.

  • index.js should be moved to main.js, or
  • index.html and package.json should be adjusted to create/refer to index.js instead of main.js

How to produce a production optimized bundle?

Running the current bundle script produces a bundle of around 600kb. I was wondering what additional steps could be taken to produce a smaller bundle?

I tried ensuring NODE_ENV was set to production before running parcel build and got the same output. I also tried using zephyr but failed to get a parcel build to succeed when referencing the zephyr's output.

Use more up-to-date learn/documentation links that are more beginner-friendly

I think this project may convince some people on the fence about PureScript. However, your guide links to the outdated Book and also to a version of the Halogen guide that's not very beginner-friendly. As such, newcomers who are enthusiastic about this language will likely be demoralized soon thereafter due to having a poor first-experience with the Getting Started part of the language.

In the Prerequisites section, why not update that section with a few additional links:

  • My 'Getting Started' file, which
    • already links to the FP Slack community and Discourse forum (using the correct URL and not the outdated .ml domain name) as a way to get more help
    • shows how to install the language correctly for the 0.12.1 release and not the outdated 0.11.7 release
    • pushes people to use psc-package which "just works" rather than Bower, which often comes with a number of issues where a first-time user does not know how to fix such problems immediately. (When they get more familiar with the language, they can choose whether to use Bower from there.)
  • My 'Dependency Managers' file, which explains why we used Bower in the first place, what its problems were that led to the creation of psc-package, and how spacchetti + dhall makes that easier (I've yet to include the update for spago)
  • My 'Halogen Guide' file, which
    • explains that one needs to checkout the v4.0.0 tag in order to get the Halogen examples to work (not sure whether this is still relevant, but it'll stop the confusion that would otherwise occur by seeing your v4 Halogen code and their v5 Halogen examples
    • links to my beginner-friendly "bottom-up" guide to Halogen where each of the polymorphic types are introduced one at a time
    • links to their original "top-down" guide to Halogen
    • most importantly, links to my Halogen Flowchart which shows how the overall concept works in a visual manner.

And yes, to save you time, I'd be willing to submit a PR if you agree with this idea.

Installation warnings

Do I need to be concerned about any of the following? I've done many years of systems level C development and have learned Haskell to maybe the novice level, but web development is new to me.

I'm assuming that the "No lockfile found" is not a problem, but what about all the warnings?

$ yarn install
yarn install v1.22.4
info No lockfile found.
[1/4] Resolving packages...
warning parcel-bundler > [email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
warning parcel-bundler > babylon-walk > babel-runtime > [email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
warning parcel-bundler > @parcel/watcher > [email protected]: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
warning parcel-bundler > htmlnano > uncss > [email protected]: request has been deprecated, see request/request#3142
warning parcel-bundler > htmlnano > uncss > jsdom > [email protected]: request has been deprecated, see request/request#3142
warning parcel-bundler > @parcel/watcher > chokidar > [email protected]: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
warning parcel-bundler > micromatch > snapdragon > source-map-resolve > [email protected]: https://github.com/lydell/resolve-url#deprecated
warning parcel-bundler > micromatch > snapdragon > source-map-resolve > [email protected]: Please see https://github.com/lydell/urix#deprecated
warning purescript > purescript-installer > [email protected]: request has been deprecated, see request/request#3142
warning spago > [email protected]: request has been deprecated, see request/request#3142
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...

Show tags in editor when editing an article

Hi,

I'm using this project as a basis to create my own PS Halogen based app. Now I wonder how to handle the case when editing a form that represents an existing object (with initial data). My form contains various components that should have their state initialized from the form data (handled by formless).
Sadly, your code does not initialize the TagInput component when editing an existing article, as that would show exactly the code I would need :-)

Update: This is my attempt:
mjepronk@ad0bc60
The hardcoded tags work, but I can't get it to work with the form values (the commented part F.getInput proxies.tagList form).

Thanks again for all your work!

Thank you

I cannot express enough my gratitude for this work. I feel like I may have saved a few months of learning FP just by reading your excellent explanation and code.
PureScript by Example and this resource are the bare minimum that I would recommend any newcomer to PureScript.
Thanks a ton!

Typos

API Domain change

Hello!

Due to governance changes, we are now using the realworld.io domain for the RealWorld demo (both client and API).
Requests from conduit.productionready.io are redirected to api.realworld.io, but such a redirection might lead to inconsistent responses.

We encourage domain change for the community.
If this repository is maintained anymore, we'll consider hosting a demo of your implementation in a few weeks with the domain change.

The demo link will be added to the RealWorld documentation.

Change in url does not refresh the page

Hello. I've build the project and run a local sever with yarn serve.
I've made two articles:
http://localhost:8081/?#/article/aaa-6umu5b
http://localhost:8081/?#/article/bbb-wvj44m
When I open two pages in two separate tabs, everything works.
However, if I open first page and then manually edit url to the second one, the page content remains unchanged. It only happens when I move from one article to another - if, for example, I open http://localhost:8081/?#/settings and then edit url to http://localhost:8081/?#/article/bbb-wvj44m, page content will be updated.

Unless I have some serious misunderstanding of how routing in SPA supposed to work, this looks like a bug. Any thoughts?

npm run serves fails with `Segmentation fault (core dumped`

codewarrior@blueberry:/home/chris/temp/wiptemp/774/purescript-halogen-template$ npm run serve

> serve
> parcel dev/index.html --open

Port "1234" could not be used
node:events:491
      throw er; // Unhandled 'error' event
      ^

Error: spawn xdg-open ENOENT
    at Process.ChildProcess._handle.onexit (node:internal/child_process:285:19)
    at onErrorNT (node:internal/child_process:485:16)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)
Emitted 'error' event on ChildProcess instance at:
    at Process.ChildProcess._handle.onexit (node:internal/child_process:291:12)
    at onErrorNT (node:internal/child_process:485:16)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'spawn xdg-open',
  path: 'xdg-open',
  spawnargs: [ 'http://localhost:38331' ]
}
Segmentation fault (core dumped)

I tried changing parcel to serve on port 1235 instead but run into the same issue:

codewarrior@blueberry:/home/chris/temp/wiptemp/774/purescript-halogen-template$ npm run serve

> serve
> parcel -p 1235 dev/index.html --open

node:events:491
      throw er; // Unhandled 'error' event
      ^

Error: spawn xdg-open ENOENT
    at Process.ChildProcess._handle.onexit (node:internal/child_process:285:19)
    at onErrorNT (node:internal/child_process:485:16)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)
Emitted 'error' event on ChildProcess instance at:
    at Process.ChildProcess._handle.onexit (node:internal/child_process:291:12)
    at onErrorNT (node:internal/child_process:485:16)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'spawn xdg-open',
  path: 'xdg-open',
  spawnargs: [ 'http://localhost:1235' ]
}
Segmentation fault (core dumped)

Googling this issue and figuring out it's to do with xdg-open, I removed the --open from package.json which then fixes the issue.

Help: Logout button in Header

I'm trying to add a logout button to Conduit.Component.HTML.Header but when looking at the current implementation in Conduit.Page.Settings:

, HE.onClick \_ -> Just LogUserOut

it's using it's own handleAction which I can't really do as I don't have access to H.Component:

header :: forall i p r. Maybe { | ProfileRep r } -> Route -> HH.HTML i p

Could the solution be that I pass this message up to the Page.Home component and deal with it there or convert header to have it's own handleAction etc? (which to me feels nicer as better dealing with logout in one place)

I'm just unsure how either would look like codewise and can't seem to find another place in the codebase that does what I'm after. 😃

Simple routing questions?

Hi, i have a couple of simple routing questions.

I see that we handle the initial route and wrap it back up in a Maybe. The Router component then falls back to Home in the case of a Nothing. What's not clear to me though is how our initial route in the browser changes from http://172.28.225.97:8080 to http://172.28.225.97:8080/#/. I see our safeHref util will append the hash when navigating to another component. But how does our initial /#/ get appended to the route when we first start the app?

In a similar vein what is the best way for handling invalid routes? Are we able to navigate back to /#/ when an invalid route is entered into the browser?

thanks

`npm run serve` fails

I cloned this repository and followed the steps in the README, specifically

  • nix develop
  • npm install
  • npm run build

After those, npm run serve fails with

✘ [ERROR] Cannot serve an entry point without an output path

That seems to be hitting this path in esbuild https://github.com/evanw/esbuild/blob/a652e730ff07b9081470ef6965f3d54daa7b2aab/pkg/api/serve_other.go#L726

If I add --outfile=dist/index.js to the "serve" script in package.json that seems to fix things.

-  "serve": "spago build && esbuild --bundle index.js --servedir=dist",
+  "serve": "spago build && esbuild --bundle index.js --outfile=dist/index.js --servedir=dist",

I can make a PR with that change if it makes sense.

Build Fails when I update to the latest package sets: Error found: in module Conduit.Data.Profile

When I attempt to update the package sets to the latest (https://github.com/purescript/package-sets/releases/download/psc-0.15.14-20240118/packages.dhall), I get the following error:

`[ 1 of 24] Compiling Conduit.Data.Profile
Error found:
in module Conduit.Data.Profile
at src/Data/Profile.purs:26:20 - 26:28 (line 26, column 20 - line 26, column 28)

Cannot import value mapCodec from module Data.Codec
It either does not exist or the module does not export it.`

This is obviously because the Data.Codec module was massively simplified. I attempted to fix it but it was far beyond my current skill level. I'd like to use the latest package set to build this project. If possible, I'd love to help refactor this application to take advantage of the latest package sets. Thanks for sharing this super-important example for the Purescript ecosystem.

yarn install fails due to invalid link in halogen-formless

Hi,

thanks a lot for this example project it is really helpful. I have just tried installing a fresh copy and it fails during yarn install:

spago: Installation failed.
Error:
Invalid file name in tar archive: "../bower_components/purescript-halogen-storybook/examples/src/Storybook.css"
error Command failed with exit code 1.

Running spago install -v shows a bit more context:

About to fetch tarball for https://github.com/thomashoneyman/purescript-halogen-formless/archive/v1.0.0-rc.1.tar.gz
Fetching https://github.com/thomashoneyman/purescript-halogen-formless/archive/v1.0.0-rc.1.tar.gz
spago: Installation failed.

Error:

Invalid file name in tar archive: "../bower_components/purescript-halogen-storybook/examples/src/Storybook.css"

So the problem is that halogen-formless contains a link to bower_components which does not exist in the source repository. I am not sure if spago should ignore this type of error or if halogen-formless should create the link only after bower has populated that directory - or if there is even another approach.

Form `submit` event is not prevented

The browser navigate the current page (from https://wryk.github.io/purescript-halogen-realworld/#/login to https://wryk.github.io/purescript-halogen-realworld/?#/login) when logging in, bypassing login app behavior and re-displaying the same login form. I can consistently reproduce this bug on both submit button click and enter keypress with Firefox 79 and Chromium 84 on the url without the empty query component (?).

This is because the app doesn't prevent native submit event behavior from the form (and instead rely on click event from the submit button to proceed with authentication). I can't explain why this is working when the url contains an empty query component.

The bug can be partially mitigated by using a button with type=button or properly by preventing default behavior of submit event. The later is usually the way forms are handled on SPA.

Purescript Halogen Realworld React Redux Realword
No event listener on form but one on submit button No event listener on submit button but one on form, allowing .preventDefault() on its submit event
image image

Others form may also be concerned by this problem.

Upgrade to Halogen 6

Hi!

It would be much appreciated if this project was bumped to Halogen 6. It seems like all the necessary dependencies are at 0.14.0 since a little while back. I gave it a shot, but I know too little about the library to translate the bus event source things.

Styling question

One more question for you guys.

I started to really go through this last night because it's the most complete example and I'm wanting to use it, but the one thing I think is missing is talking anything about styling. I see you are using demo.productionready.io/main.css, and that's more or less opaque. Do you have any insights/links/tutorials/libraries explaining how to do this better? How to make Halogen sites look nice?

The one thing I get with purescript-elmish, which I'm using on my project here https://github.com/joshcough/chatbots/tree/master/frontend, is that I can easily drop into react, import react-bootstrap, and just go. So I can actually start to make things look nice right away. Of course, purescript-elmish is missing a lot of things that Halogen has, which is why I'm looking here in the first place.

I'm just sorta looking for anything to help me tie it all together, if that makes sense.

Thanks for putting this project together though, having all the comments in the code is really amazing.

Question on Router component

Hi and thank you for this fantastic project. I'm curious about this type declaration in Router.purs

type ChildSlot = Either7
  Unit
  Unit
  Unit
  Unit
  Unit
  Unit
  Unit

Is this so you have the ability to change Unit into something else for each component? or is it necessary to do it like this? I admit I don't really get the logic behind either7

Global Feed shows "Articles not yet loaded"

As an unauthenticated user, with the Global Feed tab selected, I see no articles (and a "Articles not yet loaded" message)

Screenshot showing Global Feed tab selected, and Articles not yet loaded message

In the browser console I see an error reported about a failure to decode ArticleWithMetadata because of a bad Slug

[ERROR: 2024-22-03 02:57:05 AM]
An error occurred while decoding a JSON value:
  Under 'PaginatedArray ArticleWithMetadata':
  At object key body:
  At array index 0:
  Under 'ArticleWithMetadata':
  At object key slug:
  Under 'Slug':
  Unexpected value "Ill-quantify-the-redundant-TCP-bus-that-should-hard-drive-the-ADP-bandwidth!-553".

The Slug package expects that a slug "consists of alphanumeric groups of characters" and that "every character with a defined notion of case is lower-cased," but slugs from api.realworld.io/api/articles can contain upper-case letters and ! apparently.

❯ curl -s "https://api.realworld.io/api/articles" | jq ".articles[].slug"
"Ill-quantify-the-redundant-TCP-bus-that-should-hard-drive-the-ADP-bandwidth!-553"
"quantifying-the-circuit-wont-do-anything-we-need-to-parse-the-back-end-FTP-interface!-553"
"Ill-compress-the-optical-SDD-hard-drive-that-should-interface-the-XSS-bandwidth!-553"
"The-JSON-interface-is-down-hack-the-haptic-transmitter-so-we-can-bypass-the-XML-system!-553"
"We-need-to-quantify-the-primary-TCP-matrix!-553"
"If-we-hack-the-firewall-we-can-get-to-the-USB-application-through-the-bluetooth-SDD-system!-553"
"Ill-override-the-digital-ADP-alarm-that-should-microchip-the-USB-firewall!-553"
"Try-to-calculate-the-JBOD-firewall-maybe-it-will-override-the-redundant-port!-553"
"Try-to-transmit-the-HTTP-card-maybe-it-will-override-the-multi-byte-hard-drive!-553"
"Use-the-open-source-THX-application-then-you-can-quantify-the-solid-state-transmitter!-553"

Question about conduit.productionready.io

Hi, sorry for asking a question here, but wasn't sure the best place to do it. I'm looking to find the backend code for conduit.productionready.io, because I can't really put this whole thing together as an example application without it. Like, I would really like to try this out on my own, get up my own server and use this as a launchpad, but yeah, just isn't possible without the backend code. Please let me know.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.