Skip to content

Commit

Permalink
Close StreamSource when <turbo-stream-source> disconnects
Browse files Browse the repository at this point in the history
Closes [hotwired#969][]

When a `<turbo-stream-source>` element is removed, close the connection
that is created during connection.

[hotwired#969]: hotwired#969
  • Loading branch information
seanpdoyle committed Sep 11, 2023
1 parent c44664d commit 04c4ccf
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/elements/stream_source_element.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export class StreamSourceElement extends HTMLElement {

disconnectedCallback() {
if (this.streamSource) {
this.streamSource.close()

disconnectStreamSource(this.streamSource)
}
}
Expand Down
29 changes: 27 additions & 2 deletions src/tests/functional/stream_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ test("test receiving a stream message over SSE", async ({ page }) => {
`<turbo-stream-source id="stream-source" src="/__turbo/messages"></turbo-stream-source>`
)
})
await nextBeat()
assert.equal(await getReadyState(page, "stream-source"), await page.evaluate(() => EventSource.OPEN))

const messages = await page.locator("#messages .message")

assert.deepEqual(await messages.allTextContents(), ["First"])
Expand All @@ -113,11 +116,33 @@ test("test receiving a stream message over SSE", async ({ page }) => {
await waitUntilText(page, "Hello world!")
assert.deepEqual(await messages.allTextContents(), ["First", "Hello world!"])

await page.evaluate(() => document.getElementById("stream-source")?.remove())
await nextBeat()
const readyState = await page.evaluate((id) => {
const element = document.getElementById(id)

if (element && element.streamSource) {
element.remove()

return element.streamSource.readyState
} else {
return -1
}
}, "stream-source")
assert.equal(readyState, await page.evaluate(() => EventSource.CLOSED))

await page.click("#async button")
await nextBeat()

assert.deepEqual(await messages.allTextContents(), ["First", "Hello world!"])
})

async function getReadyState(page, id) {
return page.evaluate((id) => {
const element = document.getElementById(id)

if (element?.streamSource) {
return element.streamSource.readyState
} else {
return -1
}
}, id)
}

0 comments on commit 04c4ccf

Please sign in to comment.