Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
ggeoffrey authored Jan 26, 2024
1 parent 57d9ed5 commit 784dbe8
Showing 1 changed file with 29 additions and 28 deletions.
57 changes: 29 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Electric Starter App

Minimal setup for an Electric Clojure app. Plus instructions on how to integrate it into an existing app.
Be sure to check [Electric Tutorial](https://electric.hyperfiddle.net).
A minimal Electric Clojure app.
Plus instructions on how to integrate it into an existing app.

For real-world examples, check out [Electric Fiddle](https://github.com/hyperfiddle/electric-fiddle).

Expand All @@ -16,12 +16,12 @@ At the REPL:
(dev/-main)
```

Navigate to `http://localhost:8080`
Navigate to [http://localhost:8080](http://localhost:8080)

## Customize it

With the app running:
1. Go to `src/electric_starter_app/main.cljc`
1. Go to [src/electric_starter_app/main.cljc](src/electric_starter_app/main.cljc)
2. Edit and save
3. App will automatically update in your browser

Expand All @@ -40,65 +40,66 @@ java -cp target/app.jar clojure.main -m prod
```

There is also:
- an example `Dockerfile`
- `fly.io` deployment example (look at `.github/workflows/deploy.yml` and `fly.toml`)
- an example [Dockerfile](Dockerfile)
- `fly.io` deployment example (look at [.github/workflows/deploy.yml](.github/workflows/deploy.yml) and [fly.toml](fly.toml))

### Integrate it in an existing clojure app
## Integrate it in an existing clojure app

1. Look at `src-prod/prod.cljc`. It contains:
1. Look at [src-prod/prod.cljc](src-prod/prod.cljc). It contains:
- server entrypoint
- client entrypoint
- necessary configuration
2. Look at `src/electric_starter_app/server_jetty.clj`. It contains:
2. Look at [src/electric_starter_app/server_jetty.clj](src/electric_starter_app/server_jetty.clj). It contains:
- an example Jetty integration
- required ring middlewares

You'll also need to account for the following requirements.
You'll also need to account for the following requirements:

#### For a client to connect to the server, the two program versions must match.
### For a client to connect to the server, the two program’s version must match.

Electric Clojure compiles a single program into two artifacts:
- a javascript program - runs in the browser,
- a JVM program - runs on the server,
- these two programs communicate via websocket.
- these two programs work in pairs,
- they communicate via websocket.

If an outdated client tries to connect to the server, the server will:
If an mismatching client tries to connect to the server, the server will:
- reject the connection,
- inform the client it needs to refresh.
- inform the client it needs to refresh (so to get the newer client js file)

How it works:
- `clj -X:build:prod build-client` will
- generate js files with the version baked in
- `clj -X:build:prod build-client` will:
- generate js files with the version baked in,
- write the version in `resources/electric-manifest.edn`
- On server start, the server will
- On server start, the server will:
- read `resources/electric-manifest.edn`
- configure a ring middleware rejecting outdated client connections.
- configure a ring middleware rejecting mismatching (supposedly outdated) clients’ connection.
- On client -> server connection, the client will:
- send it's baked in version
- send it's baked-in version,
- try to refresh the page if the server rejects the version.

Here are examples you might want to adapt to your existing app:
- `src/electric_starter_app/server_jetty.clj` esp. `reject-stale-client`
- `src-build/build.clj`
- [src/electric_starter_app/server_jetty.clj](src/electric_starter_app/server_jetty.clj) esp. `reject-stale-client`
- [src-build/build.clj](src-build/build.clj)


Notice that `src-prod/prod.clj` reads `electric-manifest.edn`.
Notice that [src-prod/prod.clj](src-prod/prod.clj) reads `electric-manifest.edn`.

#### Ensuring cache invalidation
### Ensuring cache invalidation

If your production system doesn't already have a similar solution.
Only if your production system doesn't already handles it.

Complied js files are fingerprinted with their respective hash, to ensure a new release
properly invalidates asset caches. `index.html` is templated with the generated
properly invalidates asset caches. [index.html](resources/public/electric_starter_app/index.html) is templated with the generated
js file name. The generated name comes from the `manifest.edn` file
(in `resources/public/electric_starter_app/js/manifest.edn`), produced by `clj -X:build:prod build-client`.

Notice that `src/electric_starter_app/server_jetty.clj` -> `wrap-index-page` reads `:manifest-path` from config.
The config comes from `src-prod/prod.clj`.
Notice that [src/electric_starter_app/server_jetty.clj](src/electric_starter_app/server_jetty.clj) -> `wrap-index-page` reads `:manifest-path` from config.
The config comes from [src-prod/prod.clj](src-prod/prod.clj).



---
Notes

- This starter app uses Logback to log messages through `clojure.tools.logging`. Feel free to replace it by your favorite equivalent.
- This starter app logs with Logback for simplicity. Feel free to replace it by your favorite equivalent.

0 comments on commit 784dbe8

Please sign in to comment.