Created
July 31, 2024 23:53
-
-
Save maietta/69f07388f1d62934f52420acfe495146 to your computer and use it in GitHub Desktop.
Proxy SSE data streams in SvelteKit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts"> | |
import { onMount } from 'svelte'; | |
import { writable } from 'svelte/store'; | |
// Define the type for your message objects | |
interface Message { | |
now: number; | |
created_at: string; | |
// Add any other properties your message might have | |
} | |
// Create the writable store with the correct type | |
const messages = writable<Message[]>([]); | |
onMount(() => { | |
const evtSource = new EventSource('/sse'); // Point to path | |
evtSource.onmessage = function (event) { | |
try { | |
// Remove 'data: ' prefix and parse the JSON | |
const dataString = event.data.replace(/^data: /, ''); | |
const dataobj: Message = JSON.parse(dataString); | |
messages.update((arr) => [...arr, dataobj]); | |
} catch (e) { | |
console.error('Failed to parse message:', e); | |
} | |
}; | |
return () => { | |
evtSource.close(); | |
}; | |
}); | |
</script> | |
{#each $messages as m} | |
{m.now} - {m.created_at} <br /> | |
{/each} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { RequestHandler } from '@sveltejs/kit'; | |
export const GET: RequestHandler = async () => { | |
const response = await fetch('https://sse.dev/test'); | |
if (!response.body) { | |
return new Response('No body in response', { status: 500 }); | |
} | |
const reader = response.body.getReader(); | |
const decoder = new TextDecoder('utf-8'); | |
const encoder = new TextEncoder(); | |
const stream = new ReadableStream({ | |
async start(controller) { | |
try { | |
while (true) { | |
const { done, value } = await reader.read(); | |
if (done) { | |
controller.close(); | |
break; | |
} | |
const text = decoder.decode(value, { stream: true }); | |
// Ensure each event data is prefixed with 'data: ' and followed by '\n\n' | |
const data = `data: ${text}\n\n`; | |
controller.enqueue(encoder.encode(data)); | |
} | |
} catch (error) { | |
console.error('Stream reading error:', error); | |
controller.error(error); | |
} | |
}, | |
cancel() { | |
console.log('Stream canceled'); | |
} | |
}); | |
return new Response(stream, { | |
headers: { | |
'Content-Type': 'text/event-stream', | |
'Cache-Control': 'no-cache', | |
Connection: 'keep-alive' | |
} | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment