<% end %>
```
Internally, this works the same as [bypassing futurism in tests](#testing)
### Broadcast Partials Individually
Futurism's default behavior is to `broadcast` partials as they are generated in batches:
On the client side, `IntersectionObserver` events are triggered in a debounced fashion, so several `render`s are performed on the server for each of those events. By default, futurism will group those to a single `broadcast` call (to save server CPU time).
For collections, however, you can opt into individual broadcasts by specifying `broadcast_each: true` in your helper usage:
```erb
<%= futurize @posts, broadcast_each: true, extends: :tr do %>
<% end %>
```
### Contextual Placeholder Arguments
For individual models or arbitrary collections, you can pass `record` and `index` to the placeholder block as arguments:
```erb
<%= futurize @post, extends: :div do |post| %>
<%= post.title %>
<% end %>
```
```erb
<%= futurize @posts, extends: :tr do |post, index| %>
<%= index + 1 %> | <%= post.title %> |
<% end %>
```
```erb
<%= futurize partial: "users/user", collection: users, extends: "tr" do |user, index| %>
<%= index + 1 %> | <%= user.name %> |
<% end >
```
## Events
Once your futurize element has been rendered, the `futurism:appeared` custom event will be called.
## Instrumentation
Futurism includes support for instrumenting rendering events.
To enable ActiveSupport notifications, use the `instrumentation` option:
```ruby
Futurism.instrumentation = true
```
Then subscribe to the `render.futurism` event:
```ruby
ActiveSupport::Notifications.subscribe("render.futurism") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
event.name # => "render.futurism"
event.payload[:channel] # => "Futurism::Channel" # ActionCable channel to broadcast
event.payload[:controller] # => "posts" # The controller that invokes `futurize` call
event.payload[:action] # => "show" # The action that invokes `futurize` call
event.payload[:partial] # => "posts/card" # The partial that was rendered
end
```
This is useful for performance monitoring, specifically for tracking the source of `futurize` calls.
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'futurism'
```
And then execute:
```bash
$ bundle
```
To copy over the javascript files to your application, run
```bash
$ bin/rails futurism:install
```
**! Note that the installer will run `yarn add @stimulus_reflex/futurism` for you !**
### Manual Installation
After `bundle`, install the Javascript library:
There are a few ways to install the Futurism JavaScript client, depending on your application setup.
#### ESBuild / Webpacker
```sh
yarn add @stimulus_reflex/futurism
```
#### Import maps:
```ruby
# config/importmap.rb
# ...
pin '@stimulus_reflex/futurism', to: 'futurism.min.js', preload: true
```
#### Rails Asset pipeline (Sprockets):
```html+erb
<%= javascript_include_tag "futurism.umd.min.js", "data-turbo-track": "reload" %>
```
In your `app/javascript/channels/index.js`, add the following
```js
import * as Futurism from '@stimulus_reflex/futurism'
import consumer from './consumer'
Futurism.initializeElements()
Futurism.createSubscription(consumer)
```
## Authentication
For authentication, you can rely on ActionCable identifiers, for example, if you use Devise:
```ruby
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = env["warden"].user || reject_unauthorized_connection
end
end
end
```
The [Stimulus Reflex Docs](https://docs.stimulusreflex.com/authentication) have an excellent section about all sorts of authentication.
## Testing
In Rails system tests there is a chance that flaky errors will occur due to Capybara not waiting for the placeholder elements to be replaced. To overcome this, add the flag
```ruby
Futurism.skip_in_test = true
```
to an initializer, for example `config/initializers/futurism.rb`.
## Gotchas
### ActiveStorage URLs aren't correct in development
Out of the box, Rails will prefix generated urls with `http://example.org` rather than `http://localhost`, much like ActionMailer. To amend this, add
```ruby
# config/environments/development.rb
config.action_controller.default_url_options = {host: "localhost", port: 3000}
# config/environments/production.rb
config.action_controller.default_url_options = {host: "mysite.com"}
```
to your environments.
### Choosing the parent for Futurism::Channel
By default Futurism::CHannel will inherit from ApplicationCable::Channel, you can change this by setting
```ruby
Futurism.configure do |config|
config.parent_channel = "CustomFuturismChannel"
end
```
in config/initializers.
## Contributing
### Get local environment setup
Below are a set of instructions that may help you get a local development environment working
```shell
# Get the gem/npm package source locally
git clone futurism
cd futurism/javascript
yarn install # install all of the npm package's dependencies
yarn link # set the local machine's futurism npm package's lookup to this local path
# Setup a sample project, use the information below directly or use your own project
git clone https://github.com/leastbad/stimulus_reflex_harness.git
cd stimulus_reflex_harness
git checkout futurism
# Edit Gemfile to point point to local gem (e.g. `gem "futurism", path: "../futurism"`)
# yarn link @stimulus_reflex/futurism
# Do your work, Submit PR, Profit!
# To stop using your local version of futurism
# change your Gemfile back to the published (e.g. `gem "futurism"`)
cd path/to/futurism/javascript
# Stop using the local npm package
yarn unlink
# Instruct your project to reinstall the published version of the npm package
cd path/to/project
yarn install --force
```
### 📦 Releasing
1. Make sure that you run `yarn` and `bundle` to pick up the latest.
2. Bump version number at `lib/futurism/version.rb`. Pre-release versions use `.preN`
3. Run `rake build` and `yarn build`
4. Commit and push changes to github `git commit -m "Bump version to x.x.x"`
5. Run `rake release`
6. Run `yarn publish --no-git-tag-version`
7. Yarn will prompt you for the new version. Pre-release versions use `-preN`
8. Commit and push changes to GitHub
9. Create a new release on GitHub ([here](https://github.com/stimulusreflex/futurism/releases)) and generate the changelog for the stable release for it
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!