Skip to content

Remote Functions: allow returning raw binary responses #16524

Description

@MrVoshel

Describe the problem

When dealing with binary data, I would like to avoid the serialization/deserialization and size overhead caused by passing it through devalue.

Currently, doing so requires creating a separate +server.ts endpoint and manually fetching it on the client. While that is simple enough, if such thing is feasible and makes sense, I would prefer to retain the ergonomics of remote functions while returning binary responses.

Describe the proposed solution

Provide a way for a remote function to return binary data

export const generate_pdf = query({ text: v.string() }, async ({ text }) => {
	const file = await get_file();
	const processed = await fill_with_user_input(file, text);

	return binary(processed);
});

or even avoid the binary() abstraction and just let the user handle it with a standard response:

return request.headers.get('if-none-match') === etag
	? new Response(null, {
			status: 304,
			headers: { etag }
		})
	: new Response(await processed.save(), {
			headers: {
				'content-type': 'application/pdf',
				'etag': random_hash(),
				'cache-control': 'private, no-cache'
			}
		});

And ideally consume it like this on the client:

<script lang="ts">
	import { generate_pdf } from './pdf.remote';
	import ShowPDF from './ShowPDF.svelte';
</script>

{let text = $state('')}
{let pdf = $state<Blob>()}

<input bind:value={text} />

<button onclick={async () => pdf = await generate_pdf({ text })}>
	Update PDF
</button>

<ShowPDF file={pdf} />

Alternatives considered

  • Continue having +server.ts endpoint for fetching the updated file, while having the additional logic that manipulates that same file in a different handling.remote.ts

  • Avoid the HTTP approach and defer this to what SvelteKit will end up with for their WebSocket implementation.

Importance

nice to have

Additional Information

Related to #16285 only if the APIs introduced there end up overlapping with this proposal. (Although my issue has more to do with same-origin responses)

A similar need for efficient binary transport was also mentioned here:
Originally posted by @garth in #13897 (reply in thread)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions