Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enhanced turbo-train-stream-source JS API #11

Merged
merged 9 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,23 @@ jobs:
strategy:
matrix:
ruby-version:
- "3.1"
- "3.2.2"
- "3.2"
- "3.3.3"
rails-version:
- "6.1"
- "7.0"
- "main"

env:
RAILS_VERSION: "${{ matrix.rails-version }}"
TEST_MSG_ID: "msg-${{ matrix.rails-version }}-${{ matrix.ruby-version }}"
MERCURE_DOMAIN: ${{ secrets.MERCURE_DOMAIN }}
MERCURE_PUBLISHER_KEY: ${{ secrets.MERCURE_PUBLISHER_KEY }}
MERCURE_SUBSCRIBER_KEY: ${{ secrets.MERCURE_SUBSCRIBER_KEY }}
FANOUT_FASTLY_KEY: ${{ secrets.FANOUT_FASTLY_KEY }}
FANOUT_SERVICE_ID: ${{ secrets.FANOUT_SERVICE_ID }}
FANOUT_SERVICE_URL: ${{ secrets.FANOUT_SERVICE_URL }}
ANYCABLE_URL: ${{ secrets.ANYCABLE_URL }}
ANYCABLE_BROADCAST_KEY: ${{ secrets.ANYCABLE_BROADCAST_KEY }}
MERCURE_DOMAIN: ${{ secrets.MERCURE_DOMAIN }}
MERCURE_PUBLISHER_KEY: ${{ secrets.MERCURE_PUBLISHER_KEY }}
MERCURE_SUBSCRIBER_KEY: ${{ secrets.MERCURE_SUBSCRIBER_KEY }}

name: ${{ format('Tests (Ruby {0}, Rails {1})', matrix.ruby-version, matrix.rails-version) }}
runs-on: ubuntu-latest
Expand All @@ -46,12 +45,6 @@ jobs:
run: |
bin/rails db:create db:migrate

- name: Run tests [mercure]
env:
TURBO_TRAIN_TEST_SERVER: mercure
run: |
bin/test test/**/*_test.rb

- name: Run tests [fanout]
env:
TURBO_TRAIN_TEST_SERVER: fanout
Expand All @@ -64,3 +57,9 @@ jobs:
run: |
bin/test test/**/*_test.rb

- name: Run tests [mercure]
env:
TURBO_TRAIN_TEST_SERVER: mercure
run: |
bin/test test/**/*_test.rb

4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
/log/*.log
/pkg/
/tmp/
/node_modules
/test/dummy/db/*.sqlite3
/test/dummy/db/*.sqlite3-*
/test/dummy/log/*.log
/test/dummy/storage/
/test/dummy/tmp/
Gemfile.lock
.DS_Store
.idea
.idea
.mise.toml
2 changes: 1 addition & 1 deletion app/assets/javascripts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@uscreentv/turbo-train",
"version": "0.0.3",
"version": "0.1.0",
"description": "",
"main": "turbo-train.js",
"type": "module",
Expand Down
90 changes: 84 additions & 6 deletions app/assets/javascripts/turbo-train.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,103 @@
import { Turbo } from "@hotwired/turbo-rails"


export default class TurboTrain extends HTMLElement {
static get observedAttributes() {
return [ 'href' ];
return [ 'href' ]
}

error = null

#eventSource = null

constructor() {
super();
super()
}

connectedCallback() {
this.eventSource = new EventSource(this.href);
Turbo.connectStreamSource(this.eventSource);
this.init()
}

// Public API - client can trigger initialization manually
init = () => {
this.#eventSource = new EventSource(this.href)
this.#eventSource.addEventListener('message', this.#onMessage)
this.#eventSource.addEventListener('error', this.#onError)
this.#eventSource.addEventListener('open', this.#onOpen)

if (this.shouldConnectTurboStream) {
Turbo.connectStreamSource(this.#eventSource)
}
}

disconnectedCallback() {
Turbo.disconnectStreamSource(this.eventSource);
this.destroy()
}

// Public API - client can trigger destruction manually
destroy = () => {
this.#eventSource?.close()
if (this.shouldConnectTurboStream) {
Turbo.disconnectStreamSource(this.#eventSource)
}
this.#eventSource?.removeEventListener('message', this.#onMessage)
this.#eventSource?.removeEventListener('error', this.#onError)
this.#eventSource?.removeEventListener('open', this.#onOpen)
}

get href() {
return this.getAttribute('href');
return this.getAttribute('href')
}

// By default component should always connect to turbo stream
// Only in case when we want to listen for event with JS we don't need to connect to turbo stream
get shouldConnectTurboStream() {
return !this.hasAttribute('no-turbo-stream')
}

// Humanize event source ready state
get state() {
if (!this.#eventSource) return null

switch (this.#eventSource.readyState) {
case EventSource.CONNECTING:
return 'connecting'
case EventSource.OPEN:
return 'open'
case EventSource.CLOSED:
return 'closed'
}
}

#onMessage = (event) => {
this.error = null
try {
const data = JSON.parse(event.data)
this.#emit('message', { detail: data, contentType: 'application/json' })
} catch (error) {
this.#emit('message', { detail: event.data, contentType: 'text/plain' })
}
}

#onError = (error) => {
this.error = error
this.#emit('error', { detail: error })
}

#onOpen = (event) => {
this.#emit('open', { detail: event })
}

#emit = (name, options = {}) => {
const event = new CustomEvent(name, {
bubbles: true,
cancelable: false,
composed: true,
detail: {},
...options
})
this.dispatchEvent(event)
return event
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/turbo/train/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Turbo
module Train
VERSION = "0.4.0"
VERSION = "0.5.0"
end
end
10 changes: 0 additions & 10 deletions node_modules/.yarn-integrity

This file was deleted.