UNPKG

@sveltejs/kit

Version:

SvelteKit is the fastest way to build Svelte apps

73 lines (62 loc) 1.93 kB
import { app_dir, base } from '$app/paths/internal/client'; import { app } from '../../client.js'; import { get_remote_request_headers, handle_side_channel_response } from '../shared.svelte.js'; import * as devalue from 'devalue'; import { HttpError } from '@sveltejs/kit/internal'; import { noop } from '../../../../utils/functions.js'; import { read_sse } from '../../sse.js'; /** * @template T * @param {string} id * @param {string} payload * @param {AbortController} [controller] * @param {() => void} [on_connect] * @returns {AsyncGenerator<T>} */ export async function* create_live_iterator( id, payload, controller = new AbortController(), on_connect = noop ) { const url = `${base}/${app_dir}/remote/${id}${payload ? `?payload=${payload}` : ''}`; const response = await fetch(url, { headers: get_remote_request_headers(), signal: controller.signal }); if (!response.ok) { const result = await response.json().catch(() => ({ type: 'error', status: response.status, error: response.statusText })); throw new HttpError(result.status ?? response.status ?? 500, result.error); } if (response.headers.get('content-type')?.includes('application/json')) { // we can end up here if we e.g. redirect in `handle` const result = await response.json(); await handle_side_channel_response(result); throw new HttpError(500, 'Invalid query.live response'); } if (!response.body) { throw new Error('Expected query.live response body to be a ReadableStream'); } const reader = response.body.getReader(); try { on_connect(); for await (const node of read_sse(reader)) { if (node.type === 'result') { yield devalue.parse(node.result, app.decoders); continue; } await handle_side_channel_response(node); throw new HttpError(500, 'Invalid query.live response'); } } finally { try { await reader.cancel(); } catch { // already closed } } }